diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index e69b3794f5854cd6c9446b120eb6d64603f8d143..74df1acd7c98139314656e70b2e074adcbb0983b 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,18 +1,25 @@
 {
     "name": "virtual-fluids-environment",
-    "extensions": [
-        "mhutchie.git-graph",
-        "donjayamanne.githistory",
-        "twxs.cmake",
-        "ms-vscode.cpptools",
-        "visualstudioexptteam.vscodeintellicode",
-        "xaver.clang-format",
-        "notskm.clang-tidy",
-        "streetsidesoftware.code-spell-checker"
-    ],
+    "customizations": {
+        "vscode": {
+            "extensions": [
+                "mhutchie.git-graph",
+                "donjayamanne.githistory",
+                "twxs.cmake",
+                "ms-vscode.cpptools",
+                "visualstudioexptteam.vscodeintellicode",
+                "xaver.clang-format",
+                "notskm.clang-tidy",
+                "streetsidesoftware.code-spell-checker",
+                "llvm-vs-code-extensions.vscode-clangd",
+                "jbenden.c-cpp-flylint",
+                "ms-python.python",
+            ]
+        }
+    },
     "containerEnv": {"TZ": "${localEnv:TZ:Europe/Berlin}"},
     "runArgs": ["--gpus","all",                     // remove this line in case you have no gpus available
                 "--hostname=${localEnv:HOSTNAME}"], // HOSTNAME needs to be known by the vscode environment. It is probably necessary to add "export HOSTNAME=<hostname>" to the config file of your host machine's bash.
 
-    "image": "git.rz.tu-bs.de:4567/irmb/virtualfluids/ubuntu20_04:1.5"
+    "image": "git.rz.tu-bs.de:4567/irmb/virtualfluids/ubuntu22_04:1.0"
 }
diff --git a/.gitignore b/.gitignore
index f1d2c183fdb7171668c7cfe5f6129a942593f83b..a750e16f2b49f42e1a4fbff5092680574aefc488 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,7 @@ cmake-build-debug/
 run/
 buildGCC
 buildWSL
-.vscode
+pybuild/
 
 # Python
 _skbuild/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e12f8c5ae11456bc45fcf280a7601376805b25a9..281644f5614054f167c577898d4b8eb4788b2076 100755
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,7 +1,7 @@
 ###############################################################################
 ##                       VirtualFluids CI Pipeline                           ##
 ###############################################################################
-image: git.rz.tu-bs.de:4567/irmb/virtualfluids/ubuntu20_04:1.5
+image: git.rz.tu-bs.de:4567/irmb/virtualfluids/ubuntu22_04:1.0
 
 stages:
   - build
@@ -13,6 +13,11 @@ stages:
   - deploy
   - release
 
+workflow:
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
+      when: never  # disable detached merge request pipelines
+    - when: always # add all jobs to normal pipeline. This can be overwritten by the rules of the jobs.
 
 ###############################################################################
 ##                                Builds                                     ##
@@ -51,7 +56,7 @@ stages:
     - cmake .. -LAH
       --preset=make_all
       -DBUILD_WARNINGS_AS_ERRORS=ON
-      -DCMAKE_CUDA_ARCHITECTURES=60
+      -DCMAKE_CUDA_ARCHITECTURES=70
       -DBUILD_VF_ALL_SAMPLES=ON
     - make -j4
     - ccache --show-stats
@@ -60,7 +65,7 @@ stages:
     BUILD_FOLDER: "build"
 
 ###############################################################################
-gcc_9:
+gcc_12:
   extends: .gnu_build_template
 
   before_script:
@@ -68,7 +73,7 @@ gcc_9:
     - export CXX=g++
 
 ###############################################################################
-clang_10:
+clang_15:
   extends: .gnu_build_template
 
   before_script:
@@ -112,29 +117,29 @@ msvc_17:
 ###############################################################################
 ##                             Build Python                                  ##
 ###############################################################################
-gcc_9_python:
+gcc_12_python:
   stage: build_python
 
-  needs: ["gcc_9"]
+  needs: ["gcc_12"]
 
   cache:
-    key: "gcc_9-$CI_COMMIT_REF_SLUG"
+    key: "gcc_12-$CI_COMMIT_REF_SLUG"
     paths:
       - build
 
   artifacts:
     expire_in: 1 hrs
     paths:
-      - build/
-      - dist/
-      - _skbuild/
+      - pybuild/ # build in separate folder to avoid conflicts with c++ build
 
   before_script:
     - export CCACHE_BASEDIR=$CI_PROJECT_DIR
     - export CCACHE_DIR=$CI_PROJECT_DIR/cache
 
   script:
-    - python3 setup.py bdist_wheel build_ext --build-temp=_skbuild -- -DBUILD_VF_CPU=ON -DBUILD_VF_DOUBLE_ACCURACY=ON -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CUDA_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache
+    - export SKBUILD_BUILD_DIR="pybuild"
+    - export SKBUILD_CMAKE_ARGS="-DBUILD_VF_CPU=ON;-DBUILD_VF_DOUBLE_ACCURACY=ON;-DCMAKE_CXX_COMPILER_LAUNCHER=ccache;-DCMAKE_CUDA_COMPILER_LAUNCHER=ccache;-DCMAKE_C_COMPILER_LAUNCHER=ccache;-G=Ninja"
+    - pip install . -v
 
 ###############################################################################
 ##                            Container Upload                               ##
@@ -149,8 +154,6 @@ build_poiseuille_test_container:
   rules:
     - if: $REMOTE_USER && $REMOTE_HOST && $PRIVATE_KEY && $CI_PIPELINE_SOURCE == "schedule"
       when: always
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
-      when: never
     - when: manual
       allow_failure: true
 
@@ -169,10 +172,10 @@ build_poiseuille_test_container:
 ###############################################################################
 ##                                Tests                                      ##
 ###############################################################################
-gcc_9_unit_tests:
+gcc_12_unit_tests:
   stage: test
 
-  needs: ["gcc_9"]
+  needs: ["gcc_12"]
 
   before_script:
     - cd $CI_PROJECT_DIR/build
@@ -199,22 +202,19 @@ msvc_17_unit_tests:
     - ctest --output-on-failure -C Release
 
 ###############################################################################
-gcc_9_python_bindings_test:
+gcc_12_python_bindings_test:
   stage: test
 
-  needs: ["gcc_9_python"]
+  needs: ["gcc_12_python"]
 
   before_script:
-    - export PYTHONPATH="Python"
-    - export VF_WHEEL=$(find dist/*.whl)
-    - pip3 install $VF_WHEEL
     - pip3 install -r Python/requirements.txt
 
   script:
     - python3 -m unittest discover -s Python -v
 
 ###############################################################################
-gcc_9_python_hpc_test:
+gcc_12_python_hpc_test:
   image: python:latest
   stage: test
 
@@ -223,8 +223,6 @@ gcc_9_python_hpc_test:
   rules:
     - if: $REMOTE_USER && $REMOTE_HOST && $PRIVATE_KEY && $CI_PIPELINE_SOURCE == "schedule"
       when: always
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
-      when: never
     - when: manual
       allow_failure: true
 
@@ -253,8 +251,6 @@ build-regression-tests-ci:
   rules:
     - if: $CI_PIPELINE_SOURCE == "schedule"
       when: always
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
-      when: never
     - when: manual
       allow_failure: true
 
@@ -276,12 +272,11 @@ trigger-regression-tests:
 regression_test_4gpu:
   image: python:latest
   stage: test
+  needs: []
 
   rules:
     - if: $REMOTE_USER && $REMOTE_HOST && $PRIVATE_KEY && $CI_PIPELINE_SOURCE == "schedule"
       when: always
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
-      when: never
     - when: manual
       allow_failure: true
 
@@ -290,7 +285,10 @@ regression_test_4gpu:
     - pip install "fieldcompare[all]"
 
   script:
-    - hpc-rocket launch --watch regression-tests/multigpu_test/rocket4GPU.yml
+    - hpc-rocket launch regression-tests/multigpu_test/rocket4GPU.yml |& tee hpcrocket4GPU.log
+    - hpc-rocket watch regression-tests/multigpu_test/rocket4GPU.yml $(python regression-tests/multigpu_test/utilities/parsejobid.py hpcrocket4GPU.log)
+    - hpc-rocket finalize regression-tests/multigpu_test/rocket4GPU.yml
+    - cat output/4GPU/slurm4GPU.out
     - git clone --depth 1 --filter=blob:none --sparse https://github.com/irmb/test_data
     - cd test_data
     - git sparse-checkout set regression_tests/gpu/DrivenCavity_4GPU_2Levels regression_tests/gpu/SphereScaling_4GPU_2Levels
@@ -298,16 +296,23 @@ regression_test_4gpu:
     - fieldcompare dir output/4GPU test_data/regression_tests/gpu/DrivenCavity_4GPU_2Levels --include-files "DrivenCavityMultiGPU*.vtu"
     - fieldcompare dir output/4GPU test_data/regression_tests/gpu/SphereScaling_4GPU_2Levels --include-files "SphereScaling*.vtu"
 
+  after_script:
+    - hpc-rocket cancel regression-tests/multigpu_test/rocket4GPU.yml $(python regression-tests/multigpu_test/utilities/parsejobid.py hpcrocket4GPU.log)
+
+  artifacts:
+    when: always
+    paths:
+      - output/4GPU/slurm4GPU.out
+    expire_in: 1 week
 ###############################################################################
 regression_test_8gpu:
   image: python:latest
   stage: test
+  needs: []
 
   rules:
     - if: $REMOTE_USER && $REMOTE_HOST && $PRIVATE_KEY && $CI_PIPELINE_SOURCE == "schedule"
       when: always
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
-      when: never
     - when: manual
       allow_failure: true
 
@@ -316,21 +321,32 @@ regression_test_8gpu:
     - pip install "fieldcompare[all]"
 
   script:
-    - hpc-rocket launch --watch regression-tests/multigpu_test/rocket8GPU.yml
+    - hpc-rocket launch regression-tests/multigpu_test/rocket8GPU.yml |& tee hpcrocket8GPU.log
+    - hpc-rocket watch regression-tests/multigpu_test/rocket8GPU.yml $(python regression-tests/multigpu_test/utilities/parsejobid.py hpcrocket8GPU.log)
+    - hpc-rocket finalize regression-tests/multigpu_test/rocket8GPU.yml
+    - cat output/8GPU/slurm8GPU.out
     - git clone --depth 1 --filter=blob:none --sparse https://github.com/irmb/test_data
     - cd test_data
     - git sparse-checkout set regression_tests/gpu/DrivenCavity_8GPU_2Levels regression_tests/gpu/SphereScaling_8GPU_2Levels
     - cd ..
     - fieldcompare dir output/8GPU test_data/regression_tests/gpu/DrivenCavity_8GPU_2Levels --include-files "DrivenCavityMultiGPU*.vtu"
     - fieldcompare dir output/8GPU test_data/regression_tests/gpu/SphereScaling_8GPU_2Levels --include-files "SphereScaling*.vtu"
+  
+  after_script:
+    - hpc-rocket cancel regression-tests/multigpu_test/rocket8GPU.yml $(python regression-tests/multigpu_test/utilities/parsejobid.py hpcrocket8GPU.log)
 
+  artifacts:
+    when: always
+    paths:
+      - output/8GPU/slurm8GPU.out
+    expire_in: 1 week
 ###############################################################################
 ##                            Benchmark                                      ##
 ###############################################################################
 nvidia_test:
   stage: benchmark
 
-  image: nvidia/cuda:11.1.1-devel-ubuntu20.04
+  image: nvidia/cuda:12.1.1-devel-ubuntu22.04
 
   needs: []
 
@@ -349,8 +365,6 @@ gpu_numerical_tests:
   rules:
     - if: $CI_PIPELINE_SOURCE == "schedule"
       when: always
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
-      when: never
     - when: manual
       allow_failure: true
 
@@ -386,20 +400,32 @@ gpu_numerical_tests:
       - $CI_PROJECT_DIR/cache
 
   artifacts:
-    expire_in: 1 hrs
     paths:
       - $CI_PROJECT_DIR/numerical_tests_gpu_results.txt
 
 ###############################################################################
 ##                        Code analysis                                      ##
 ###############################################################################
-clang_build_analyzer_clang_10:
+.analyze_template:
   stage: analyze
 
-  only: ["schedules"]
-
   needs: []
 
+  tags:
+    - gpu
+    - linux
+
+  rules:
+    - if: '$CI_PROJECT_NAMESPACE == "irmb" && $CI_COMMIT_BRANCH == "develop"'
+      when: always
+    - if: '$CI_PROJECT_NAMESPACE != "irmb"'
+      when: manual
+      allow_failure: true
+
+
+clang_build_analyzer:
+  extends: .analyze_template
+
   before_script:
     - export CC=clang
     - export CXX=clang++
@@ -424,22 +450,19 @@ clang_build_analyzer_clang_10:
     - ClangBuildAnalyzer --analyze CBA
 
 ###############################################################################
-include_what_you_use_clang_10:
-  stage: analyze
-
-  only: ["schedules"]
-
-  needs: []
+include_what_you_use_clang_15:
+  extends: .analyze_template
 
   before_script:
+    - apt-get update && apt-get install -y libclang-15-dev llvm-15-dev
     - export CC=clang
     - export CXX=clang++
     - $CXX --version
     - cd /tmp
     - git clone https://github.com/include-what-you-use/include-what-you-use.git
     - cd include-what-you-use
-    - git checkout clang_10
-    - cmake . -DCMAKE_PREFIX_PATH=/usr/lib/llvm-10
+    - git checkout clang_15
+    - cmake . -DCMAKE_PREFIX_PATH=/usr/lib/llvm-15
     - make
     - export PATH+=:$(pwd)/bin
 
@@ -453,24 +476,13 @@ include_what_you_use_clang_10:
     - make
 
 ###############################################################################
-.analyze_template:
-
-  rules: # dont create MR pipeline, run always on irmb/develop and manual in all other cases
-    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
-      when: never
-    - if: '$CI_PROJECT_NAMESPACE == "irmb" && $CI_COMMIT_BRANCH == "develop"'
-      when: always
-    - when: manual
-      allow_failure: true
-
 cppcheck:
-  stage: analyze
-
   extends: .analyze_template
 
-  needs: []
-
   before_script:
+    - apt-get update && apt-get install -y libpcre3-dev
+    - chmod +x utilities/install-cppcheck.sh 
+    - ./utilities/install-cppcheck.sh
     - cppcheck --version
 
   script:
@@ -486,17 +498,9 @@ cppcheck:
 # lizard - Cyclomatic Complexity Analyzer
 # Ignore warnings is manually set to 191. This job will fail when new warnings are added.
 lizard:
-  stage: analyze
-
   extends: .analyze_template
 
-  needs: []
-
   before_script:
-    - cd /tmp
-    - git clone https://github.com/terryyin/lizard.git
-    - cd lizard
-    - python3 setup.py install
     - lizard --version
 
   script:
@@ -510,25 +514,25 @@ lizard:
 
 ###############################################################################
 # code coverage
-gcov_gcc_9:
+gcov_gcc:
   stage: analyze
 
   extends: .analyze_template
 
-  needs: []
-
   before_script:
     - gcovr --version
+    - export CC=/usr/bin/gcc-11
+    - export CXX=/usr/bin/g++-11
 
   script:
     - mkdir -p $CI_PROJECT_DIR/build
     - cd $CI_PROJECT_DIR/build
     - cmake ..
       --preset=make_all
-      -DCMAKE_CUDA_ARCHITECTURES=60
-      -DBUILD_VF_COVERAGE=ON
+      -DCMAKE_BUILD_TYPE=PROFILE
+      -DCMAKE_CUDA_ARCHITECTURES=70
     - make -j4
-    - ./bin/basicsTests
+    - ctest --output-on-failure
     - cd ..
     - mkdir coverage
     - gcovr -r $CI_PROJECT_DIR -k build -f "src" --print-summary --html coverage/coverage.html --html-details --xml coverage/coverage.xml
@@ -551,16 +555,10 @@ gcov_gcc_9:
 ###############################################################################
 # this job also produces a compile commands json file.
 clang-tidy:
-  stage: analyze
-
   extends: .analyze_template
 
-  needs: []
-
-  allow_failure: true
-
   before_script:
-    - run-clang-tidy -h
+    - run-clang-tidy-15 -h
 
   script:
     - mkdir -p $CI_PROJECT_DIR/build
@@ -570,7 +568,7 @@ clang-tidy:
       -DBUILD_VF_DOUBLE_ACCURACY=ON
       -DBUILD_VF_GPU=OFF
     - python3 ../utilities/filterCompileCommands.py compile_commands.json
-    - run-clang-tidy -quiet > clangtidy.txt
+    - run-clang-tidy-15 -quiet > clangtidy.txt
 
   artifacts:
     when: always
@@ -580,6 +578,33 @@ clang-tidy:
       - build/compile_commands.json
 
 
+###############################################################################
+##                            Sanitizer                                      ##
+###############################################################################
+sanitizer-address-leak-ub:
+  extends: .analyze_template
+  script:
+    - mkdir -p build && cd build
+    - cmake ..
+      --preset=make_all
+      -DCMAKE_CUDA_ARCHITECTURES=70
+      -DENABLE_SANITIZER_ADDRESS=ON
+      -DENABLE_SANITIZER_LEAK=ON
+      -DENABLE_SANITIZER_UNDEFINED_BEHAVIOR=ON
+    - make -j8
+    - ctest --output-on-failure
+
+sanitizer-memory:
+  extends: .analyze_template
+  script:
+    - mkdir -p build && cd build
+    - cmake ..
+      --preset=make_all
+      -DCMAKE_CUDA_ARCHITECTURES=70
+      -DENABLE_SANITIZER_MEMORY=ON
+    - make -j8
+    - ctest --output-on-failure
+
 ###############################################################################
 # doxgen
 pages:
@@ -628,7 +653,7 @@ pages:
 vf_to_phoenix:
   extends: .deploy_template
   stage: deploy
-  needs: ["gcc_9_python", "gcc_9_unit_tests", "gcc_9_python_bindings_test"]
+  needs: ["gcc_12_python", "gcc_12_unit_tests", "gcc_12_python_bindings_test"]
 
   when: manual
 
@@ -652,7 +677,7 @@ vf_wheel_to_jupyterhub:
 
   only: ["manual"]
 
-  needs: ["gcc_9_python", "gcc_9_unit_tests", "gcc_9_python_bindings_test"]
+  needs: ["gcc_12_python", "gcc_12_unit_tests", "gcc_12_python_bindings_test"]
 
   variables:
     HOST: "gitlab-runner01.irmb.bau.tu-bs.de"
@@ -680,7 +705,7 @@ sonar-scanner:
   variables:
     SONAR_HOST_URL: "http://gitlab-runner01.irmb.bau.tu-bs.de/sonarqube/"
 
-  needs: ["cppcheck","clang-tidy","gcov_gcc_9"]
+  needs: ["cppcheck","clang-tidy","gcov_gcc"]
 
   before_script:
     - cd /tmp
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..431c2f796787e5ddb22df5f93587eeac6362f9cf
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,4 @@
+{
+    "c-cpp-flylint.flexelint.enable": false,
+    "c-cpp-flylint.flawfinder.enable": false
+}
\ No newline at end of file
diff --git a/3rdParty/cuda_samples/helper_functions.h b/3rdParty/cuda_samples/helper_functions.h
index 3fc2ea47ba7d39a4bf6a882f65b16779de6de0ac..058aee7aac750787307a385d7e27b30c381c0ced 100644
--- a/3rdParty/cuda_samples/helper_functions.h
+++ b/3rdParty/cuda_samples/helper_functions.h
@@ -48,7 +48,7 @@
 #include <vector>
 
 // includes, timer, string parsing, image helpers
-#include <helper_image.h>  // helper functions for image compare, dump, data comparisons
+// #include <helper_image.h>  // helper functions for image compare, dump, data comparisons
 #include <helper_string.h>  // helper functions for string parsing
 #include <helper_timer.h>   // helper functions for timers
 
diff --git a/CMake/Sanitizers.cmake b/CMake/Sanitizers.cmake
index 6f16207fefbc2f9ca72f065950b242a4333d442e..ea37a66a1ed7d4416a5fbe54afc2390e168d848b 100644
--- a/CMake/Sanitizers.cmake
+++ b/CMake/Sanitizers.cmake
@@ -52,6 +52,7 @@ function(enable_sanitizers project_name)
        "${LIST_OF_SANITIZERS}"
        STREQUAL
        "")
+      message(STATUS "Enabling sanitizers: ${LIST_OF_SANITIZERS}")
       target_compile_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS})
       target_link_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS})
     endif()
diff --git a/CMake/compilerflags/GNU.cmake b/CMake/compilerflags/GNU.cmake
index 8d54b52a434719a1e99aa705b121593973f3375a..cf77b2228e1ac470f064db71c8f8e87f33902f04 100644
--- a/CMake/compilerflags/GNU.cmake
+++ b/CMake/compilerflags/GNU.cmake
@@ -17,10 +17,10 @@ if(NOT BUILD_VF_INCLUDE_WHAT_YOU_USE) # optimization flag '-funroll-all-loops' i
 endif()
 
 # gcov
-if (BUILD_VF_COVERAGE)
-    list(APPEND CS_COMPILER_FLAGS_CXX "--coverage")
-    set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage")
-endif()
+# According to https://gcovr.com/en/stable/cookbook.html#out-of-source-builds-with-cmake
+# This flags are used if cmake is called with -DCMAKE_BUILD_TYPE=PROFILE
+set(CMAKE_C_FLAGS_PROFILE --coverage)
+set(CMAKE_CXX_FLAGS_PROFILE --coverage)
 
 #############################################################################################################
 # warnings
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e7f62a5ba3308a7e382e1802a8cc42a1bb043b25..d82fe2b93c5103beb6a960ea4bd29914f0d982c4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -58,7 +58,6 @@ option(BUILD_VF_UNIT_TESTS "Build VirtualFluids unit tests" OFF)
 option(BUILD_VF_CLANG_TIDY "Add the clang tidy checks to the targets" OFF)
 option(BUILD_VF_INCLUDE_WHAT_YOU_USE "Add IWYU to the targets" OFF)
 option(BUILD_VF_CPPCHECK "Add cppcheck to the targets" OFF)
-option(BUILD_VF_COVERAGE "Add the -coverage compiler flag." OFF)
 
 option(BUILD_CUDA_LTO "Enables the cuda link optimization." OFF)
 
@@ -92,9 +91,12 @@ include(${VF_CMAKE_DIR}/Cache.cmake)
 include(CMakePrintHelpers)
 include(${VF_CMAKE_DIR}/VirtualFluidsMacros.cmake)
 
-IF( BUILD_VF_DOUBLE_ACCURACY )
+if(BUILD_VF_DOUBLE_ACCURACY)
     list(APPEND VF_COMPILER_DEFINITION VF_DOUBLE_ACCURACY)
-ENDIF()
+    message(STATUS "Configure VirtualFluids with double precision")
+else()
+    message(STATUS "Configure VirtualFluids with single precision")
+endif()
 
 # set gpu features
 if(BUILD_VF_GPU)
diff --git a/Containers/Ubuntu22_04.Dockerfile b/Containers/Ubuntu22_04.Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..eff34a26937107a7f5612a598306e83f22de3ab8
--- /dev/null
+++ b/Containers/Ubuntu22_04.Dockerfile
@@ -0,0 +1,46 @@
+# VirtualFluids Development Image:
+# Ubuntu 22.04
+
+FROM nvidia/cuda:12.1.1-devel-ubuntu22.04
+
+# timezone
+ARG TZ
+ENV TZ="$TZ"
+
+ARG DEBIAN_FRONTEND=noninteractive
+RUN apt-get update &&   \
+    apt-get install -y  \
+    git wget unzip software-properties-common \
+    build-essential g++-12 gcc-12 gdb \
+    ccache              \
+    ninja-build         \
+    openmpi-bin         \
+    libopenmpi-dev      \
+    libomp-15-dev          \
+    clang-15               \
+    clang-format-15        \
+    clang-tidy-15          \
+    clang-tools-15         \
+    python3.11          \
+    python3-pip         \
+    python3.11-dev      \
+    cppcheck            \
+    clangd-12           \
+    && update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 100 \
+    && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 \
+    && update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-15 100 \
+    && update-alternatives --install /usr/bin/clang clang /usr/bin/clang-15 100 \
+    && update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.11 100 \
+    && update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-12 100 \
+    && pip3 install      \
+        cmake==3.26.3    \
+        setuptools       \
+        wheel            \
+        scikit-build     \
+        pyvista          \
+        numpy            \
+        ansible          \
+        'jinja2<3.1'     \
+        gcovr==6.0       \
+        lizard==1.17.10
+
diff --git a/MANIFEST.in b/MANIFEST.in
index adafcf99560acd9da79aa060194df8263b6e77e0..196bdc09019d6028792a565d0776e2c267d3c15a 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1 +1 @@
-include pythonbindings/*/bindings*
\ No newline at end of file
+include pythonbindings/*/*.cpython*
\ No newline at end of file
diff --git a/Python/SlurmTests/poiseuille/result_collector.py b/Python/SlurmTests/poiseuille/result_collector.py
index 06efa481c8c010647531426f2af2bec2c2d7eaee..ed374b7d6dc8a32c46716c4648fc8ba35cbb9b4c 100644
--- a/Python/SlurmTests/poiseuille/result_collector.py
+++ b/Python/SlurmTests/poiseuille/result_collector.py
@@ -1,73 +1,73 @@
-from typing import Collection, List
+# from typing import Collection, List
 
-import pyvista as pv
-from poiseuille.analytical import PoiseuilleSettings, poiseuille_at_heights
-from vtk_utilities import vertical_column_from_mesh, get_values_from_indices
-from SlurmTests.poiseuille.settings import Scaling
+# import pyvista as pv
+# from poiseuille.analytical import PoiseuilleSettings, poiseuille_at_heights
+# from vtk_utilities import vertical_column_from_mesh, get_values_from_indices
+# from SlurmTests.poiseuille.settings import Scaling
 
 
-def get_output_file_name(output_folder, runtime_params):
-    timesteps = runtime_params.number_of_timesteps
-    file_name = f"{output_folder}/mq/mq{timesteps}/mq0_{timesteps}.bin.vtu"
+# def get_output_file_name(output_folder, runtime_params):
+#     timesteps = runtime_params.number_of_timesteps
+#     file_name = f"{output_folder}/mq/mq{timesteps}/mq0_{timesteps}.bin.vtu"
 
-    return file_name
+#     return file_name
 
 
-def get_mesh_for_last_timestep(output_folder, runtime_params):
-    file_name_of_last_timestep = get_output_file_name(output_folder, runtime_params)
-    mesh_of_last_timestep = pv.read(file_name_of_last_timestep)
-    return mesh_of_last_timestep
+# def get_mesh_for_last_timestep(output_folder, runtime_params):
+#     file_name_of_last_timestep = get_output_file_name(output_folder, runtime_params)
+#     mesh_of_last_timestep = pv.read(file_name_of_last_timestep)
+#     return mesh_of_last_timestep
 
 
-def get_heights_from_indices(mesh, indices):
-    return [mesh.points[index][2] for index in indices]
+# def get_heights_from_indices(mesh, indices):
+#     return [mesh.points[index][2] for index in indices]
 
 
-def get_heights(output_folder, runtime_params):
-    mesh_of_last_timestep = get_mesh_for_last_timestep(output_folder, runtime_params)
-    column_indices = vertical_column_from_mesh(mesh_of_last_timestep)
-    heights = get_heights_from_indices(mesh_of_last_timestep, column_indices)
-    return heights
+# def get_heights(output_folder, runtime_params):
+#     mesh_of_last_timestep = get_mesh_for_last_timestep(output_folder, runtime_params)
+#     column_indices = vertical_column_from_mesh(mesh_of_last_timestep)
+#     heights = get_heights_from_indices(mesh_of_last_timestep, column_indices)
+#     return heights
 
 
-def get_numerical_results(runtime_params, output_folder):
-    mesh_of_last_timestep = get_mesh_for_last_timestep(output_folder, runtime_params)
-    velocities_in_x_direction = mesh_of_last_timestep.get_array("Vx")
-    column_indices = vertical_column_from_mesh(mesh_of_last_timestep)
-    numerical_results = get_values_from_indices(velocities_in_x_direction, column_indices)
+# def get_numerical_results(runtime_params, output_folder):
+#     mesh_of_last_timestep = get_mesh_for_last_timestep(output_folder, runtime_params)
+#     velocities_in_x_direction = mesh_of_last_timestep.get_array("Vx")
+#     column_indices = vertical_column_from_mesh(mesh_of_last_timestep)
+#     numerical_results = get_values_from_indices(velocities_in_x_direction, column_indices)
 
-    return numerical_results
+#     return numerical_results
 
 
-def get_analytical_results(grid_params, physical_params, kernel, height_values):
-    channel_height = grid_params.number_of_nodes_per_direction[2]
-    settings = get_analytical_poiseuille_settings(channel_height, physical_params, kernel)
-    max_grid_height = channel_height * grid_params.node_distance
-    adjusted_height_values = [value / max_grid_height * channel_height for value in height_values]
-    analytical_results = poiseuille_at_heights(settings, adjusted_height_values)
-    return analytical_results
+# def get_analytical_results(grid_params, physical_params, kernel, height_values):
+#     channel_height = grid_params.number_of_nodes_per_direction[2]
+#     settings = get_analytical_poiseuille_settings(channel_height, physical_params, kernel)
+#     max_grid_height = channel_height * grid_params.node_distance
+#     adjusted_height_values = [value / max_grid_height * channel_height for value in height_values]
+#     analytical_results = poiseuille_at_heights(settings, adjusted_height_values)
+#     return analytical_results
 
 
-def get_analytical_poiseuille_settings(height, physical_params, kernel):
-    settings = PoiseuilleSettings()
-    settings.height = height
-    settings.viscosity = physical_params.lattice_viscosity
-    settings.density = 1
-    settings.force = kernel.forcing_in_x1
+# def get_analytical_poiseuille_settings(height, physical_params, kernel):
+#     settings = PoiseuilleSettings()
+#     settings.height = height
+#     settings.viscosity = physical_params.lattice_viscosity
+#     settings.density = 1
+#     settings.force = kernel.forcing_in_x1
 
-    return settings
+#     return settings
 
 
-def collect_results() -> (List[List[float]], List[List[float]]):
-    analytical_results = []
-    numerical_results = []
+# def collect_results() -> (List[List[float]], List[List[float]]):
+#     analytical_results = []
+#     numerical_results = []
 
-    for simulation_run in range(0, 3):
-        output_folder = f"output-{simulation_run}"
-        grid_params, physical_params, runtime_params, kernel = Scaling.configuration_for_scale_level(simulation_run)
-        heights = get_heights(output_folder, runtime_params)
-        analytical_results.append(
-            get_analytical_results(grid_params, physical_params, kernel, heights))
-        numerical_results.append(get_numerical_results(runtime_params, output_folder))
+#     for simulation_run in range(0, 3):
+#         output_folder = f"output-{simulation_run}"
+#         grid_params, physical_params, runtime_params, kernel = Scaling.configuration_for_scale_level(simulation_run)
+#         heights = get_heights(output_folder, runtime_params)
+#         analytical_results.append(
+#             get_analytical_results(grid_params, physical_params, kernel, heights))
+#         numerical_results.append(get_numerical_results(runtime_params, output_folder))
 
-    return analytical_results, numerical_results
+#     return analytical_results, numerical_results
diff --git a/Python/actuator_line/actuator_line.py b/Python/actuator_line/actuator_line.py
index d0589f402456e8ffe8320ce7f780738aef22fbe4..b8e7efb59673c3b3c9206bfda535bdd1f85e451d 100644
--- a/Python/actuator_line/actuator_line.py
+++ b/Python/actuator_line/actuator_line.py
@@ -104,8 +104,8 @@ length = np.array([6,4,1])*boundary_layer_height
 dx = boundary_layer_height/nodes_per_height
 dt = dx * mach / (np.sqrt(3) * velocity)
 velocity_ratio = dx/dt
-velocity_LB = velocity / velocity_ratio # LB units
-viscosity_LB = viscosity / (velocity_ratio * dx) # LB units
+velocity_LB = velocity / velocity_ratio  # LB units
+viscosity_LB = viscosity / (velocity_ratio * dx)  # LB units
 pressure_gradient = u_star * u_star / boundary_layer_height
 pressure_gradient_LB = pressure_gradient * (dt*dt)/dx
 
@@ -142,7 +142,7 @@ tm_factory.read_config_file(config)
 grid_scaling_factory = gpu.GridScalingFactory()
 grid_scaling_factory.set_scaling_factory(gpu.GridScaling.ScaleCompressible)
 
-grid_builder.add_coarse_grid(0.0, 0.0, 0.0, *length, dx)
+grid_builder.add_coarse_grid(0.0, 0.0, 0.0, length[0], length[1], length[2], dx)
 grid_builder.set_periodic_boundary_condition(not read_precursor, True, False)
 grid_builder.build_grids(False)
 
@@ -162,7 +162,7 @@ bc_factory.set_slip_boundary_condition(gpu.SlipBC.SlipBounceBack)
 bc_factory.set_pressure_boundary_condition(gpu.PressureBC.OutflowNonReflective)
 if read_precursor:
     bc_factory.set_precursor_boundary_condition(gpu.PrecursorBC.DistributionsPrecursor if use_distributions else gpu.PrecursorBC.VelocityPrecursor)
-para.set_outflow_pressure_correction_factor(0.0); 
+para.set_outflow_pressure_correction_factor(0.0)
 #%%
 # don't use python init functions, they are very slow! Just kept as an example.
 # Define lambda in bindings and set it here.
@@ -176,7 +176,7 @@ para.set_outflow_pressure_correction_factor(0.0);
 para.set_initial_condition_perturbed_log_law(u_star, z0, length[0], length[2], boundary_layer_height, velocity_ratio)
 
 #%%
-turb_pos = np.array([3,3,3])*turbine_diameter
+turb_pos = np.array([3, 3, 3])*turbine_diameter
 epsilon = 1.5*dx
 density = 1.225
 level = 0
@@ -185,7 +185,7 @@ n_blade_nodes = 32
 omega = 1
 blade_radii = np.arange(n_blade_nodes, dtype=np.float32)/(0.5*turbine_diameter)
 alm = gpu.ActuatorFarm(n_blades, density, n_blade_nodes, epsilon, level, dt, dx, True)
-alm.add_turbine(turb_pos[0],turb_pos[1],turb_pos[2], turbine_diameter, omega, 0, 0, blade_radii)
+alm.add_turbine(turb_pos[0], turb_pos[1], turb_pos[2], turbine_diameter, omega, 0, 0, blade_radii)
 para.add_actuator(alm)
 #%%
 planar_average_probe = gpu.probes.PlanarAverageProbe("horizontalPlanes", para.get_output_path(), 0, int(t_start_tmp_averaging/dt), int(t_averaging/dt) , int(t_start_out_probe/dt), int(t_out_probe/dt), 'z')
diff --git a/Python/boundary_layer/boundary_layer.py b/Python/boundary_layer/boundary_layer.py
index 25b3cd895f8a3a80f9fd6438e00d3e924fc13779..0ebdbb43894e6bdae55cca1f788a33c3739fb0c6 100644
--- a/Python/boundary_layer/boundary_layer.py
+++ b/Python/boundary_layer/boundary_layer.py
@@ -116,7 +116,7 @@ logger.vf_log_info(f"viscosity [10^8 dx^2/dt] = {viscosity_LB*1e8}")
 logger.vf_log_info(f"u* /(dx/dt) = {u_star*dt/dx}")
 logger.vf_log_info(f"dpdx  = {pressure_gradient}")
 logger.vf_log_info(f"dpdx /(dx/dt^2) = {pressure_gradient_LB}")
-    
+
 #%%
 
 #%%
@@ -136,6 +136,8 @@ para.set_timestep_start_out(int(t_start_out/dt))
 para.set_timestep_out(int(t_out/dt))
 para.set_timestep_end(int(t_end/dt))
 para.set_is_body_force(config.get_bool_value("bodyForce"))
+para.set_devices(np.arange(10))
+para.set_max_dev(communicator.get_number_of_process())
 #%%
 tm_factory = gpu.TurbulenceModelFactory(para)
 tm_factory.read_config_file(config)
@@ -161,13 +163,7 @@ bc_factory.set_pressure_boundary_condition(gpu.PressureBC.OutflowNonReflective)
 bc_factory.set_precursor_boundary_condition(gpu.PrecursorBC.DistributionsPrecursor if use_distributions else gpu.PrecursorBC.VelocityPrecursor)
 para.set_outflow_pressure_correction_factor(0.0); 
 #%%
-def init_func(coord_x, coord_y, coord_z):
-    return [
-        0.0, 
-        (u_star/0.4 * np.log(np.maximum(coord_z,z0)/z0) + 2.0*np.sin(np.pi*16*coord_x/length[0])*np.sin(np.pi*8*coord_z/boundary_layer_height)/(np.square(coord_z/boundary_layer_height)+1))  * dt / dx, 
-        2.0*np.sin(np.pi*16.*coord_x/length[0])*np.sin(np.pi*8.*coord_z/boundary_layer_height)/(np.square(coord_z/boundary_layer_height)+1.)  * dt / dx, 
-        8.0*u_star/0.4*(np.sin(np.pi*8.0*coord_y/boundary_layer_height)*np.sin(np.pi*8.0*coord_z/boundary_layer_height)+np.sin(np.pi*8.0*coord_x/length[0]))/(np.square(length[2]/2.0-coord_z)+1.) * dt / dx]
-para.set_initial_condition(init_func)
+para.set_initial_condition_perturbed_log_law(u_star, z0, length[0], length[2], boundary_layer_height, dx/dx)
 
 #%%
 planar_average_probe = gpu.probes.PlanarAverageProbe("horizontalPlanes", para.get_output_path(), 0, int(t_start_tmp_averaging/dt), int(t_averaging/dt) , int(t_start_out_probe/dt), int(t_out_probe/dt), 'z')
diff --git a/Python/poiseuille/test_poiseuille_l2.py b/Python/poiseuille/test_poiseuille_l2.py
index 818cba40e115945c60e4fa2ac96b3b6b5ab0bba8..f863991364974ffd9a02e9ebb212c83e1182be42 100644
--- a/Python/poiseuille/test_poiseuille_l2.py
+++ b/Python/poiseuille/test_poiseuille_l2.py
@@ -32,153 +32,154 @@ r"""
 ! \author Sven Marcus, Henry Korb
 =======================================================================================
 """
-import os
-import shutil
-import unittest
 
-import matplotlib.pyplot as plt
-import numpy as np
-import pyvista as pv
-from pyfluids import cpu
-from scipy import stats
+# import os
+# import shutil
+# import unittest
 
-from errors import normalized_l2_error
-from poiseuille.analytical import poiseuille_at_heights, PoiseuilleSettings
-from poiseuille.simulation import run_simulation
-from vtk_utilities import vertical_column_from_mesh, get_values_from_indices
+# import matplotlib.pyplot as plt
+# import numpy as np
+# import pyvista as pv
+# from pyfluids import cpu
+# from scipy import stats
 
+# from errors import normalized_l2_error
+# from poiseuille.analytical import poiseuille_at_heights, PoiseuilleSettings
+# from poiseuille.simulation import run_simulation
+# from vtk_utilities import vertical_column_from_mesh, get_values_from_indices
 
-class TestPoiseuilleFlow(unittest.TestCase):
-    node_distances = [1, 0.5, 0.25]
-    number_of_nodes = [16, 32, 64]
-    number_of_timesteps = [2_500_000, 5_000_000, 10_000_000]
-    forcings = [1e-9, 5e-10, 2.5e-10]
-    viscosities = [1e-3, 2e-3, 4e-3]
 
-    def zipped_settings(self):
-        return zip(self.node_distances,
-                   self.number_of_nodes,
-                   self.number_of_timesteps,
-                   self.forcings,
-                   self.viscosities)
+# class TestPoiseuilleFlow(unittest.TestCase):
+#     node_distances = [1, 0.5, 0.25]
+#     number_of_nodes = [16, 32, 64]
+#     number_of_timesteps = [2_500_000, 5_000_000, 10_000_000]
+#     forcings = [1e-9, 5e-10, 2.5e-10]
+#     viscosities = [1e-3, 2e-3, 4e-3]
 
-    def test_poiseuille_flow(self):
-        self.skipTest("This test is not implemented correctly yet")
-        plt.ion()
+#     def zipped_settings(self):
+#         return zip(self.node_distances,
+#                    self.number_of_nodes,
+#                    self.number_of_timesteps,
+#                    self.forcings,
+#                    self.viscosities)
 
-        physical_params = cpu.parameters.PhysicalParameters()
+#     def test_poiseuille_flow(self):
+#         self.skipTest("This test is not implemented correctly yet")
+#         plt.ion()
 
-        runtime_params = cpu.parameters.RuntimeParameters()
-        runtime_params.number_of_threads = os.cpu_count()
-        runtime_params.timestep_log_interval = 10000
+#         physical_params = cpu.parameters.PhysicalParameters()
 
-        kernel = cpu.kernel.LBMKernel(cpu.kernel.KernelType.CompressibleCumulantFourthOrderViscosity)
-        kernel.use_forcing = True
+#         runtime_params = cpu.parameters.RuntimeParameters()
+#         runtime_params.number_of_threads = os.cpu_count()
+#         runtime_params.timestep_log_interval = 10000
 
-        normalized_l2_errors = []
-        for delta_x, nodes, timesteps, forcing, viscosity in self.zipped_settings():
-            physical_params.lattice_viscosity = viscosity
-            runtime_params.number_of_timesteps = timesteps
-            kernel.forcing_in_x1 = forcing
+#         kernel = cpu.kernel.LBMKernel(cpu.kernel.KernelType.CompressibleCumulantFourthOrderViscosity)
+#         kernel.use_forcing = True
 
-            grid_params = create_grid_params_with_nodes_in_column(nodes, delta_x)
-            l2_error = get_l2_error_for_simulation(grid_params, physical_params, runtime_params, kernel)
-            normalized_l2_errors.append(l2_error)
+#         normalized_l2_errors = []
+#         for delta_x, nodes, timesteps, forcing, viscosity in self.zipped_settings():
+#             physical_params.lattice_viscosity = viscosity
+#             runtime_params.number_of_timesteps = timesteps
+#             kernel.forcing_in_x1 = forcing
 
-        nodes_as_log = [np.log10(node) for node in self.number_of_nodes]
-        l2_norms_as_log = [np.log10(l2) for l2 in normalized_l2_errors]
-        res = stats.linregress(nodes_as_log, l2_norms_as_log)
+#             grid_params = create_grid_params_with_nodes_in_column(nodes, delta_x)
+#             l2_error = get_l2_error_for_simulation(grid_params, physical_params, runtime_params, kernel)
+#             normalized_l2_errors.append(l2_error)
 
-        plt.xscale("log")
-        plt.yscale("log")
-        plt.plot(self.number_of_nodes, [np.power(10, res.intercept + res.slope * node) for node in nodes_as_log], 'r-')
-        plt.plot(self.number_of_nodes, normalized_l2_errors, "x:")
-        plt.show()
+#         nodes_as_log = [np.log10(node) for node in self.number_of_nodes]
+#         l2_norms_as_log = [np.log10(l2) for l2 in normalized_l2_errors]
+#         res = stats.linregress(nodes_as_log, l2_norms_as_log)
 
-        print(normalized_l2_errors)
-        self.assertAlmostEqual(res.slope, -2, places=2)
+#         plt.xscale("log")
+#         plt.yscale("log")
+#         plt.plot(self.number_of_nodes, [np.power(10, res.intercept + res.slope * node) for node in nodes_as_log], 'r-')
+#         plt.plot(self.number_of_nodes, normalized_l2_errors, "x:")
+#         plt.show()
 
+#         print(normalized_l2_errors)
+#         self.assertAlmostEqual(res.slope, -2, places=2)
 
-def get_l2_error_for_simulation(grid_params, physical_params, runtime_params, kernel):
-    output_folder = "./output"
-    run_simulation_with_settings(grid_params, physical_params, runtime_params, kernel, output_folder)
-    heights = get_heights(output_folder, runtime_params)
 
-    numerical_results = get_numerical_results(runtime_params, output_folder)
-    analytical_results = get_analytical_results(grid_params, physical_params, kernel, heights)
+# def get_l2_error_for_simulation(grid_params, physical_params, runtime_params, kernel):
+#     output_folder = "./output"
+#     run_simulation_with_settings(grid_params, physical_params, runtime_params, kernel, output_folder)
+#     heights = get_heights(output_folder, runtime_params)
 
-    plt.plot(heights, numerical_results)
-    plt.plot(heights, analytical_results)
-    plt.legend(["numerical", "analytical"])
-    plt.show()
+#     numerical_results = get_numerical_results(runtime_params, output_folder)
+#     analytical_results = get_analytical_results(grid_params, physical_params, kernel, heights)
 
-    return normalized_l2_error(analytical_results, numerical_results)
+#     plt.plot(heights, numerical_results)
+#     plt.plot(heights, analytical_results)
+#     plt.legend(["numerical", "analytical"])
+#     plt.show()
 
+#     return normalized_l2_error(analytical_results, numerical_results)
 
-def run_simulation_with_settings(grid_params, physical_params, runtime_params, kernel, output_folder):
-    shutil.rmtree(output_folder, ignore_errors=True)
-    run_simulation(physical_params, grid_params, runtime_params, kernel)
 
+# def run_simulation_with_settings(grid_params, physical_params, runtime_params, kernel, output_folder):
+#     shutil.rmtree(output_folder, ignore_errors=True)
+#     run_simulation(physical_params, grid_params, runtime_params, kernel)
 
-def get_heights(output_folder, runtime_params):
-    mesh_of_last_timestep = get_mesh_for_last_timestep(output_folder, runtime_params)
-    column_indices = vertical_column_from_mesh(mesh_of_last_timestep)
-    heights = get_heights_from_indices(mesh_of_last_timestep, column_indices)
-    return heights
 
+# def get_heights(output_folder, runtime_params):
+#     mesh_of_last_timestep = get_mesh_for_last_timestep(output_folder, runtime_params)
+#     column_indices = vertical_column_from_mesh(mesh_of_last_timestep)
+#     heights = get_heights_from_indices(mesh_of_last_timestep, column_indices)
+#     return heights
 
-def get_numerical_results(runtime_params, output_folder):
-    mesh_of_last_timestep = get_mesh_for_last_timestep(output_folder, runtime_params)
-    velocities_in_x_direction = mesh_of_last_timestep.get_array("Vx")
-    column_indices = vertical_column_from_mesh(mesh_of_last_timestep)
-    numerical_results = get_values_from_indices(velocities_in_x_direction, column_indices)
 
-    return numerical_results
+# def get_numerical_results(runtime_params, output_folder):
+#     mesh_of_last_timestep = get_mesh_for_last_timestep(output_folder, runtime_params)
+#     velocities_in_x_direction = mesh_of_last_timestep.get_array("Vx")
+#     column_indices = vertical_column_from_mesh(mesh_of_last_timestep)
+#     numerical_results = get_values_from_indices(velocities_in_x_direction, column_indices)
 
+#     return numerical_results
 
-def get_analytical_results(grid_params, physical_params, kernel, height_values):
-    channel_height = grid_params.number_of_nodes_per_direction[2]
-    settings = get_analytical_poiseuille_settings(channel_height, physical_params, kernel)
-    max_grid_height = channel_height * grid_params.node_distance
-    adjusted_height_values = [value / max_grid_height * channel_height for value in height_values]
-    analytical_results = poiseuille_at_heights(settings, adjusted_height_values)
-    return analytical_results
 
+# def get_analytical_results(grid_params, physical_params, kernel, height_values):
+#     channel_height = grid_params.number_of_nodes_per_direction[2]
+#     settings = get_analytical_poiseuille_settings(channel_height, physical_params, kernel)
+#     max_grid_height = channel_height * grid_params.node_distance
+#     adjusted_height_values = [value / max_grid_height * channel_height for value in height_values]
+#     analytical_results = poiseuille_at_heights(settings, adjusted_height_values)
+#     return analytical_results
 
-def get_mesh_for_last_timestep(output_folder, runtime_params):
-    file_name_of_last_timestep = get_output_file_name(output_folder, runtime_params)
-    mesh_of_last_timestep = pv.read(file_name_of_last_timestep)
-    return mesh_of_last_timestep
 
+# def get_mesh_for_last_timestep(output_folder, runtime_params):
+#     file_name_of_last_timestep = get_output_file_name(output_folder, runtime_params)
+#     mesh_of_last_timestep = pv.read(file_name_of_last_timestep)
+#     return mesh_of_last_timestep
 
-def get_analytical_poiseuille_settings(height, physical_params, kernel):
-    settings = PoiseuilleSettings()
-    settings.height = height
-    settings.viscosity = physical_params.lattice_viscosity
-    settings.density = 1
-    settings.force = kernel.forcing_in_x1
 
-    return settings
+# def get_analytical_poiseuille_settings(height, physical_params, kernel):
+#     settings = PoiseuilleSettings()
+#     settings.height = height
+#     settings.viscosity = physical_params.lattice_viscosity
+#     settings.density = 1
+#     settings.force = kernel.forcing_in_x1
 
+#     return settings
 
-def get_output_file_name(output_folder, runtime_params):
-    timesteps = runtime_params.number_of_timesteps
-    file_name = f"{output_folder}/mq/mq{timesteps}/mq0_{timesteps}.bin.vtu"
 
-    return file_name
+# def get_output_file_name(output_folder, runtime_params):
+#     timesteps = runtime_params.number_of_timesteps
+#     file_name = f"{output_folder}/mq/mq{timesteps}/mq0_{timesteps}.bin.vtu"
 
+#     return file_name
 
-def get_heights_from_indices(mesh, indices):
-    return [mesh.points[index][2] for index in indices]
 
+# def get_heights_from_indices(mesh, indices):
+#     return [mesh.points[index][2] for index in indices]
 
-def create_grid_params_with_nodes_in_column(nodes_in_column, delta_x):
-    grid_params = cpu.parameters.GridParameters()
-    grid_params.node_distance = delta_x
-    grid_params.number_of_nodes_per_direction = [1, 1, nodes_in_column]
-    grid_params.blocks_per_direction = [1, 1, 8]
-    grid_params.periodic_boundary_in_x1 = True
-    grid_params.periodic_boundary_in_x2 = True
-    grid_params.periodic_boundary_in_x3 = False
 
-    return grid_params
+# def create_grid_params_with_nodes_in_column(nodes_in_column, delta_x):
+#     grid_params = cpu.parameters.GridParameters()
+#     grid_params.node_distance = delta_x
+#     grid_params.number_of_nodes_per_direction = [1, 1, nodes_in_column]
+#     grid_params.blocks_per_direction = [1, 1, 8]
+#     grid_params.periodic_boundary_in_x1 = True
+#     grid_params.periodic_boundary_in_x2 = True
+#     grid_params.periodic_boundary_in_x3 = False
+
+#     return grid_params
diff --git a/Python/requirements.txt b/Python/requirements.txt
index 8628634d1b85ebc0b07328d563d479f35641be97..355bb47d748f0b593ed07da186d956d4a5cf48a1 100644
--- a/Python/requirements.txt
+++ b/Python/requirements.txt
@@ -4,20 +4,19 @@ cycler==0.10.0
 imageio==2.9.0
 iniconfig==1.1.1
 kiwisolver==1.3.1
-matplotlib==3.3.3
+matplotlib==3.7.1
 meshio==4.3.8
-numpy==1.19.5
+numpy==1.24.0
 packaging==20.8
-Pillow==8.1.0
+Pillow==9.5.0
 pluggy==0.13.1
 py==1.10.0
 pyparsing==2.4.7
 pytest==6.2.1
 python-dateutil==2.8.1
-pyvista==0.28.1
-scipy==1.6.1
+pyvista==0.39.1
+scipy==1.10
 scooby==0.5.6
 six==1.15.0
 toml==0.10.2
-transforms3d==0.3.1
-vtk==9.0.1
+transforms3d==0.4.1
diff --git a/apps/cpu/AcousticPulse/ap.cpp b/apps/cpu/AcousticPulse/ap.cpp
index 77ddfbf626e25b8c5d17d438255e37b4977dbddd..ac69eee6d2d158a2ea8eea27da8bf968b92f5f06 100644
--- a/apps/cpu/AcousticPulse/ap.cpp
+++ b/apps/cpu/AcousticPulse/ap.cpp
@@ -179,9 +179,9 @@ void run()
       }
 
       //set connectors  
-     //SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetInterpolationProcessor());
-      SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
-      //dynamicPointerCast<CompressibleOffsetMomentsInterpolationProcessor>(iProcessor)->setBulkViscosity(nuLB, bulckViscosity);
+     //SPtr<Interpolator> iProcessor(new CompressibleOffsetInterpolator());
+      SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolator());
+      //dynamicPointerCast<CompressibleOffsetMomentsInterpolator>(iProcessor)->setBulkViscosity(nuLB, bulckViscosity);
       SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
 
       UBLOG(logINFO, "SetConnectorsBlockVisitor:start");
diff --git a/apps/cpu/BoxBenchmark/bb.cpp b/apps/cpu/BoxBenchmark/bb.cpp
index 7d5c0ec2f4fdf4627b87a32727925f62a3bc89e9..0f0c7d6c1ddd066f36f95d8f87be7afae3ddf2c8 100644
--- a/apps/cpu/BoxBenchmark/bb.cpp
+++ b/apps/cpu/BoxBenchmark/bb.cpp
@@ -130,7 +130,7 @@ void run(string configname)
          ppblocks.reset();
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          //SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //grid->accept(setConnsVisitor);
 
@@ -192,7 +192,7 @@ void run(string configname)
          rcp.restart((int)restartStep);
          grid->setTimeStep(restartStep);
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/ConvectionOfVortex/cov.cpp b/apps/cpu/ConvectionOfVortex/cov.cpp
index baa136d6a3a96e1e4ce86ce187f116e2c560530c..bfe29fc9bb6c18782212f8cb9a080d1815b8c6a1 100644
--- a/apps/cpu/ConvectionOfVortex/cov.cpp
+++ b/apps/cpu/ConvectionOfVortex/cov.cpp
@@ -164,15 +164,15 @@ void run()
       ppblocks.reset();
 
       //set connectors  
-      //SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetInterpolationProcessor());
-      //SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
-      //dynamicPointerCast<CompressibleOffsetMomentsInterpolationProcessor>(iProcessor)->setBulkOmegaToOmega(true);
-      //SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetSquarePressureInterpolationProcessor());
+      //SPtr<Interpolator> iProcessor(new CompressibleOffsetInterpolator());
+      //SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolator());
+      //dynamicPointerCast<CompressibleOffsetMomentsInterpolator>(iProcessor)->setBulkOmegaToOmega(true);
+      //SPtr<Interpolator> iProcessor(new CompressibleOffsetSquarePressureInterpolator());
 
       OneDistributionSetConnectorsBlockVisitor setConnsVisitor(comm);
       grid->accept(setConnsVisitor);
 
-      SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
+      SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolator());
       SetInterpolationConnectorsBlockVisitor setInterConnsVisitor(comm, nuLB, iProcessor);
       grid->accept(setInterConnsVisitor);
 
diff --git a/apps/cpu/CouetteFlow/cflow.cpp b/apps/cpu/CouetteFlow/cflow.cpp
index e81c3bb008948814d79577311498dbfd5f1a76f2..112c0c96bd3c9bde56c3ef53f0047569fec031b2 100644
--- a/apps/cpu/CouetteFlow/cflow.cpp
+++ b/apps/cpu/CouetteFlow/cflow.cpp
@@ -243,7 +243,7 @@ void bflow(string configname)
 
 
       //set connectors
-      //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+      //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
       //SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, k, iProcessor);
       //grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/DHIT/dhit.cpp b/apps/cpu/DHIT/dhit.cpp
index 850a531a9ac490ed195ad17ce298ca5cf027151a..e06db26b8706bad1f94fec432868daabea8d1cce 100644
--- a/apps/cpu/DHIT/dhit.cpp
+++ b/apps/cpu/DHIT/dhit.cpp
@@ -117,7 +117,7 @@ void run(string configname)
       ppblocks.reset();
 
       //set connectors
-      InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+      InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
       SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
       grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/DLR-F16-Porous/f16.cpp b/apps/cpu/DLR-F16-Porous/f16.cpp
index 7ddd135b2996c794e2802e235fdedc2a3013cdf3..791c1c926dbdf86bf1c2f1634288696248cdb305 100644
--- a/apps/cpu/DLR-F16-Porous/f16.cpp
+++ b/apps/cpu/DLR-F16-Porous/f16.cpp
@@ -656,8 +656,8 @@ void run(string configname)
          ////////////////////////////////////////////////////////////////////////////
       }
       ////set connectors
-      SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
-      dynamicPointerCast<CompressibleOffsetMomentsInterpolationProcessor>(iProcessor)->setBulkViscosity(nuLB, bulckViscosity);
+      SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolator());
+      dynamicPointerCast<CompressibleOffsetMomentsInterpolator>(iProcessor)->setBulkViscosity(nuLB, bulckViscosity);
       SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
       grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/DLR-F16-Solid/f16.cpp b/apps/cpu/DLR-F16-Solid/f16.cpp
index 328da5dc54b5a2db751eb71ad1ce8810cb471470..2a9893ef28efba2ee163e6e9d8c62ffadd68568a 100644
--- a/apps/cpu/DLR-F16-Solid/f16.cpp
+++ b/apps/cpu/DLR-F16-Solid/f16.cpp
@@ -634,8 +634,8 @@ void run(string configname)
       }
       
       ////set connectors
-      SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
-      dynamicPointerCast<CompressibleOffsetMomentsInterpolationProcessor>(iProcessor)->setBulkViscosity(nuLB, bulckViscosity);
+      SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolator());
+      dynamicPointerCast<CompressibleOffsetMomentsInterpolator>(iProcessor)->setBulkViscosity(nuLB, bulckViscosity);
       SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
       grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/DLR-F16/f16.cpp b/apps/cpu/DLR-F16/f16.cpp
index 2bbc1b8ed63be110d4b6ccc98cdcdb88337d4760..17fef2d15f4026d4b7035a896d78664350f6b86c 100644
--- a/apps/cpu/DLR-F16/f16.cpp
+++ b/apps/cpu/DLR-F16/f16.cpp
@@ -978,8 +978,8 @@ void run(string configname)
 
 
          ////set connectors
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -1101,7 +1101,7 @@ void run(string configname)
          
                  
          ////////////////////////////////////////////////////////////////////////////
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/FallingSphere/FallingSphere.cpp b/apps/cpu/FallingSphere/FallingSphere.cpp
index ba837fcf15b32a65983b633c768aea6250a976a7..4b1a1825551f38359428f8b6f60dff08abadf042 100644
--- a/apps/cpu/FallingSphere/FallingSphere.cpp
+++ b/apps/cpu/FallingSphere/FallingSphere.cpp
@@ -11,6 +11,8 @@ using namespace std;
 
 int main(int argc, char *argv[])
 {
+    Sleep(30000);
+
     std::shared_ptr<vf::mpi::Communicator> comm = vf::mpi::MPICommunicator::getInstance();
     int myid                                        = comm->getProcessID();
 
@@ -24,7 +26,7 @@ int main(int argc, char *argv[])
     double g_maxX2 = 1;
     double g_maxX3 = 10;
 
-    int blockNX[3] = { 16, 16, 16 };
+    int blockNX[3] = { 32, 32, 32 };
     double dx = 1./32.;
 
     double d_part = 0.25;
@@ -54,7 +56,7 @@ int main(int argc, char *argv[])
     grid->setDeltaX(dx);
     grid->setBlockNX(blockNX[0], blockNX[1], blockNX[2]);
 
-    string outputPath = "f:/temp/FallingSpheresTest";
+    string outputPath = "f:/temp/FallingSpheresTestMPI";
 
     UbSystem::makeDirectory(outputPath);
     UbSystem::makeDirectory(outputPath + "/liggghts");
@@ -68,12 +70,6 @@ int main(int argc, char *argv[])
     GenBlocksGridVisitor genBlocks(gridCube);
     grid->accept(genBlocks);
 
-    SPtr<SimulationObserver> ppblocks =
-        make_shared <WriteBlocksSimulationObserver>(grid, SPtr<UbScheduler>(new UbScheduler(1)), outputPath,
-                                                          WbWriterVtkXmlBinary::getInstance(), comm);
-    ppblocks->update(0);
-    ppblocks.reset();
-
     double dx2 = 2.0 * dx;
     GbCuboid3DPtr wallZmin(
         new GbCuboid3D(g_minX1 - dx2, g_minX2 - dx2, g_minX3 - dx2, g_maxX1 + dx2, g_maxX2 + dx2, g_minX3));
@@ -85,47 +81,39 @@ int main(int argc, char *argv[])
     SPtr<D3Q27Interactor> wallZminInt(new D3Q27Interactor(wallZmin, grid, noSlipBC, Interactor3D::SOLID));
     SPtr<D3Q27Interactor> wallZmaxInt(new D3Q27Interactor(wallZmax, grid, noSlipBC, Interactor3D::SOLID));
 
-    InteractorsHelper intHelper(grid, metisVisitor, true);
-    intHelper.addInteractor(wallZminInt);
-    intHelper.addInteractor(wallZmaxInt);
-    intHelper.selectBlocks();
-
-    SetKernelBlockVisitor kernelVisitor(kernel, nuLB, 1e9, 1e9);
-    grid->accept(kernelVisitor);
-
-    intHelper.setBC();
 
-    InitDistributionsBlockVisitor initVisitor;
-    grid->accept(initVisitor);
+    SPtr<SimulationObserver> ppblocks = make_shared<WriteBlocksSimulationObserver>(grid, SPtr<UbScheduler>(new UbScheduler(1)), outputPath, WbWriterVtkXmlBinary::getInstance(), comm);
+    ppblocks->update(0);
 
+    MPI_Comm mpi_comm = *(MPI_Comm *)(comm->getNativeCommunicator());
+    LiggghtsCouplingWrapper wrapper(argv, mpi_comm);
     SPtr<UbScheduler> lScheduler = make_shared<UbScheduler>(1);
     string inFile1 = "d:/Projects/VirtualFluids_Develop/apps/cpu/FallingSphere/in.lbdem";
     string inFile2 = "d:/Projects/VirtualFluids_Develop/apps/cpu/FallingSphere/in2.lbdem";
-    MPI_Comm mpi_comm = *(MPI_Comm*)(comm->getNativeCommunicator());
-    LiggghtsCouplingWrapper wrapper(argv, mpi_comm);
-
 
- 
     // SPtr<LBMUnitConverter> units = std::make_shared<LBMUnitConverter>(r_p, 1.480, 2060, r_p/dx);
-    //SPtr<LBMUnitConverter> units = std::make_shared<LBMUnitConverter>(r_p, LBMUnitConverter::AIR_20C, r_p / dx);
+    // SPtr<LBMUnitConverter> units = std::make_shared<LBMUnitConverter>(r_p, LBMUnitConverter::AIR_20C, r_p / dx);
     SPtr<LBMUnitConverter> units = std::make_shared<LBMUnitConverter>(r_p, 0.1, 1000, r_p / dx, 0.01);
     std::cout << units->toString() << std::endl;
 
     double v_frac = 0.1;
-    double dt_phys   = units->getFactorTimeLbToW();
+    double dt_phys = units->getFactorTimeLbToW();
     int demSubsteps = 10;
-    double dt_dem   = dt_phys / (double)demSubsteps;
-    int vtkSteps    = 100;
-    string demOutDir = outputPath; 
+    double dt_dem = dt_phys / (double)demSubsteps;
+    int vtkSteps = 100;
+    string demOutDir = outputPath;
 
     wrapper.execCommand("echo none");
 
     wrapper.setVariable("d_part", d_part);
-    //wrapper.setVariable("r_part", d_part/2.);
-    //wrapper.setVariable("v_frac", v_frac);
+    // wrapper.setVariable("r_part", d_part/2.);
+    // wrapper.setVariable("v_frac", v_frac);
+
+    wrapper.execFile((char *)inFile1.c_str());
+
+    SPtr<LiggghtsCouplingSimulationObserver> lcSimulationObserver = make_shared<LiggghtsCouplingSimulationObserver>(grid, lScheduler, comm, wrapper, demSubsteps, units);
+    SPtr<Grid3DVisitor> partVisitor = make_shared<LiggghtsPartitioningGridVisitor>((g_maxX1 - g_minX1) / dx, (g_maxX2 - g_minX2) / dx, (g_maxX3 - g_minX3) / dx, wrapper.lmp);
 
-    wrapper.execFile((char*)inFile1.c_str());
- 
     //// set timestep and output directory
     wrapper.setVariable("t_step", dt_dem);
     wrapper.setVariable("dmp_stp", vtkSteps * demSubsteps);
@@ -133,9 +121,22 @@ int main(int argc, char *argv[])
 
     wrapper.execFile((char *)inFile2.c_str());
     wrapper.runUpto(demSubsteps - 1);
-  
-    SPtr<LiggghtsCouplingSimulationObserver> lcSimulationObserver =
-        make_shared<LiggghtsCouplingSimulationObserver>(grid, lScheduler, comm, wrapper, demSubsteps, units);
+
+    InteractorsHelper intHelper(grid, partVisitor, false);
+    intHelper.addInteractor(wallZminInt);
+    intHelper.addInteractor(wallZmaxInt);
+    intHelper.selectBlocks();
+
+    ppblocks->update(1);
+    ppblocks.reset();
+
+    SetKernelBlockVisitor kernelVisitor(kernel, nuLB, 1e9, 1e9);
+    grid->accept(kernelVisitor);
+
+    intHelper.setBC();
+
+    InitDistributionsBlockVisitor initVisitor;
+    grid->accept(initVisitor);
 
     // boundary conditions grid
     {
@@ -158,6 +159,9 @@ int main(int argc, char *argv[])
         new WriteMacroscopicQuantitiesSimulationObserver(grid, visSch, outputPath, WbWriterVtkXmlBinary::getInstance(),
                                                   SPtr<LBMUnitConverter>(new LBMUnitConverter()), comm));
 
+    int numOfThreads = 1;
+    omp_set_num_threads(numOfThreads);
+
     int endTime = 3000; //20;
     SPtr<Simulation> simulation(new Simulation(grid, lScheduler, endTime));
     simulation->addSimulationObserver(lcSimulationObserver);
diff --git a/apps/cpu/FallingSphere/in.lbdem b/apps/cpu/FallingSphere/in.lbdem
index b47a85c997fce75ba082490b305bbe9b55caeb25..5d0cfb511774c5270918f4e7007224d36080232c 100644
--- a/apps/cpu/FallingSphere/in.lbdem
+++ b/apps/cpu/FallingSphere/in.lbdem
@@ -11,7 +11,7 @@ communicate	single vel yes
 boundary	f f f
 newton		off
 
-processors * * 1
+processors 1 1 *
 region		box block 0. 1. 0. 1. 0. 10. units box
 create_box	1 box
 
@@ -42,7 +42,7 @@ fix xwalls2 all wall/gran model hertz tangential history primitive type 1 xplane
 fix ywalls1 all wall/gran model hertz tangential history primitive type 1 yplane 0.
 fix ywalls2 all wall/gran model hertz tangential history primitive type 1 yplane 1.
 fix zwalls1 all wall/gran model hertz tangential history primitive type 1 zplane 0.
-fix zwalls2 all wall/gran model hertz tangential history primitive type 1 zplane 2.
+fix zwalls2 all wall/gran model hertz tangential history primitive type 1 zplane 10.
 
 create_atoms 1 single 0.5 0.5 9.75
 #create_atoms 1 single 0.38 0.05 0.05
diff --git a/apps/cpu/FlowAroundCylinder/cylinder.cfg b/apps/cpu/FlowAroundCylinder/cylinder.cfg
index 97ece40e65d4ffe47a75e5377db49bd0018bbff6..1869a668ad6a8a456a5b131234c082b05d9b17be 100644
--- a/apps/cpu/FlowAroundCylinder/cylinder.cfg
+++ b/apps/cpu/FlowAroundCylinder/cylinder.cfg
@@ -1,8 +1,8 @@
-pathOut = d:/temp/cylinder_test_naming
+pathOut = ./output/FlowAroundCylinder
 
 numOfThreads = 8
 availMem = 15e9
-refineLevel = 0
+refineLevel = 1
 blockNx = 25 41 41
 uLB = 0.001
 #dx = 0.005
diff --git a/apps/cpu/FlowAroundCylinder/cylinder.cpp b/apps/cpu/FlowAroundCylinder/cylinder.cpp
index f8c2ac4674a7bfa98d42c0be4ebf20365f579695..5956a48a8bdf08d11047400f25302005d080d872 100644
--- a/apps/cpu/FlowAroundCylinder/cylinder.cpp
+++ b/apps/cpu/FlowAroundCylinder/cylinder.cpp
@@ -291,12 +291,13 @@ void run(string configname)
       }
 
 	  //set connectors
-	  //InterpolationProcessorPtr iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
+	  //InterpolationProcessorPtr iProcessor(new CompressibleOffsetMomentsInterpolator());
 	  //SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nueLB, iProcessor);
       OneDistributionSetConnectorsBlockVisitor setConnsVisitor(comm);
 	  grid->accept(setConnsVisitor);
 
-      SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
+      SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolator());
+    //   SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor_old());
       SetInterpolationConnectorsBlockVisitor setInterConnsVisitor(comm, nueLB, iProcessor);
       grid->accept(setInterConnsVisitor);
 
diff --git a/apps/cpu/Hagen_Poiseuille_flow/pflow.cpp b/apps/cpu/Hagen_Poiseuille_flow/pflow.cpp
index 074e8c3aa9b338fa00db0718862d20c7e99f5e55..5d5e47fddeecaf06b3b23590833ff2dc12d610fb 100644
--- a/apps/cpu/Hagen_Poiseuille_flow/pflow.cpp
+++ b/apps/cpu/Hagen_Poiseuille_flow/pflow.cpp
@@ -553,8 +553,8 @@ void pflowdp(string configname)
          //////////////////////////////////////
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -657,7 +657,7 @@ void pflowdp(string configname)
          grid->setTimeStep(restartStep);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Hagen_Poiseuille_flow2/pflow2.cpp b/apps/cpu/Hagen_Poiseuille_flow2/pflow2.cpp
index 40bf20ecabe23637b6271edd6ac6c4fd951f4760..f298d697f554f002f42438955ecbb3a3308ed219 100644
--- a/apps/cpu/Hagen_Poiseuille_flow2/pflow2.cpp
+++ b/apps/cpu/Hagen_Poiseuille_flow2/pflow2.cpp
@@ -194,7 +194,7 @@ void pflowdp(string configname)
          //////////////////////////////////////
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -280,7 +280,7 @@ void pflowdp(string configname)
          grid->accept(bcVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/HerschelBulkleyModel/hbflow.cpp b/apps/cpu/HerschelBulkleyModel/hbflow.cpp
index 83686a88495ef5fc2a3ce8529453f2d59d30dab7..6abe6b5c55ce3fb3c54d5dd169a06b47026b9b3e 100644
--- a/apps/cpu/HerschelBulkleyModel/hbflow.cpp
+++ b/apps/cpu/HerschelBulkleyModel/hbflow.cpp
@@ -290,7 +290,7 @@ void bflow(string configname)
 
 
       //set connectors
-      //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+      //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
       //SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, k, iProcessor);
       //grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/InterfaceTest/itest.cpp b/apps/cpu/InterfaceTest/itest.cpp
index face949bd7d68c8d4fe94d7e32dc728b7818f42f..723802f6d3160dd79c28c2347ed311d360020d77 100644
--- a/apps/cpu/InterfaceTest/itest.cpp
+++ b/apps/cpu/InterfaceTest/itest.cpp
@@ -94,9 +94,9 @@ void run()
       ppblocks.reset();
 
       //set connectors
-      //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
-      InterpolationProcessorPtr iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
-      dynamicPointerCast<CompressibleOffsetMomentsInterpolationProcessor>(iProcessor)->setBulkOmegaToOmega(true);
+      //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
+      InterpolationProcessorPtr iProcessor(new CompressibleOffsetMomentsInterpolator());
+      dynamicPointerCast<CompressibleOffsetMomentsInterpolator>(iProcessor)->setBulkOmegaToOmega(true);
       SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
 
       UBLOG(logINFO, "SetConnectorsBlockVisitor:start");
diff --git a/apps/cpu/JetBreakup/CMakeLists.txt b/apps/cpu/JetBreakup/CMakeLists.txt
index b5bb536cf0c0b4820953ade37b1b5ccca265d7f2..162e9c959fc27171e3f0d7e1df5e62eb6ff7ef87 100644
--- a/apps/cpu/JetBreakup/CMakeLists.txt
+++ b/apps/cpu/JetBreakup/CMakeLists.txt
@@ -3,4 +3,4 @@
 ########################################################
 PROJECT(JetBreakup)
 
-vf_add_library(BUILDTYPE binary PRIVATE_LINK VirtualFluidsCore basics ${MPI_CXX_LIBRARIES} MultiphaseFlow FILES JetBreakup.cpp )
\ No newline at end of file
+vf_add_library(BUILDTYPE binary PRIVATE_LINK VirtualFluidsCore basics ${MPI_CXX_LIBRARIES} MultiphaseFlow NonNewtonianFluids FILES JetBreakup.cpp )
\ No newline at end of file
diff --git a/apps/cpu/JetBreakup/JetBreakup.cpp b/apps/cpu/JetBreakup/JetBreakup.cpp
index 235987e83997e63248af66d78d0397aa9eab8c40..c126dddc36962e7728a6119c227a8e8ffdb0dccd 100644
--- a/apps/cpu/JetBreakup/JetBreakup.cpp
+++ b/apps/cpu/JetBreakup/JetBreakup.cpp
@@ -2,14 +2,13 @@
 #include <memory>
 #include <string>
 
-#include "VirtualFluids.h"
 #include "MultiphaseFlow/MultiphaseFlow.h"
+#include "VirtualFluids.h"
 
 using namespace std;
 
 void setInflowBC(real x1, real x2, real x3, real radius, int dir)
 {
-
 }
 
 void run(string configname)
@@ -24,20 +23,20 @@ void run(string configname)
         config.load(configname);
 
         string pathname = config.getValue<string>("pathname");
-        //string pathGeo = config.getValue<string>("pathGeo");
-        //string geoFile = config.getValue<string>("geoFile");
+        // string pathGeo = config.getValue<string>("pathGeo");
+        // string geoFile = config.getValue<string>("geoFile");
         int numOfThreads = config.getValue<int>("numOfThreads");
         vector<int> blocknx = config.getVector<int>("blocknx");
-        //vector<double> boundingBox = config.getVector<double>("boundingBox");
-        // vector<double>  length = config.getVector<double>("length");
+        // vector<double> boundingBox = config.getVector<double>("boundingBox");
+        //  vector<double>  length = config.getVector<double>("length");
         real U_LB = config.getValue<real>("U_LB");
         // double uF2                         = config.getValue<double>("uF2");
-        //double nuL = config.getValue<double>("nuL");
-        //double nuG = config.getValue<double>("nuG");
-        //double densityRatio = config.getValue<double>("densityRatio");
-        //double sigma = config.getValue<double>("sigma");
+        // double nuL = config.getValue<double>("nuL");
+        // double nuG = config.getValue<double>("nuG");
+        // double densityRatio = config.getValue<double>("densityRatio");
+        // double sigma = config.getValue<double>("sigma");
         int interfaceWidth = config.getValue<int>("interfaceWidth");
-        //double D          = config.getValue<double>("D");
+        // double D          = config.getValue<double>("D");
         real theta = config.getValue<real>("contactAngle");
         real D_LB = config.getValue<real>("D_LB");
         real phiL = config.getValue<real>("phi_L");
@@ -48,24 +47,21 @@ void run(string configname)
         real endTime = config.getValue<real>("endTime");
         real outTime = config.getValue<real>("outTime");
         real availMem = config.getValue<real>("availMem");
-        //int refineLevel = config.getValue<int>("refineLevel");
-        //double Re = config.getValue<double>("Re");
-        
+        // int refineLevel = config.getValue<int>("refineLevel");
+        // double Re = config.getValue<double>("Re");
+
         bool logToFile = config.getValue<bool>("logToFile");
         real restartStep = config.getValue<real>("restartStep");
         real cpStart = config.getValue<real>("cpStart");
         real cpStep = config.getValue<real>("cpStep");
         bool newStart = config.getValue<bool>("newStart");
 
-
-
         int caseN = config.getValue<int>("case");
 
         SPtr<vf::mpi::Communicator> comm = vf::mpi::MPICommunicator::getInstance();
         int myid = comm->getProcessID();
 
-        if (myid == 0)
-            UBLOG(logINFO, "Jet Breakup: Start!");
+        if (myid == 0) UBLOG(logINFO, "Jet Breakup: Start!");
 
         if (logToFile) {
 #if defined(__unix__)
@@ -84,25 +80,25 @@ void run(string configname)
 
         // Sleep(30000);
 
-        real rho_h=0, rho_l=0, r_rho=0, mu_h=0, /*mu_l,*/ Uo=0, D=0, sigma=0;
+        real rho_h = 0, rho_l = 0, r_rho = 0, mu_h = 0, /*mu_l,*/ Uo = 0, D = 0, sigma = 0;
 
         switch (caseN) {
-            case 1: 
-                //density of heavy fluid (kg/m^3)
-                rho_h = 848; 
-                //density of light fluid (kg/m^3)
+            case 1:
+                // density of heavy fluid (kg/m^3)
+                rho_h = 848;
+                // density of light fluid (kg/m^3)
                 rho_l = 34.5;
-                //density ratio
+                // density ratio
                 r_rho = rho_h / rho_l;
-                //dynamic viscosity of heavy fluid (Pa � s)
+                // dynamic viscosity of heavy fluid (Pa � s)
                 mu_h = 2.87e-3;
-                //dynamic viscosity of light fluid (Pa � s)
-                //mu_l = 1.97e-5;
-                //velocity (m/s)
+                // dynamic viscosity of light fluid (Pa � s)
+                // mu_l = 1.97e-5;
+                // velocity (m/s)
                 Uo = 100;
-                //diameter of jet (m)
+                // diameter of jet (m)
                 D = 0.0001;
-                //surface tension (N/m)
+                // surface tension (N/m)
                 sigma = 0.03;
                 break;
             case 2:
@@ -115,7 +111,7 @@ void run(string configname)
                 // dynamic viscosity of heavy fluid (Pa � s)
                 mu_h = 2.87e-3;
                 // dynamic viscosity of light fluid (Pa � s)
-                //mu_l = 1.84e-5;
+                // mu_l = 1.84e-5;
                 // velocity (m/s)
                 Uo = 200;
                 // diameter of jet (m)
@@ -133,14 +129,14 @@ void run(string configname)
                 // dynamic viscosity of heavy fluid (Pa � s)
                 mu_h = 2.87e-3;
                 // dynamic viscosity of light fluid (Pa � s)
-                //mu_l = 1.84e-5;
+                // mu_l = 1.84e-5;
                 // velocity (m/s)
                 Uo = 200;
                 // diameter of jet (m)
                 D = 0.0001;
                 // surface tension (N/m)
                 sigma = 0.03;
-                break;                
+                break;
         }
 
         real Re = rho_h * Uo * D / mu_h;
@@ -149,14 +145,15 @@ void run(string configname)
         real dx = D / D_LB;
         real nu_h = U_LB * D_LB / Re;
         real nu_l = nu_h;
+        nu_h *= 100;
 
         real rho_h_LB = 1;
-        //surface tension
+        // surface tension
         real sigma_LB = rho_h_LB * U_LB * U_LB * D_LB / We;
 
         // LBMReal dLB = 0; // = length[1] / dx;
         real rhoLB = 0.0;
-        //LBMReal nuLB = nu_l; //(uLB*dLB) / Re;
+        // LBMReal nuLB = nu_l; //(uLB*dLB) / Re;
 
         real beta = 12.0 * sigma_LB / interfaceWidth;
         real kappa = 1.5 * interfaceWidth * sigma_LB;
@@ -177,18 +174,18 @@ void run(string configname)
             UBLOG(logINFO, "path = " << pathname);
         }
 
-                    // bounding box
-            real g_minX1 = 0;
-            real g_minX2 = 0;
-            real g_minX3 = 0;
+        // bounding box
+        real g_minX1 = 0;
+        real g_minX2 = 0;
+        real g_minX3 = 0;
 
-            //double g_maxX1 = 8.0*D;
-            //double g_maxX2 = 2.5*D;
-            //double g_maxX3 = 2.5*D;
+        // double g_maxX1 = 8.0*D;
+        // double g_maxX2 = 2.5*D;
+        // double g_maxX3 = 2.5*D;
 
-             real g_maxX1 = 8.0 * D;
-             real g_maxX2 = 5 * D;
-             real g_maxX3 = 5 * D;
+        real g_maxX1 = 2.0 * D;
+        real g_maxX2 = 2.5 * D;
+        real g_maxX3 = 2.5 * D;
 
         SPtr<LBMUnitConverter> conv(new LBMUnitConverter());
 
@@ -201,9 +198,10 @@ void run(string configname)
         // kernel = SPtr<LBMKernel>(new MultiphaseTwoPhaseFieldsCumulantLBMKernel());
         // kernel = SPtr<LBMKernel>(new MultiphaseTwoPhaseFieldsVelocityCumulantLBMKernel());
         // kernel = SPtr<LBMKernel>(new MultiphaseTwoPhaseFieldsPressureFilterLBMKernel());
-        //kernel = SPtr<LBMKernel>(new MultiphasePressureFilterLBMKernel());
-        //kernel = SPtr<LBMKernel>(new MultiphaseSimpleVelocityBaseExternalPressureLBMKernel());
+        // kernel = SPtr<LBMKernel>(new MultiphasePressureFilterLBMKernel());
+        // kernel = SPtr<LBMKernel>(new MultiphaseSimpleVelocityBaseExternalPressureLBMKernel());
         kernel = make_shared<MultiphaseScaleDistributionLBMKernel>();
+       //kernel = make_shared<MultiphaseSharpInterfaceLBMKernel>();
 
         kernel->setWithForcing(true);
         kernel->setForcingX1(0.0);
@@ -222,7 +220,7 @@ void run(string configname)
         kernel->setMultiphaseModelParameters(beta, kappa);
         kernel->setContactAngle(theta);
         kernel->setInterfaceWidth(interfaceWidth);
-        //dynamicPointerCast<MultiphasePressureFilterLBMKernel>(kernel)->setPhaseFieldBC(0.0);
+        // dynamicPointerCast<MultiphasePressureFilterLBMKernel>(kernel)->setPhaseFieldBC(0.0);
         kernel->setSigma(sigma);
 
         SPtr<BCSet> bcProc(new BCSet());
@@ -236,8 +234,7 @@ void run(string configname)
         // grid->setPeriodicX3(true);
         grid->setGhostLayerWidth(2);
 
-        SPtr<Grid3DVisitor> metisVisitor(new MetisPartitioningGridVisitor(
-            comm, MetisPartitioningGridVisitor::LevelBased, DIR_MMM, MetisPartitioner::RECURSIVE));
+        SPtr<Grid3DVisitor> metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, DIR_MMM, MetisPartitioner::RECURSIVE));
 
         //////////////////////////////////////////////////////////////////////////
         // restart
@@ -270,6 +267,8 @@ void run(string configname)
         mu::Parser fctF2;
         fctF2.SetExpr("vx1");
         fctF2.DefineConst("vx1", U_LB);
+        fctF2.SetExpr("vx1");
+        fctF2.DefineConst("vx1", U_LB);
 
         // real startTime = 1;
         // SPtr<BC> velBCF1(new MultiphaseVelocityBC(true, false, false, fctF1, phiH, 0.0, startTime));
@@ -295,15 +294,17 @@ void run(string configname)
         fctvel_F2_init.DefineConst("U", 0);
 
         velBCF1->setBCStrategy(SPtr<BCStrategy>(new MultiphaseVelocityBCStrategy()));
+        velBCF2->setBCStrategy(SPtr<BCStrategy>(new MultiphaseVelocityBCStrategy()));
         //////////////////////////////////////////////////////////////////////////////////
         // BC visitor
         MultiphaseBoundaryConditionsBlockVisitor bcVisitor;
         bcVisitor.addBC(noSlipBC);
         //bcVisitor.addBC(denBC); // Ohne das BB?
         bcVisitor.addBC(velBCF1);
+        bcVisitor.addBC(velBCF2);
 
-        //SPtr<D3Q27Interactor> inflowF1Int;
-        //SPtr<D3Q27Interactor> cylInt;
+        // SPtr<D3Q27Interactor> inflowF1Int;
+        // SPtr<D3Q27Interactor> cylInt;
 
         SPtr<D3Q27Interactor> inflowInt;
 
@@ -315,25 +316,23 @@ void run(string configname)
 
             // geometry
             SPtr<GbObject3D> gridCube(new GbCuboid3D(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3));
-            if (myid == 0)
-                GbSystem3D::writeGeoObject(gridCube.get(), pathname + "/geo/gridCube",
-                                           WbWriterVtkXmlBinary::getInstance());
-
-            //if (myid == 0)
-            //    UBLOG(logINFO, "Read geoFile:start");
-            //SPtr<GbTriFaceMesh3D> cylinder = make_shared<GbTriFaceMesh3D>();
-            //cylinder->readMeshFromSTLFileBinary(pathGeo + "/" + geoFile, false);
-            //GbSystem3D::writeGeoObject(cylinder.get(), pathname + "/geo/Stlgeo", WbWriterVtkXmlBinary::getInstance());
-            //if (myid == 0)
-            //    UBLOG(logINFO, "Read geoFile:stop");
-            // inflow
-            // GbCuboid3DPtr geoInflowF1(new GbCuboid3D(g_minX1, g_minX2 - 0.5 * dx, g_minX3, g_maxX1, g_minX2 - 1.0 *
-            // dx, g_maxX3));
-            //GbCuboid3DPtr geoInflowF1(new GbCuboid3D(g_minX1 * 0.5 - dx, g_minX2 - dx, g_minX3 * 0.5 - dx,
-            //                                         g_maxX1 * 0.5 + dx, g_minX2, g_maxX3 * 0.5 + dx));
-            //if (myid == 0)
-            //    GbSystem3D::writeGeoObject(geoInflowF1.get(), pathname + "/geo/geoInflowF1",
-            //                               WbWriterVtkXmlASCII::getInstance());
+            if (myid == 0) GbSystem3D::writeGeoObject(gridCube.get(), pathname + "/geo/gridCube", WbWriterVtkXmlBinary::getInstance());
+
+            // if (myid == 0)
+            //     UBLOG(logINFO, "Read geoFile:start");
+            // SPtr<GbTriFaceMesh3D> cylinder = make_shared<GbTriFaceMesh3D>();
+            // cylinder->readMeshFromSTLFileBinary(pathGeo + "/" + geoFile, false);
+            // GbSystem3D::writeGeoObject(cylinder.get(), pathname + "/geo/Stlgeo", WbWriterVtkXmlBinary::getInstance());
+            // if (myid == 0)
+            //     UBLOG(logINFO, "Read geoFile:stop");
+            //  inflow
+            //  GbCuboid3DPtr geoInflowF1(new GbCuboid3D(g_minX1, g_minX2 - 0.5 * dx, g_minX3, g_maxX1, g_minX2 - 1.0 *
+            //  dx, g_maxX3));
+            // GbCuboid3DPtr geoInflowF1(new GbCuboid3D(g_minX1 * 0.5 - dx, g_minX2 - dx, g_minX3 * 0.5 - dx,
+            //                                          g_maxX1 * 0.5 + dx, g_minX2, g_maxX3 * 0.5 + dx));
+            // if (myid == 0)
+            //     GbSystem3D::writeGeoObject(geoInflowF1.get(), pathname + "/geo/geoInflowF1",
+            //                                WbWriterVtkXmlASCII::getInstance());
 
             GbCylinder3DPtr geoInflow(new GbCylinder3D(g_minX1 - 2.0*dx, g_maxX2 / 2.0, g_maxX3 / 2.0, g_minX1, g_maxX2 / 2.0, g_maxX3 / 2.0, D / 2.0));
             if (myid == 0) GbSystem3D::writeGeoObject(geoInflow.get(), pathname + "/geo/geoInflow", WbWriterVtkXmlASCII::getInstance());
@@ -341,7 +340,6 @@ void run(string configname)
             GbCylinder3DPtr geoSolid(new GbCylinder3D(g_minX1 - 2.0 * dx, g_maxX2 / 2.0, g_maxX3 / 2.0, g_minX1-dx, g_maxX2 / 2.0, g_maxX3 / 2.0, 1.5*D / 2.0));
             if (myid == 0) GbSystem3D::writeGeoObject(geoSolid.get(), pathname + "/geo/geoSolid", WbWriterVtkXmlASCII::getInstance());
 
-
             // GbCylinder3DPtr cylinder2(
             //    new GbCylinder3D(0.0, g_minX2 - 2.0 * dx / 2.0, 0.0, 0.0, g_minX2 + 4.0 * dx, 0.0, 8.0+2.0*dx));
             // if (myid == 0)
@@ -350,8 +348,8 @@ void run(string configname)
             // outflow
             // GbCuboid3DPtr geoOutflow(new GbCuboid3D(-1.0, -1, -1.0, 121.0, 1.0, 121.0)); // For JetBreakup (Original)
             // GbCuboid3DPtr geoOutflow(new GbCuboid3D(g_minX1, g_maxX2 - 40 * dx, g_minX3, g_maxX1, g_maxX2, g_maxX3));
-            GbCuboid3DPtr geoOutflow(new GbCuboid3D(g_maxX1, g_minX2 - 2.0*dx, g_minX3 - 2.0*dx, g_maxX1 + 2.0*dx, g_maxX2 + 2.0*dx, g_maxX3));
-            if (myid == 0) GbSystem3D::writeGeoObject(geoOutflow.get(), pathname + "/geo/geoOutflow",                                         WbWriterVtkXmlASCII::getInstance());
+            GbCuboid3DPtr geoOutflow(new GbCuboid3D(g_maxX1, g_minX2 - 2.0 * dx, g_minX3 - 2.0 * dx, g_maxX1 + 2.0 * dx, g_maxX2 + 2.0 * dx, g_maxX3));
+            if (myid == 0) GbSystem3D::writeGeoObject(geoOutflow.get(), pathname + "/geo/geoOutflow", WbWriterVtkXmlASCII::getInstance());
 
             // double blockLength = blocknx[0] * dx;
 
@@ -369,11 +367,10 @@ void run(string configname)
             GenBlocksGridVisitor genBlocks(gridCube);
             grid->accept(genBlocks);
 
-            SPtr<WriteBlocksSimulationObserver> ppblocks(new WriteBlocksSimulationObserver(
-                grid, SPtr<UbScheduler>(new UbScheduler(1)), pathname, WbWriterVtkXmlBinary::getInstance(), comm));
+            SPtr<WriteBlocksSimulationObserver> ppblocks(new WriteBlocksSimulationObserver(grid, SPtr<UbScheduler>(new UbScheduler(1)), pathname, WbWriterVtkXmlBinary::getInstance(), comm));
 
-            //SPtr<Interactor3D> tubes(new D3Q27TriFaceMeshInteractor(cylinder, grid, noSlipBC,
-            //                                                        Interactor3D::SOLID, Interactor3D::POINTS));
+            // SPtr<Interactor3D> tubes(new D3Q27TriFaceMeshInteractor(cylinder, grid, noSlipBC,
+            //                                                         Interactor3D::SOLID, Interactor3D::POINTS));
 
             // inflowF1Int =
             //    SPtr<D3Q27Interactor>(new D3Q27Interactor(cylinder1, grid, noSlipBC, Interactor3D::SOLID));
@@ -402,11 +399,17 @@ void run(string configname)
             SPtr<D3Q27Interactor> wallZmaxInt(new D3Q27Interactor(wallZmax, grid, noSlipBC, Interactor3D::SOLID));
             SPtr<D3Q27Interactor> wallYminInt(new D3Q27Interactor(wallYmin, grid, noSlipBC, Interactor3D::SOLID));
             SPtr<D3Q27Interactor> wallYmaxInt(new D3Q27Interactor(wallYmax, grid, noSlipBC, Interactor3D::SOLID));
+            SPtr<D3Q27Interactor> wallXminInt(new D3Q27Interactor(wallXmin, grid, noSlipBC, Interactor3D::SOLID));
+            SPtr<D3Q27Interactor> wallXmaxInt(new D3Q27Interactor(wallXmax, grid, noSlipBC, Interactor3D::SOLID));
+            SPtr<D3Q27Interactor> wallZminInt(new D3Q27Interactor(wallZmin, grid, noSlipBC, Interactor3D::SOLID));
+            SPtr<D3Q27Interactor> wallZmaxInt(new D3Q27Interactor(wallZmax, grid, noSlipBC, Interactor3D::SOLID));
+            SPtr<D3Q27Interactor> wallYminInt(new D3Q27Interactor(wallYmin, grid, noSlipBC, Interactor3D::SOLID));
+            SPtr<D3Q27Interactor> wallYmaxInt(new D3Q27Interactor(wallYmax, grid, noSlipBC, Interactor3D::SOLID));
 
-            //cylInt = SPtr<D3Q27Interactor>(new D3Q27Interactor(cylinder1, grid, velBCF1, Interactor3D::SOLID));
-            //cylInt->addBC(velBCF2);
-            // SPtr<D3Q27Interactor> cyl2Int(new D3Q27Interactor(cylinder2, grid, noSlipBC,
-            // Interactor3D::SOLID));
+            // cylInt = SPtr<D3Q27Interactor>(new D3Q27Interactor(cylinder1, grid, velBCF1, Interactor3D::SOLID));
+            // cylInt->addBC(velBCF2);
+            //  SPtr<D3Q27Interactor> cyl2Int(new D3Q27Interactor(cylinder2, grid, noSlipBC,
+            //  Interactor3D::SOLID));
 
             inflowInt = SPtr<D3Q27Interactor>(new D3Q27Interactor(geoInflow, grid, velBCF1, Interactor3D::SOLID));
             //inflowInt->addBC(velBCF2);
@@ -425,12 +428,13 @@ void run(string configname)
 
             intHelper.addInteractor(wallXminInt);
             intHelper.addInteractor(wallXmaxInt);
+            intHelper.addInteractor(wallXmaxInt);
             intHelper.addInteractor(wallZminInt);
             intHelper.addInteractor(wallZmaxInt);
             intHelper.addInteractor(wallYminInt);
             intHelper.addInteractor(wallYmaxInt);
-            intHelper.addInteractor(inflowInt);
-            //intHelper.addInteractor(solidInt);
+            //intHelper.addInteractor(inflowInt);
+            intHelper.addInteractor(inflowAirInt);
 
             intHelper.selectBlocks();
 
@@ -439,13 +443,10 @@ void run(string configname)
 
             unsigned long long numberOfBlocks = (unsigned long long)grid->getNumberOfBlocks();
             int ghostLayer = 3;
-            unsigned long long numberOfNodesPerBlock =
-                (unsigned long long)(blocknx[0]) * (unsigned long long)(blocknx[1]) * (unsigned long long)(blocknx[2]);
+            unsigned long long numberOfNodesPerBlock = (unsigned long long)(blocknx[0]) * (unsigned long long)(blocknx[1]) * (unsigned long long)(blocknx[2]);
             unsigned long long numberOfNodes = numberOfBlocks * numberOfNodesPerBlock;
-            unsigned long long numberOfNodesPerBlockWithGhostLayer =
-                numberOfBlocks * (blocknx[0] + ghostLayer) * (blocknx[1] + ghostLayer) * (blocknx[2] + ghostLayer);
-            real needMemAll =
-                real(numberOfNodesPerBlockWithGhostLayer * (27 * sizeof(real) + sizeof(int) + sizeof(float) * 4));
+            unsigned long long numberOfNodesPerBlockWithGhostLayer = numberOfBlocks * (blocknx[0] + ghostLayer) * (blocknx[1] + ghostLayer) * (blocknx[2] + ghostLayer);
+            real needMemAll = real(numberOfNodesPerBlockWithGhostLayer * (27 * sizeof(real) + sizeof(int) + sizeof(float) * 4));
             real needMem = needMemAll / real(comm->getNumberOfProcesses());
 
             if (myid == 0) {
@@ -467,10 +468,10 @@ void run(string configname)
 
             grid->accept(kernelVisitor);
 
-            //if (refineLevel > 0) {
-            //    SetUndefinedNodesBlockVisitor undefNodesVisitor;
-            //    grid->accept(undefNodesVisitor);
-            //}
+            // if (refineLevel > 0) {
+            //     SetUndefinedNodesBlockVisitor undefNodesVisitor;
+            //     grid->accept(undefNodesVisitor);
+            // }
 
             intHelper.setBC();
 
@@ -483,15 +484,28 @@ void run(string configname)
             real x3c = (g_minX3 + g_maxX3)/2;
             
             mu::Parser fct1;
-            fct1.SetExpr("0.5-0.5*tanh(2*(sqrt((x1-x1c)^2+(x2-x2c)^2+(x3-x3c)^2)-radius)/interfaceThickness)");
+            fct1.SetExpr("(0.5-0.5*tanh(2*(sqrt((x1/radius-x1c)^2+(x2-x2c)^2+(x3-x3c)^2)-radius)/interfaceThickness))-(0.5-0.5*tanh(2*(sqrt((x1/radius-x1c)^2+(x2-x2c)^2+(x3-x3c)^2)-radius2)/interfaceThickness))");
+            //fct1.SetExpr("x1 < 4*dx ? (0.5-0.5*tanh(2*(1-4*dx)*(sqrt((x2-x2c)^2+(x3-x3c)^2)-radius)/interfaceThickness)) : 0");
             fct1.DefineConst("x1c", x1c);
             fct1.DefineConst("x2c", x2c);
             fct1.DefineConst("x3c", x3c);
-            fct1.DefineConst("radius", 0.5*D);
-            fct1.DefineConst("interfaceThickness", interfaceWidth*dx);
+            fct1.DefineConst("dx", dx);
+            fct1.DefineConst("radius", 0.5 * D /* + 2. * dx*/);
+            fct1.DefineConst("radius2", D/4.);
+            fct1.DefineConst("interfaceThickness", interfaceWidth * dx);
+
+            mu::Parser fct2;
+            // fct1.SetExpr("0.5-0.5*tanh(2*(sqrt((x1/radius-x1c)^2+(x2-x2c)^2+(x3-x3c)^2)-radius)/interfaceThickness)");
+            fct2.SetExpr("x1 < 4*dx ? (0.5-0.5*tanh(2*(1-4*dx)*(sqrt((x2-x2c)^2+(x3-x3c)^2)-radius)/interfaceThickness)) : 0");
+            fct2.DefineConst("x1c", x1c);
+            fct2.DefineConst("x2c", x2c);
+            fct2.DefineConst("x3c", x3c);
+            fct2.DefineConst("dx", dx);
+            fct2.DefineConst("radius", 0.5 * D /* + 2. * dx*/);
+            fct2.DefineConst("interfaceThickness", interfaceWidth * dx);
 
             MultiphaseVelocityFormInitDistributionsBlockVisitor initVisitor;
-            initVisitor.setPhi(fct1);
+            //initVisitor.setPhi(fct1);
             grid->accept(initVisitor);
             ///////////////////////////////////////////////////////////////////////////////////////////
             //{
@@ -538,22 +552,19 @@ void run(string configname)
             // boundary conditions grid
             {
                 SPtr<UbScheduler> geoSch(new UbScheduler(1));
-                SPtr<WriteBoundaryConditionsSimulationObserver> ppgeo(new WriteBoundaryConditionsSimulationObserver(
-                    grid, geoSch, pathname, WbWriterVtkXmlBinary::getInstance(), comm));
+                SPtr<WriteBoundaryConditionsSimulationObserver> ppgeo(new WriteBoundaryConditionsSimulationObserver(grid, geoSch, pathname, WbWriterVtkXmlBinary::getInstance(), comm));
                 ppgeo->update(0);
                 ppgeo.reset();
             }
 
-            if (myid == 0)
-                UBLOG(logINFO, "Preprocess - end");
+            if (myid == 0) UBLOG(logINFO, "Preprocess - end");
         } else {
             rcp->restart((int)restartStep);
             grid->setTimeStep(restartStep);
 
-            if (myid == 0)
-                UBLOG(logINFO, "Restart - end");
+            if (myid == 0) UBLOG(logINFO, "Restart - end");
         }
-        
+
         //  TwoDistributionsSetConnectorsBlockVisitor setConnsVisitor(comm);
         //  grid->accept(setConnsVisitor);
 
@@ -591,13 +602,12 @@ void run(string configname)
         simulation->addSimulationObserver(npr);
         simulation->addSimulationObserver(pp);
         // simulation->addSimulationObserver(timeDepBC);
+        // simulation->addSimulationObserver(timeDepBC);
         simulation->addSimulationObserver(rcp);
 
-        if (myid == 0)
-            UBLOG(logINFO, "Simulation-start");
+        if (myid == 0) UBLOG(logINFO, "Simulation-start");
         simulation->run();
-        if (myid == 0)
-            UBLOG(logINFO, "Simulation-end");
+        if (myid == 0) UBLOG(logINFO, "Simulation-end");
     } catch (std::exception &e) {
         cerr << e.what() << endl << flush;
     } catch (std::string &s) {
diff --git a/apps/cpu/LaminarTubeFlow/ltf.cpp b/apps/cpu/LaminarTubeFlow/ltf.cpp
index c70c2c19e7a02129ff00f8ca3bd0d7e53894831c..315bee6f263b3d5395499c0ed925c3790d7bfcdf 100644
--- a/apps/cpu/LaminarTubeFlow/ltf.cpp
+++ b/apps/cpu/LaminarTubeFlow/ltf.cpp
@@ -311,7 +311,7 @@ void run(string configname)
       OneDistributionSetConnectorsBlockVisitor setConnsVisitor(comm);
       grid->accept(setConnsVisitor);
 
-      SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
+      SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolator());
       SetInterpolationConnectorsBlockVisitor setInterConnsVisitor(comm, nuLB, iProcessor);
       grid->accept(setInterConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/Multiphase (Droplet Test).cpp.backup b/apps/cpu/Multiphase/Multiphase (Droplet Test).cpp.backup
index 533fb619c2bb82783b99110894079594b5ddba47..b783a354fd39f66ba82383f2387daf92ecbde758 100644
--- a/apps/cpu/Multiphase/Multiphase (Droplet Test).cpp.backup	
+++ b/apps/cpu/Multiphase/Multiphase (Droplet Test).cpp.backup	
@@ -370,8 +370,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -420,8 +420,8 @@ void run(string configname)
          //grid->accept(bcVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/Multiphase (Jet breakup on Phoenix).cpp.backup b/apps/cpu/Multiphase/Multiphase (Jet breakup on Phoenix).cpp.backup
index 954d4b539411adb36ea47724ab612fcd8d70be87..ebf91e6cb54f1a067535ae512f85e706a2d88980 100644
--- a/apps/cpu/Multiphase/Multiphase (Jet breakup on Phoenix).cpp.backup	
+++ b/apps/cpu/Multiphase/Multiphase (Jet breakup on Phoenix).cpp.backup	
@@ -396,8 +396,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -446,8 +446,8 @@ void run(string configname)
          //grid->accept(bcVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/backup/CumulantKernel-Before Cumulant modifications.cpp b/apps/cpu/Multiphase/backup/CumulantKernel-Before Cumulant modifications.cpp
index 860a1f1128fb161ee502bf8e1989748722a7941b..a667643c51186f3494d4e80018c482494ed8af30 100644
--- a/apps/cpu/Multiphase/backup/CumulantKernel-Before Cumulant modifications.cpp	
+++ b/apps/cpu/Multiphase/backup/CumulantKernel-Before Cumulant modifications.cpp	
@@ -1,6 +1,6 @@
 #include "MultiphaseCumulantLBMKernel.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <math.h>
 #include <omp.h>
diff --git a/apps/cpu/Multiphase/backup/Multiphase (Droplet Test).cpp b/apps/cpu/Multiphase/backup/Multiphase (Droplet Test).cpp
index 3362f66d5b07d1b94fd6c2623af58011ae425905..e6efac95353e04e93aae0a9dfcde0422259a2832 100644
--- a/apps/cpu/Multiphase/backup/Multiphase (Droplet Test).cpp	
+++ b/apps/cpu/Multiphase/backup/Multiphase (Droplet Test).cpp	
@@ -370,8 +370,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -420,8 +420,8 @@ void run(string configname)
          //grid->accept(bcVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/backup/Multiphase (Final before automation).cpp b/apps/cpu/Multiphase/backup/Multiphase (Final before automation).cpp
index 5ed66edace35c61fa3244c445fa479db13ccec8f..61d37660015ae6b6134e6d30c83010f75ec362e6 100644
--- a/apps/cpu/Multiphase/backup/Multiphase (Final before automation).cpp	
+++ b/apps/cpu/Multiphase/backup/Multiphase (Final before automation).cpp	
@@ -474,8 +474,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -524,8 +524,8 @@ void run(string configname)
          //grid->accept(bcVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/backup/Multiphase (Flow Focusing).cpp b/apps/cpu/Multiphase/backup/Multiphase (Flow Focusing).cpp
index a6355a2aa56e0bd85d919250e750427df7662284..32548c12b0d559928bf789cd2187cb180213dc65 100644
--- a/apps/cpu/Multiphase/backup/Multiphase (Flow Focusing).cpp	
+++ b/apps/cpu/Multiphase/backup/Multiphase (Flow Focusing).cpp	
@@ -448,8 +448,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -498,8 +498,8 @@ void run(string configname)
          //grid->accept(bcVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/backup/Multiphase (Jet breakup on Phoenix).cpp b/apps/cpu/Multiphase/backup/Multiphase (Jet breakup on Phoenix).cpp
index 954d4b539411adb36ea47724ab612fcd8d70be87..ebf91e6cb54f1a067535ae512f85e706a2d88980 100644
--- a/apps/cpu/Multiphase/backup/Multiphase (Jet breakup on Phoenix).cpp	
+++ b/apps/cpu/Multiphase/backup/Multiphase (Jet breakup on Phoenix).cpp	
@@ -396,8 +396,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -446,8 +446,8 @@ void run(string configname)
          //grid->accept(bcVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/backup/Multiphase (T-Junction).cpp b/apps/cpu/Multiphase/backup/Multiphase (T-Junction).cpp
index 1af6f9a19754035d1e4cc1466d80fa0d77de52c7..93844c4a2f9068debe7759943efb3243da923703 100644
--- a/apps/cpu/Multiphase/backup/Multiphase (T-Junction).cpp	
+++ b/apps/cpu/Multiphase/backup/Multiphase (T-Junction).cpp	
@@ -376,8 +376,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -426,8 +426,8 @@ void run(string configname)
          //grid->accept(bcVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/backup/Multiphase (Thermal).cpp b/apps/cpu/Multiphase/backup/Multiphase (Thermal).cpp
index 51ba4463a32740f8b2e07391d1ab174ccb9e7095..68e07b43c2cfff23affee121f9d8b39997d0fd8d 100644
--- a/apps/cpu/Multiphase/backup/Multiphase (Thermal).cpp	
+++ b/apps/cpu/Multiphase/backup/Multiphase (Thermal).cpp	
@@ -417,8 +417,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -467,8 +467,8 @@ void run(string configname)
          //grid->accept(bcVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/backup/Multiphase (Tube).cpp b/apps/cpu/Multiphase/backup/Multiphase (Tube).cpp
index 7e6dfd24a1ba90420891de57a7ba399d5c860e7d..492a906b816129de271189ab8d35fe1a4d180b56 100644
--- a/apps/cpu/Multiphase/backup/Multiphase (Tube).cpp	
+++ b/apps/cpu/Multiphase/backup/Multiphase (Tube).cpp	
@@ -305,8 +305,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -352,8 +352,8 @@ void run(string configname)
          //grid->accept(bcVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/backup/Multiphase.cpp b/apps/cpu/Multiphase/backup/Multiphase.cpp
index 8b09c15f4f5eb829ca37fce160bbb86ebb92f19d..b029e35277729803df53fb0d79d025863e21719b 100644
--- a/apps/cpu/Multiphase/backup/Multiphase.cpp
+++ b/apps/cpu/Multiphase/backup/Multiphase.cpp
@@ -643,8 +643,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          //ConnectorFactoryPtr factory(new Block3DConnectorFactory());
          //ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, factory);
@@ -693,8 +693,8 @@ void run(string configname)
          //grid->accept(bcVisitor);
 
          //set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/Multiphase/backup/MultiphaseCumulantLBMKernel (New VBased).cpp b/apps/cpu/Multiphase/backup/MultiphaseCumulantLBMKernel (New VBased).cpp
index 1cdf5905cbac12297fc3ab9c759cda726673c508..a0bfe97ba310a8858225b5c344f425121ddd2585 100644
--- a/apps/cpu/Multiphase/backup/MultiphaseCumulantLBMKernel (New VBased).cpp	
+++ b/apps/cpu/Multiphase/backup/MultiphaseCumulantLBMKernel (New VBased).cpp	
@@ -1,6 +1,6 @@
 #include "MultiphaseCumulantLBMKernel.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <math.h>
 #include <omp.h>
diff --git a/apps/cpu/Multiphase/backup/MultiphaseCumulantLBMKernel (Original Final).cpp b/apps/cpu/Multiphase/backup/MultiphaseCumulantLBMKernel (Original Final).cpp
index 498d91ff8fb8e0a7ae19000225d82a2d7e757387..c0dcd4d0cf26a41da3ff36195d7d6efeabfe016d 100644
--- a/apps/cpu/Multiphase/backup/MultiphaseCumulantLBMKernel (Original Final).cpp	
+++ b/apps/cpu/Multiphase/backup/MultiphaseCumulantLBMKernel (Original Final).cpp	
@@ -1,6 +1,6 @@
 #include "MultiphaseCumulantLBMKernel.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <math.h>
 #include <omp.h>
diff --git a/apps/cpu/MultiphaseDropletTest/CMakeLists.txt b/apps/cpu/MultiphaseDropletTest/CMakeLists.txt
index b70fdf8fb1e93807e7812988374b28a4f9a969b4..c48e517aaad9ff75f6245101ae0a433a2bd49886 100644
--- a/apps/cpu/MultiphaseDropletTest/CMakeLists.txt
+++ b/apps/cpu/MultiphaseDropletTest/CMakeLists.txt
@@ -1,3 +1,3 @@
 PROJECT(MultiphaseDropletTest)
 
-vf_add_library(BUILDTYPE binary PRIVATE_LINK VirtualFluidsCore basics ${MPI_CXX_LIBRARIES} MultiphaseFlow FILES droplet.cpp )
+vf_add_library(BUILDTYPE binary PRIVATE_LINK VirtualFluidsCore basics ${MPI_CXX_LIBRARIES} MultiphaseFlow NonNewtonianFluids  FILES droplet.cpp )
diff --git a/apps/cpu/MultiphaseDropletTest/droplet.cpp b/apps/cpu/MultiphaseDropletTest/droplet.cpp
index eaa3e550f873113bf2ffdeba4ed8a962ccae5046..32b6f8cfb904226029f6acf27e7c84d9a5c5deaa 100644
--- a/apps/cpu/MultiphaseDropletTest/droplet.cpp
+++ b/apps/cpu/MultiphaseDropletTest/droplet.cpp
@@ -9,6 +9,7 @@
 
 #include "VirtualFluids.h"
 #include "MultiphaseFlow/MultiphaseFlow.h"
+#include "NonNewtonianFluids/NonNewtonianFluids.h"
 
 using namespace std;
 
@@ -141,12 +142,19 @@ void run(string configname)
 
         //const int baseLevel = 0;
 
+        
+        SPtr<Rheology> thix = Rheology::getInstance();
+        thix->setYieldStress(0);
+
         SPtr<LBMKernel> kernel;
 
         //kernel = SPtr<LBMKernel>(new MultiphaseScratchCumulantLBMKernel());
        // kernel = SPtr<LBMKernel>(new MultiphaseCumulantLBMKernel());
         //kernel = SPtr<LBMKernel>(new MultiphaseTwoPhaseFieldsPressureFilterLBMKernel());
-        kernel = SPtr<LBMKernel>(new MultiphasePressureFilterLBMKernel());
+        //kernel = SPtr<LBMKernel>(new MultiphasePressureFilterLBMKernel());
+        //kernel = make_shared< MultiphaseScaleDistributionLBMKernel>();
+        //kernel = SPtr<LBMKernel>(new MultiphaseSharpInterfaceLBMKernel());
+        kernel = make_shared<MultiphaseSharpInterfaceLBMKernel>();
 
         mu::Parser fgr;
         fgr.SetExpr("-(rho-rho_l)*g_y");
@@ -287,12 +295,14 @@ void run(string configname)
             intHelper.setBC();
 
             // initialization of distributions
-            real x1c = 2.5 * D; // (g_maxX1 - g_minX1-1)/2; //
+            real x1c = 1.5;//
+            //2.5 * D;             // (g_maxX1 - g_minX1-1)/2; //
             real x2c = 12.5 * D; //(g_maxX2 - g_minX2-1)/2;
-            real x3c = 1.5; //2.5 * D; //(g_maxX3 - g_minX3-1)/2;
+            real x3c = 2.5 * D;
+            //1.5; // 2.5 * D; //(g_maxX3 - g_minX3-1)/2;
             //LBMReal x3c = 2.5 * D;
             mu::Parser fct1;
-            fct1.SetExpr("0.5-0.5*tanh(2*(sqrt((x1-x1c)^2+(x2-x2c)^2+(x3-x3c)^2)-radius)/interfaceThickness)");
+            fct1.SetExpr("0.5+0.5*tanh(2*(sqrt(0*(x1-x1c)^2+(x2-x2c)^2+(x3-x3c)^2)-radius)/interfaceThickness)");
             fct1.DefineConst("x1c", x1c);
             fct1.DefineConst("x2c", x2c);
             fct1.DefineConst("x3c", x3c);
@@ -300,7 +310,7 @@ void run(string configname)
             fct1.DefineConst("interfaceThickness", interfaceThickness);
 
             mu::Parser fct2;
-            fct2.SetExpr("0.5*uLB-uLB*0.5*tanh(2*(sqrt((x1-x1c)^2+(x2-x2c)^2+(x3-x3c)^2)-radius)/interfaceThickness)");
+            fct2.SetExpr("0.5*uLB-uLB*0.5*tanh(2*(sqrt(0*(x1-x1c)^2+(x2-x2c)^2+(x3-x3c)^2)-radius)/interfaceThickness)");
             //fct2.SetExpr("uLB");
             fct2.DefineConst("uLB", uLB);
             fct2.DefineConst("x1c", x1c);
@@ -381,7 +391,7 @@ void run(string configname)
         t = (int)(t_ast/std::sqrt(g_y/D));         
         visSch->addSchedule(t,t,t); //t=9
 
-        SPtr<WriteMultiphaseQuantitiesSimulationObserver> pp(new WriteMultiphaseQuantitiesSimulationObserver(
+        SPtr<WriteSharpInterfaceQuantitiesSimulationObserver> pp(new WriteSharpInterfaceQuantitiesSimulationObserver(
             grid, visSch, pathname, WbWriterVtkXmlBinary::getInstance(), conv, comm));
         if(grid->getTimeStep() == 0) 
             pp->update(0);
diff --git a/apps/cpu/Nozzle/CMakeLists.txt b/apps/cpu/Nozzle/CMakeLists.txt
index f9e90c7e95115d4b4dfc436721a192100ad95e98..9764934d46b39abca2ceda133e3434a78980f294 100644
--- a/apps/cpu/Nozzle/CMakeLists.txt
+++ b/apps/cpu/Nozzle/CMakeLists.txt
@@ -1,3 +1,3 @@
 PROJECT(Nozzle)
 
-vf_add_library(BUILDTYPE binary PRIVATE_LINK VirtualFluidsCore basics ${MPI_CXX_LIBRARIES} LiggghtsCoupling MultiphaseFlow NonNewtonianFluids FILES nozzle.cpp )
+vf_add_library(BUILDTYPE binary PRIVATE_LINK VirtualFluidsCore basics ${MPI_CXX_LIBRARIES} LiggghtsCoupling MultiphaseFlow NonNewtonianFluids FILES nozzleSinglePhase.cpp )
diff --git a/apps/cpu/Nozzle/nozzle.cpp b/apps/cpu/Nozzle/nozzle.cpp.1
similarity index 91%
rename from apps/cpu/Nozzle/nozzle.cpp
rename to apps/cpu/Nozzle/nozzle.cpp.1
index babee1900c0bd9bb10bca3bccd790e83d25d14b8..0feddc57b709be57c05000da0ef8075b6941b8c0 100644
--- a/apps/cpu/Nozzle/nozzle.cpp
+++ b/apps/cpu/Nozzle/nozzle.cpp.1
@@ -14,7 +14,7 @@ using namespace std;
 
 int main(int argc, char *argv[])
 {
-    // Sleep(30000);
+    //Sleep(30000);
 
     try {
 
@@ -42,11 +42,11 @@ int main(int argc, char *argv[])
 
         double g_minX1 = -1.31431;
         double g_minX2 = 0.375582;
-        double g_minX3 = 0.1; //-210e-3 - 0.2 - 6e-3; //- 1e-3;
+        double g_minX3 = -0.21; //-210e-3 - 0.2 - 6e-3; //- 1e-3;
 
         double g_maxX1 = -1.28831;
         double g_maxX2 = 0.401582;
-        double g_maxX3 = 0.206;
+        double g_maxX3 = 0.175;//0.21;
 
         int blockNX[3] = { 26, 26, 35 };
 
@@ -126,8 +126,8 @@ int main(int argc, char *argv[])
         if (myid == 0) VF_LOG_INFO("Yield stress = {} Pa", tau0);
         if (myid == 0) VF_LOG_INFO("Yield stress LB = {} ", tau0_LB);
 
-        // SPtr<BC> noSlipBC(new NoSlipBC());
-        // noSlipBC->setBCStrategy(SPtr<BCStrategy>(new NoSlipBCStrategy()));
+        //SPtr<BC> noSlipBC(new NoSlipBC());
+        //noSlipBC->setBCStrategy(SPtr<BCStrategy>(new NoSlipBCStrategy()));
         SPtr<BC> noSlipBC(new NoSlipBC());
         noSlipBC->setBCStrategy(SPtr<BCStrategy>(new MultiphaseNoSlipBCStrategy()));
 
@@ -161,8 +161,8 @@ int main(int argc, char *argv[])
         //    fct.DefineConst("U", uLB_ref * ((N + 3) / (N + 1)));
         //    fct.DefineConst("NplusOne", N + 1.0);
 
-        // SPtr<BC> inflowConcreteBC(new VelocityBC(false, false, true, fct, 0, BCFunction::INFCONST));
-        // inflowConcreteBC->setBCStrategy(SPtr<BCStrategy>(new VelocityBCStrategy()));
+        //SPtr<BC> inflowConcreteBC(new VelocityBC(false, false, true, fct, 0, BCFunction::INFCONST));
+        //inflowConcreteBC->setBCStrategy(SPtr<BCStrategy>(new VelocityBCStrategy()));
         SPtr<BC> inflowConcreteBC(new MultiphaseVelocityBC(false, false, true, fct, phiH, 0, BCFunction::INFCONST));
         inflowConcreteBC->setBCStrategy(SPtr<BCStrategy>(new MultiphaseVelocityBCStrategy()));
 
@@ -444,13 +444,15 @@ int main(int argc, char *argv[])
         bcVisitor.addBC(noSlipBC);
         bcVisitor.addBC(inflowConcreteBC);
         bcVisitor.addBC(inflowAirBC1);
-        //bcVisitor.addBC(outflowBC);
+        bcVisitor.addBC(outflowBC);
 
         // SPtr<LBMKernel> kernel   = make_shared<IBcumulantK17LBMKernel>();
         // SPtr<LBMKernel> kernel   = make_shared<CumulantK17LBMKernel>();
         // SPtr<LBMKernel> kernel = make_shared<MultiphaseTwoPhaseFieldsPressureFilterLBMKernel>();
         // SPtr<LBMKernel> kernel = make_shared<MultiphaseSimpleVelocityBaseExternalPressureLBMKernel>();
-        SPtr<LBMKernel> kernel = make_shared<MultiphaseSharpInterfaceLBMKernel>();
+        //SPtr<LBMKernel> kernel = make_shared<MultiphaseSharpInterfaceLBMKernel>();
+        //SPtr<LBMKernel> kernel = make_shared<IBcumulantK17LBMKernel>();
+        SPtr<LBMKernel> kernel = make_shared<IBsharpInterfaceLBMKernel>();
 
         kernel->setWithForcing(false);
         kernel->setForcingX1(0.0);
@@ -482,7 +484,7 @@ int main(int argc, char *argv[])
 
         string geoPath = "d:/Projects/TRR277/Project/WP4/NozzleGeo";
 
-        string outputPath = "f:/temp/NozzleFlowTest_SharpInterface_OutflowPress";
+        string outputPath = "d:/temp/NozzleFlowTest_SharpInterface_With_Part_fraction_0.23";
         UbSystem::makeDirectory(outputPath);
         UbSystem::makeDirectory(outputPath + "/liggghts");
 
@@ -492,6 +494,44 @@ int main(int argc, char *argv[])
         //     UbLog::output_policy::setStream(logFilename.str());
         // }
 
+        /////////////////////////////////////////////////////////////////////
+        //LIGGGHTS things
+        /////////////////////////////////////////////////////////////////////
+        string inFile1 = "d:/Projects/TRR277/Project/WP4/Config/in.nozzle";
+        // string inFile2 = "d:/Projects/VirtualFluids_LIGGGHTS_coupling/apps/cpu/LiggghtsApp/in2.lbdem";
+        MPI_Comm mpi_comm = *(MPI_Comm *)(comm->getNativeCommunicator());
+        LiggghtsCouplingWrapper wrapper(argv, mpi_comm);
+
+        double v_frac = 0.1;
+        double dt_phys = units->getFactorTimeLbToW();
+        int demSubsteps = 10;
+        double dt_dem = dt_phys / (double)demSubsteps;
+        int vtkSteps = 1000;
+        string demOutDir = outputPath + "/liggghts";
+
+        // wrapper.execCommand("echo none");
+
+        // wrapper.execFile((char*)inFile1.c_str());
+
+        //// set timestep and output directory
+        wrapper.setVariable("t_step", dt_dem);
+        wrapper.setVariable("dmp_stp", vtkSteps * demSubsteps);
+        wrapper.setVariable("dmp_dir", demOutDir);
+
+        wrapper.execFile((char *)inFile1.c_str());
+        //wrapper.runUpto(demSubsteps - 1);
+        // wrapper.runUpto(1000);
+
+        //LatticeDecomposition lDec((g_maxX1 - g_minX1) / dx, (g_maxX2 - g_minX2) / dx, (g_maxX3 - g_minX3) / dx, wrapper.lmp, grid);
+
+        SPtr<UbScheduler> lScheduler = make_shared<UbScheduler>(1);
+        SPtr<LiggghtsCouplingSimulationObserver> lcSimulationObserver = make_shared<LiggghtsCouplingSimulationObserver>(grid, lScheduler, comm, wrapper, demSubsteps, unitsAir);
+        //SPtr<Grid3DVisitor> partVisitor = make_shared<LiggghtsPartitioningGridVisitor>(std::ceil((g_maxX1 - g_minX1) / dx), std::ceil((g_maxX2 - g_minX2) / dx), std::ceil((g_maxX3 - g_minX3) / dx), wrapper.lmp);
+        SPtr<Grid3DVisitor> partVisitor = make_shared<LiggghtsPartitioningGridVisitor>(26,26,420, wrapper.lmp);
+        
+        /////////////////////////////////////////////////////////////////////
+        /////////////////////////////////////////////////////////////////////
+        
         SPtr<Grid3DVisitor> metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, vf::lbm::dir::DIR_MMM, MetisPartitioner::RECURSIVE));
 
         SPtr<GbObject3D> gridCube = make_shared<GbCuboid3D>(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3);
@@ -557,7 +597,8 @@ int main(int argc, char *argv[])
         SPtr<D3Q27Interactor> intrBox = SPtr<D3Q27Interactor>(new D3Q27Interactor(gridCube, grid, noSlipBC, Interactor3D::INVERSESOLID));
         ///////////////////////////////////////////////////////////
         // inflow
-        GbCylinder3DPtr geoInflow(new GbCylinder3D(-1.30181 + 0.0005, 0.390872 - 0.00229, 0.20105, -1.30181 + 0.0005, 0.390872 - 0.00229, 0.23, 0.013));
+        //GbCylinder3DPtr geoInflow(new GbCylinder3D(-1.30181 + 0.0005, 0.390872 - 0.00229, 0.20105, -1.30181 + 0.0005, 0.390872 - 0.00229, 0.23, 0.013));
+        GbCylinder3DPtr geoInflow(new GbCylinder3D(-1.30181 + 0.0005, 0.390872 - 0.00229, 0.175, -1.30181 + 0.0005, 0.390872 - 0.00229, 0.21, 0.013));
         if (myid == 0) GbSystem3D::writeGeoObject(geoInflow.get(), outputPath + "/geo/geoInflow", WbWriterVtkXmlBinary::getInstance());
         SPtr<D3Q27Interactor> intrInflow = SPtr<D3Q27Interactor>(new D3Q27Interactor(geoInflow, grid, inflowConcreteBC, Interactor3D::SOLID));
         ///////////////////////////////////////////////////////////
@@ -628,7 +669,7 @@ int main(int argc, char *argv[])
         SPtr<Interactor3D> intAirInlet6 = std::make_shared<D3Q27TriFaceMeshInteractor>(meshAirInlet6, grid, inflowAirBC6, Interactor3D::SOLID, Interactor3D::POINTS);
         ///////////////////////////////////////////////////////////
 
-        InteractorsHelper intHelper(grid, metisVisitor, true);
+        InteractorsHelper intHelper(grid, partVisitor, false);
 
         intHelper.addInteractor(intrFluidArea);
         intHelper.addInteractor(intrNozzleVolcanNozzle2);
@@ -658,10 +699,11 @@ int main(int argc, char *argv[])
 
         // if (myid == 0) UBLOG(logINFO, Utilities::toString(grid, comm->getNumberOfProcesses()));
 
-        // SetKernelBlockVisitor kernelVisitor(kernel, nuLB, comm->getNumberOfProcesses());
+        //SetKernelBlockVisitor kernelVisitor(kernel, nu_l_LB, comm->getNumberOfProcesses());
         MultiphaseSetKernelBlockVisitor kernelVisitor(kernel, nu_h_LB, nu_l_LB, 1e9, 1);
         grid->accept(kernelVisitor);
 
+
         intHelper.setBC();
 
         // InitDistributionsBlockVisitor initVisitor;
@@ -669,9 +711,10 @@ int main(int argc, char *argv[])
 
         double x1c = -1.31431 + R;
         double x2c = 0.375582 + R;
-        double x3c = 0.20105;
+        double Ri = 5;
+        double x3c = 0.136 + Ri;
 
-        R = 0.2 - 0.145; // 0.078-0.04; // 0.2;
+        //R = 0.2 - 0.145; // 0.078-0.04; // 0.2;
 
         mu::Parser fct1;
         // fct1.SetExpr(" 0.5 - 0.5 * tanh(2 * (sqrt((x1 - x1c) ^ 2 + (x2 - x2c) ^ 2 + (x3 - x3c) ^ 2) - radius) / interfaceThickness)");
@@ -679,40 +722,15 @@ int main(int argc, char *argv[])
         fct1.DefineConst("x1c", x1c);
         fct1.DefineConst("x2c", x2c);
         fct1.DefineConst("x3c", x3c);
-        fct1.DefineConst("radius", R);
+        fct1.DefineConst("radius", Ri);
         fct1.DefineConst("interfaceThickness", interfaceThickness * dx);
 
         MultiphaseVelocityFormInitDistributionsBlockVisitor initVisitor;
         initVisitor.setPhi(fct1);
         grid->accept(initVisitor);
 
-        string inFile1 = "d:/Projects/VirtualFluids_Develop/apps/cpu/Nozzle/in.nozzle";
-        //string inFile2 = "d:/Projects/VirtualFluids_LIGGGHTS_coupling/apps/cpu/LiggghtsApp/in2.lbdem";
-        MPI_Comm mpi_comm = *(MPI_Comm*)(comm->getNativeCommunicator());
-        LiggghtsCouplingWrapper wrapper(argv, mpi_comm);
-
-        double v_frac = 0.1;
-        double dt_phys   = units->getFactorTimeLbToW();
-        int demSubsteps = 10;
-        double dt_dem   = dt_phys / (double)demSubsteps;
-        int vtkSteps = 100;
-        string demOutDir = outputPath + "/liggghts";
-
-        //wrapper.execCommand("echo none");
-
-        //wrapper.execFile((char*)inFile1.c_str());
-
-        //// set timestep and output directory
-        wrapper.setVariable("t_step", dt_dem);
-        wrapper.setVariable("dmp_stp", vtkSteps * demSubsteps);
-        wrapper.setVariable("dmp_dir", demOutDir);
-
-        //wrapper.execFile((char *)inFile1.c_str());
-        //wrapper.runUpto(demSubsteps - 1);
-        //wrapper.runUpto(1000);
-
-        SPtr<UbScheduler> lScheduler = make_shared<UbScheduler>(1);
-        SPtr<LiggghtsCouplingSimulationObserver> lcSimulationObserver = make_shared<LiggghtsCouplingSimulationObserver>(grid, lScheduler, comm, wrapper, demSubsteps, units);
+        //InitDistributionsBlockVisitor initVisitor;
+        //grid->accept(initVisitor);
 
         // boundary conditions grid
         {
@@ -724,12 +742,12 @@ int main(int argc, char *argv[])
 
         grid->accept(bcVisitor);
 
-        // OneDistributionSetConnectorsBlockVisitor setConnsVisitor(comm);
+        //OneDistributionSetConnectorsBlockVisitor setConnsVisitor(comm);
         TwoDistributionsDoubleGhostLayerSetConnectorsBlockVisitor setConnsVisitor(comm);
         // ThreeDistributionsDoubleGhostLayerSetConnectorsBlockVisitor setConnsVisitor(comm);
         grid->accept(setConnsVisitor);
 
-        int numOfThreads = 18;
+        int numOfThreads = 1;
         omp_set_num_threads(numOfThreads);
 
         SPtr<UbScheduler> nupsSch = std::make_shared<UbScheduler>(10, 10, 100);
@@ -739,12 +757,16 @@ int main(int argc, char *argv[])
         SPtr<UbScheduler> visSch(new UbScheduler(vtkSteps));
         // SPtr<UbScheduler> visSch(new UbScheduler(1, 8700, 8800));
         // visSch->addSchedule(1, 8700, 8800);
-        SPtr<WriteSharpInterfaceQuantitiesSimulationObserver> writeMQSimulationObserver(new WriteSharpInterfaceQuantitiesSimulationObserver(grid, visSch, outputPath, WbWriterVtkXmlASCII::getInstance(), SPtr<LBMUnitConverter>(new LBMUnitConverter()), comm));
+        SPtr<WriteSharpInterfaceQuantitiesSimulationObserver> writeMQSimulationObserver(new WriteSharpInterfaceQuantitiesSimulationObserver(grid, visSch, outputPath, WbWriterVtkXmlBinary::getInstance(), SPtr<LBMUnitConverter>(new LBMUnitConverter()), comm));
+        //writeMQSimulationObserver->update(0);
+
+        //SPtr<WriteMacroscopicQuantitiesSimulationObserver> writeMQSimulationObserver(new WriteMacroscopicQuantitiesSimulationObserver(grid, visSch, outputPath, WbWriterVtkXmlBinary::getInstance(), SPtr<LBMUnitConverter>(new LBMUnitConverter()), comm));
+        //writeMQSimulationObserver->update(0);
 
         int endTime = 10000000;
         SPtr<Simulation> simulation(new Simulation(grid, lScheduler, endTime));
         simulation->addSimulationObserver(nupsSimulationObserver);
-        // Simulation->addSimulationObserver(lcSimulationObserver);
+        simulation->addSimulationObserver(lcSimulationObserver);
         simulation->addSimulationObserver(writeMQSimulationObserver);
 
         if (myid == 0) UBLOG(logINFO, "Simulation-start");
diff --git a/apps/cpu/Nozzle/nozzleSinglePhase.cpp b/apps/cpu/Nozzle/nozzleSinglePhase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed89cb57374e543630134296ae4ba24d02481db5
--- /dev/null
+++ b/apps/cpu/Nozzle/nozzleSinglePhase.cpp
@@ -0,0 +1,798 @@
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include "VirtualFluids.h"
+
+#include "LiggghtsCoupling/LiggghtsCoupling.h"
+
+#include "MultiphaseFlow/MultiphaseFlow.h"
+
+#include "NonNewtonianFluids/NonNewtonianFluids.h"
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+    //Sleep(30000);
+
+    try {
+
+        std::shared_ptr<vf::mpi::Communicator> comm = vf::mpi::MPICommunicator::getInstance();
+        int myid = comm->getProcessID();
+
+        // bounding box
+        // double g_minX1 = -1341.81e-3;
+        // double g_minX2 =  348.087e-3;
+        // double g_minX3 = -210e-3;
+
+        // double g_maxX1 = -1260.81e-3;
+        // double g_maxX2 =  429.087e-3;
+        // double g_maxX3 =  214.5e-3;
+
+        // double g_minX1 = -1341.81e-3 + 10e-3;
+        // double g_minX2 =  0.360872;
+        // double g_minX3 = -210e-3;
+
+        // double g_maxX1 = -1260.81e-3 - 10e-3;
+        // double g_maxX2 =  0.416302;
+        // double g_maxX3 = 210e-3;
+
+        // int blockNX[3] = { 10, 10, 10 };
+
+        double g_minX1 = -1.31431;
+        double g_minX2 = 0.375582;
+        double g_minX3 = -0.21; //-210e-3 - 0.2 - 6e-3; //- 1e-3;
+
+        double g_maxX1 = -1.28831;
+        double g_maxX2 = 0.401582;
+        double g_maxX3 = 0.175;//0.21;
+
+        int blockNX[3] = { 26, 26, 35 };
+
+        double dx = 1e-3;
+
+        double uLB_ref = 0.0001;
+        // double rhoLB = 0.0;
+
+        // concrete
+        double d_part = 1e-3;
+        double V = 0.4*10.; // flow rate [m^3/h]
+        double D = 0.026;     // shotcrete inlet diameter [m]
+        double R = D / 2.0;   // radius [m]
+        double A = UbMath::PI * R * R;
+        double u = V / 3600 / A;
+        double muConcrete = 2.1133054011798826; // [Pa s]
+        double rhoAir = 1.2041;                 // [kg/m^3]
+        double tau0 = 715.218181094648;         // Pa
+        double rhoConcrete = 2400;              // [kg/m^3]
+        double nu = muConcrete / rhoConcrete;
+
+        // double Re_D = d_part * u / nu;
+        // if (myid == 0) UBLOG(logINFO, "Re_D = " << Re_D);
+        //
+        SPtr<LBMUnitConverter> units = std::make_shared<LBMUnitConverter>(d_part, 1., 2400, d_part / dx, uLB_ref);
+        if (myid == 0) std::cout << units->toString() << std::endl;
+
+        double interfaceThickness = 3; // 4.096;
+        double sigma = 0.3; //0.03;
+        double Re = rhoConcrete * u * d_part / muConcrete;
+        double We = rhoConcrete * u * u * d_part / sigma;
+
+        double u_LB_con = u * units->getFactorVelocityWToLb();
+        double nu_h_LB = nu * units->getFactorViscosityWToLb(); // uLB_ref * d_part * units->getFactorLentghWToLb() / Re;
+        double nu_l_LB = 0;                                     // = nu_h_LB;
+
+        double rho_h_LB = 1;
+
+        // surface tension
+        double sigma_LB = rho_h_LB *u_LB_con *u_LB_con *d_part * units->getFactorLentghWToLb() / We;
+
+        // LBMReal dLB = 0; // = length[1] / dx;
+        LBMReal rhoLB = 0.0;
+        // LBMReal nuLB = nu_l; //(uLB_ref*dLB) / Re;
+
+        double beta = 12.0 * sigma_LB / interfaceThickness;
+        double kappa = 1.5 * interfaceThickness * sigma_LB;
+
+        double phiL = 0.0;
+        double phiH = 1.0;
+        double tauH = 0.6; // Phase - field Relaxation
+        double mob = 0.02; // Mobility
+        // double nuL = 1e-2;
+        // double nuG = 0.015811388300841892;
+        double densityRatio = rhoConcrete / rhoAir;
+        // double sigma_old = 1.0850694444444444e-06;
+        //
+        // double beta_old = 12.0 * sigma / interfaceThickness;
+        // double kappa_old = 1.5 * interfaceThickness * sigma;
+
+        double theta = 110; // contact angle
+
+        // https://civilsir.com/density-of-cement-sand-and-aggregate-in-kg-m3-list-of-material-density/
+
+        // SPtr<LBMUnitConverter> units = std::make_shared<LBMUnitConverter>(r_p, 1.480, 2060, r_p/dx);
+        // SPtr<LBMUnitConverter> units = std::make_shared<LBMUnitConverter>(r_p, LBMUnitConverter::AIR_20C, r_p / dx);
+        // SPtr<LBMUnitConverter> units = std::make_shared<LBMUnitConverter>(d_part, 1., 1000, d_part / dx, std::abs(uLB_ref));
+        // SPtr<LBMUnitConverter> units = std::make_shared<LBMUnitConverter>(d_part, 1., 1000, d_part / dx, std::abs(uLB_ref));
+        // SPtr<LBMUnitConverter> units = std::make_shared<LBMUnitConverter>(d_part, 1., 2400, d_part / dx, uRef);
+
+        double Bm = (tau0 * d_part) / (muConcrete * u);
+        double tau0_LB = Bm * nu_h_LB * u_LB_con / (d_part * units->getFactorLentghWToLb());
+
+        SPtr<Rheology> thix = Rheology::getInstance();
+        thix->setYieldStress(tau0_LB);
+
+        if (myid == 0) VF_LOG_INFO("Yield stress = {} Pa", tau0);
+        if (myid == 0) VF_LOG_INFO("Yield stress LB = {} ", tau0_LB);
+
+        SPtr<BC> noSlipBC(new NoSlipBC());
+        noSlipBC->setBCStrategy(SPtr<BCStrategy>(new NoSlipBCStrategy()));
+        //SPtr<BC> noSlipBC(new NoSlipBC());
+        //noSlipBC->setBCStrategy(SPtr<BCStrategy>(new MultiphaseNoSlipBCStrategy()));
+
+        // concrete inflow boundary condition
+        mu::Parser fct;
+        fct.SetExpr("U");
+        fct.DefineConst("U", -u_LB_con);
+        if (myid == 0) VF_LOG_INFO("Concrete inflow velocity = {} m/s", u);
+        if (myid == 0) VF_LOG_INFO("Concrete inflow velocity = {} dx/dt", u_LB_con);
+        if (myid == 0) VF_LOG_INFO("Concrete Re = {}", Re);
+
+        //    // Ã… tigler, J. (2014). Analytical velocity profile in tube for laminar and turbulent flow. Engineering
+        //    // Mechanics, 21(6), 371-379.
+        //    double cx1 = -1.31431 + R;
+        //    double cx2 = 0.375582 + R;
+        //    //double cx3 = 0.20105 + R;
+        //    double L = g_maxX1 - g_minX1;
+        //    double p_concrete = 1e5; // Pa = 1 Bar
+        //    double p1 = p_concrete * units->getFactorPressureWToLb();
+        //    double p2 = 0.0;
+        //    double drhoLB = 1.0 + rhoLB;
+        //    double muLB = drhoLB * nuLB;
+        //    double N = R * R / 2 * muLB * uLB_ref * (p1 - p2) / L - 3;
+
+        //    // mu::Parser fct;
+        //    fct.SetExpr("U*(1-(((((x2-y0)^2+(x1-x0)^2)^0.5)/R)^NplusOne))");
+        //    fct.DefineConst("x0", cx1);
+        //    fct.DefineConst("y0", cx2);
+        //    //fct.DefineConst("z0", cx3);
+        //    fct.DefineConst("R", R);
+        //    fct.DefineConst("U", uLB_ref * ((N + 3) / (N + 1)));
+        //    fct.DefineConst("NplusOne", N + 1.0);
+
+        SPtr<BC> inflowConcreteBC(new VelocityBC(false, false, true, fct, 0, BCFunction::INFCONST));
+        inflowConcreteBC->setBCStrategy(SPtr<BCStrategy>(new VelocityBCStrategy()));
+        //SPtr<BC> inflowConcreteBC(new MultiphaseVelocityBC(false, false, true, fct, phiH, 0, BCFunction::INFCONST));
+        //inflowConcreteBC->setBCStrategy(SPtr<BCStrategy>(new MultiphaseVelocityBCStrategy()));
+
+        // air inflow boundary condition
+        //  Ã… tigler, J. (2014). Analytical velocity profile in tube for laminar and turbulent flow. Engineering
+        //  Mechanics, 21(6), 371-379.
+        // SPtr<LBMUnitConverter> unitsAir = std::make_shared<LBMUnitConverter>(d_part, LBMUnitConverter::AIR_20C, d_part / dx);
+        // SPtr<LBMUnitConverter> unitsAir = std::make_shared<LBMUnitConverter>(d_part, 1., 1.2041, d_part / dx, uLB_ref);
+        // double V = 40;      // flow rate [m^3/h]
+        // double D = 0.0166;  // air inlet diameter [m]
+        // double R = D / 2.0; // radius [m]
+        // double A = UbMath::PI * R * R;
+        // double u = V / 3600 / A;
+        // double uLB_ref = u * unitsAir->getFactorVelocityWToLb();
+        //// double cx1 = -1.2788 + R;
+        // double cx2 = 0.3803 + R;
+        // double cx3 = 0.1517 + R;
+        // double L = g_maxX1 - g_minX1;
+        // double p_air = 7e5; // Pa = 7 Bar
+        // double p1 = p_air;
+        // double p2 = 0.0;
+        // double mu = 17.2e-6; // Pa s, air 20° C
+        // double N = R * R / 2 * mu * u * (p1 - p2) / L - 3;
+        // if (myid == 0) VF_LOG_INFO("Air inflow velocity = {} m/s", u);
+        // if (myid == 0) VF_LOG_INFO("Air inflow velocity = {} dx/dt", uLB_ref);
+        //
+
+        // double nu = mu / rhoConcrete;
+        // double Re = d_part * u / nu;
+        // if (myid == 0) VF_LOG_INFO("Re_air = {}", Re);
+
+        // double nuLB = d_part * unitsAir->getFactorLentghWToLb() * uLB_ref / Re;
+        // if (myid == 0) VF_LOG_INFO("nuLB_air = {}", nuLB);
+        // nu_l_LB = nuLB;
+  
+        SPtr<LBMUnitConverter> unitsAir = std::make_shared<LBMUnitConverter>(d_part, 1., 1.2041, d_part / dx, uLB_ref);
+        //SPtr<LBMUnitConverter> unitsAir = std::make_shared<LBMUnitConverter>(d_part, LBMUnitConverter::AIR_20C, d_part / dx);
+        double V_air = 40./6.;  // flow rate [m^3/h] //10.
+        double D_air = 0.00553;     // air inlet diameter [m]
+        double R_air = D_air / 2.0; // radius [m]
+        double A_air = UbMath::PI * (R_air * R_air);
+        double u_air = V_air / 3600 / A_air;
+        double uLB_air = u_air * unitsAir->getFactorVelocityWToLb();
+        // double cx1 = -1.2788 + R;
+        double cx2 = 0.385822 + R_air;
+        double cx3 = 0.135562 + R_air;
+        double L_air = 0.00747;
+        double p_air = 7e5; // Pa = 7 Bar
+        double p1 = p_air;
+        double p2 = 1e5;
+        double mu_air = 17.2e-6; // Pa s, air 20° C
+        double rho_air = 1.2041; // [kg/m^3]
+        double Re_inlet = D_air * u_air * rho_air / mu_air;
+        double lambda = 0.3164 / pow(Re_inlet, 0.25);
+        double deltaP = (lambda / (2. * R_air)) * (rho_air * pow(u_air, 2) / 2.); // Darcy friction factor (Rohrreibungszahl)
+        double N = pow(R_air, 2) / (2. * mu_air * u_air) * deltaP - 3.;
+        // double N = R_air * R_air / 2 * mu_air * u_air * (p1 - p2) / L_air - 3;
+        if (myid == 0) VF_LOG_INFO("Air inflow velocity = {} m/s", u_air);
+        if (myid == 0) VF_LOG_INFO("Air inflow velocity = {} dx/dt", uLB_air);
+
+        double nu_air = mu_air / rho_air;
+        double Re_air = d_part * u_air / nu_air;
+        if (myid == 0) VF_LOG_INFO("Air Re = {}", Re_air);
+
+        double nuLB_air = nu_air * unitsAir->getFactorViscosityWToLb(); // d_part * unitsAir->getFactorLentghWToLb() * uLB_air / Re_air;
+        if (myid == 0) VF_LOG_INFO("nuLB_air = {}", nuLB_air);
+        nu_l_LB = nuLB_air;
+
+        if (myid == 0) VF_LOG_INFO("nu_h = {}", nu_h_LB);
+        if (myid == 0) VF_LOG_INFO("nu_l = {}", nu_l_LB);
+        if (myid == 0) VF_LOG_INFO("sigma_LB = {}", sigma_LB);
+
+        double p_air_LB = p_air * unitsAir->getFactorPressureWToLb();
+        if (myid == 0) VF_LOG_INFO("p_air_LB = {}", p_air_LB);
+
+        // mu::Parser fctVx1;
+        ////fctVx1.SetExpr("U");
+        ////fctVx1.DefineConst("U", uLB_air);
+        // mu::Parser fctVx2;
+        // fctVx2.SetExpr("U");
+        // fctVx2.DefineConst("U", 0);
+        // mu::Parser fctVx3;
+        ////fctVx3.SetExpr("U");
+        ////fctVx3.DefineConst("U", -uLB_air);
+
+        double cx1 = 0;
+        double alpha = 0;
+        double gamma = 0;
+        double U = uLB_air;// * ((N + 3.) / (N + 1.));
+
+        mu::Parser fctVx1;
+        //fctVx1.SetExpr("U*cos(alpha*_pi/180)*(1-(((((x1-x0)^2+(x2-y0)^2+(x3-z0)^2)^0.5)/R)^NplusOne))");
+        //fctVx1.SetExpr("U*cos(alpha*_pi/180)*(1-(((((x1-x0)^2+(x2-y0)^2+(x3-z0)^2)^0.5)/R)))");
+        // fctVx1.SetExpr("(((x1-x0)^2+(x2-y0)^2+(x3-z0)^2)^0.5/R)^NplusOne");
+        fctVx1.SetExpr("U*cos(alpha*_pi/180)");
+        fctVx1.DefineConst("x0", cx1);
+        fctVx1.DefineConst("y0", cx2);
+        fctVx1.DefineConst("z0", cx3);
+        fctVx1.DefineConst("R", R_air);
+        fctVx1.DefineConst("U", U); //* ((N + 3.) / (N + 1.)));
+        fctVx1.DefineConst("NplusOne", N + 1.0);
+        fctVx1.DefineConst("alpha", alpha);
+        fctVx1.DefineConst("gamma", gamma);
+
+        mu::Parser fctVx2;
+        //fctVx2.SetExpr("U*sin(alpha*_pi/180)*(1-(((((x1-x0)^2+(x2-y0)^2+(x3-z0)^2)^0.5)/R)^NplusOne))");
+        //fctVx2.SetExpr("U*sin(alpha*_pi/180)*(1-(((((x1-x0)^2+(x2-y0)^2+(x3-z0)^2)^0.5)/R)))");
+        fctVx2.SetExpr("U*sin(alpha*_pi/180)");
+        fctVx2.DefineConst("x0", cx1);
+        fctVx2.DefineConst("x0", cx1);
+        fctVx2.DefineConst("y0", cx2);
+        fctVx2.DefineConst("z0", cx3);
+        fctVx2.DefineConst("R", R_air);
+        fctVx2.DefineConst("U", U); //* ((N + 3.) / (N + 1.)));
+        fctVx2.DefineConst("NplusOne", N + 1.0);
+        fctVx2.DefineConst("alpha", alpha);
+
+        mu::Parser fctVx3;
+        //fctVx3.SetExpr("U*(1-(((((x1-x0)^2+(x2-y0)^2+(x3-z0)^2)^0.5)/R)^NplusOne))");
+        //fctVx3.SetExpr("U*cos(alpha*_pi/180)*(1-(((((x1-x0)^2+(x2-y0)^2+(x3-z0)^2)^0.5)/R)))");
+        fctVx3.SetExpr("U");
+        fctVx3.DefineConst("x0", cx1);
+        fctVx3.DefineConst("y0", cx2);
+        fctVx3.DefineConst("z0", cx3);
+        fctVx3.DefineConst("R", R_air);
+        fctVx3.DefineConst("U", -U); //* ((N + 3.) / (N + 1.)));
+        fctVx3.DefineConst("NplusOne", N + 1.0);
+        fctVx3.DefineConst("alpha", alpha);
+        fctVx3.DefineConst("gamma", gamma);
+
+        // SPtr<BC> inflowAirBC1(new VelocityBC(true, false, false, fct, 0, BCFunction::INFCONST));
+        // inflowAirBC1->setBCStrategy(SPtr<BCStrategy>(new VelocityBCStrategy()));
+        // t = U * sin(alpha * _pi / 180) * (1 - (((((x1 - x0) ^ 2 + (x2 - y0) ^ 2 + (x3 - z0) ^ 2) ^ 0.5) / R) ^ NplusOne));
+        cx1 = -1.31416;
+        cx2 = 0.388684;
+        cx3 = 0.138177;
+        alpha = 0;
+        gamma = 225;
+        fctVx1.DefineConst("x0", cx1);
+        fctVx1.DefineConst("y0", cx2);
+        fctVx1.DefineConst("z0", cx3);
+        fctVx1.DefineConst("alpha", alpha);
+        fctVx1.DefineConst("gamma", gamma);
+        fctVx2.DefineConst("x0", cx1);
+        fctVx2.DefineConst("y0", cx2);
+        fctVx2.DefineConst("z0", cx3);
+        fctVx2.DefineConst("alpha", alpha);
+        fctVx2.DefineConst("gamma", gamma);
+        fctVx3.DefineConst("x0", cx1);
+        fctVx3.DefineConst("y0", cx2);
+        fctVx3.DefineConst("z0", cx3);
+        fctVx3.DefineConst("alpha", alpha);
+        fctVx3.DefineConst("gamma", gamma);
+
+        SPtr<BC> inflowAirBC1(new VelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, 0, BCFunction::INFCONST));
+        inflowAirBC1->setBCStrategy(SPtr<BCStrategy>(new VelocityBCStrategy()));        
+        //SPtr<BC> inflowAirBC1(new MultiphaseVelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, phiL, 0, BCFunction::INFCONST));
+        //inflowAirBC1->setBCStrategy(SPtr<BCStrategy>(new MultiphaseVelocityBCStrategy()));
+
+        fctVx1.DefineVar("x1", &cx1);
+        fctVx1.DefineVar("x2", &cx2);
+        fctVx1.DefineVar("x3", &cx3);
+        fctVx2.DefineVar("x1", &cx1);
+        fctVx2.DefineVar("x2", &cx2);
+        fctVx2.DefineVar("x3", &cx3);
+        fctVx3.DefineVar("x1", &cx1);
+        fctVx3.DefineVar("x2", &cx2);
+        fctVx3.DefineVar("x3", &cx3);
+
+        if (myid == 0) {
+
+            VF_LOG_INFO("fctVx1 = {}", fctVx1.Eval());
+            VF_LOG_INFO("fctVx2 = {}", fctVx2.Eval());
+            VF_LOG_INFO("fctVx3 = {}", fctVx3.Eval());
+            VF_LOG_INFO("N = {}", N);
+            VF_LOG_INFO("NplusOne = {}", N + 1.0);
+            // return 0;
+        }
+        cx1 = -1.31303;
+        cx2 = 0.377234;
+        cx3 = 0.138174;
+        alpha = 60;
+        fctVx1.DefineConst("x0", cx1);
+        fctVx1.DefineConst("y0", cx2);
+        fctVx1.DefineConst("z0", cx3);
+        fctVx1.DefineConst("alpha", alpha);
+        fctVx2.DefineConst("x0", cx1);
+        fctVx2.DefineConst("y0", cx2);
+        fctVx2.DefineConst("z0", cx3);
+        fctVx2.DefineConst("alpha", alpha);
+        fctVx3.DefineConst("x0", cx1);
+        fctVx3.DefineConst("y0", cx2);
+        fctVx3.DefineConst("z0", cx3);
+        SPtr<BC> inflowAirBC2(new VelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, 0, BCFunction::INFCONST));
+        inflowAirBC2->setBCStrategy(SPtr<BCStrategy>(new VelocityBCStrategy()));
+        //SPtr<BC> inflowAirBC2(new MultiphaseVelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, phiL, 0, BCFunction::INFCONST));
+        //inflowAirBC2->setBCStrategy(SPtr<BCStrategy>(new MultiphaseVelocityBCStrategy()));
+
+        cx1 = -1.2948374155694822;
+        cx2 = 0.37733728717266285;
+        cx3 = 0.13840460401111598;
+        alpha = 120;
+        fctVx1.DefineConst("x0", cx1);
+        fctVx1.DefineConst("y0", cx2);
+        fctVx1.DefineConst("z0", cx3);
+        fctVx1.DefineConst("alpha", alpha);
+        fctVx2.DefineConst("x0", cx1);
+        fctVx2.DefineConst("y0", cx2);
+        fctVx2.DefineConst("z0", cx3);
+        fctVx2.DefineConst("alpha", alpha);
+        fctVx3.DefineConst("x0", cx1);
+        fctVx3.DefineConst("y0", cx2);
+        fctVx3.DefineConst("z0", cx3);
+        SPtr<BC> inflowAirBC3(new VelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, 0, BCFunction::INFCONST));
+        inflowAirBC3->setBCStrategy(SPtr<BCStrategy>(new VelocityBCStrategy()));
+        //SPtr<BC> inflowAirBC3(new MultiphaseVelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, phiL, 0, BCFunction::INFCONST));
+        //inflowAirBC3->setBCStrategy(SPtr<BCStrategy>(new MultiphaseVelocityBCStrategy()));
+
+        cx1 = -1.28847;
+        cx2 = 0.3885;
+        cx3 = 0.1385;
+        alpha = 180;
+        fctVx1.DefineConst("x0", cx1);
+        fctVx1.DefineConst("y0", cx2);
+        fctVx1.DefineConst("z0", cx3);
+        fctVx1.DefineConst("alpha", alpha);
+        fctVx2.DefineConst("x0", cx1);
+        fctVx2.DefineConst("y0", cx2);
+        fctVx2.DefineConst("z0", cx3);
+        fctVx2.DefineConst("alpha", alpha);
+        fctVx3.DefineConst("x0", cx1);
+        fctVx3.DefineConst("y0", cx2);
+        fctVx3.DefineConst("z0", cx3);
+        SPtr<BC> inflowAirBC4(new VelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, 0, BCFunction::INFCONST));
+        inflowAirBC4->setBCStrategy(SPtr<BCStrategy>(new VelocityBCStrategy()));
+        //SPtr<BC> inflowAirBC4(new MultiphaseVelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, phiL, 0, BCFunction::INFCONST));
+        //inflowAirBC4->setBCStrategy(SPtr<BCStrategy>(new MultiphaseVelocityBCStrategy()));
+
+        cx1 = -1.294771417778694;
+        cx2 = 0.399787947463142;
+        cx3 = 0.1383429692754194;
+        alpha = 240;
+        fctVx1.DefineConst("x0", cx1);
+        fctVx1.DefineConst("y0", cx2);
+        fctVx1.DefineConst("z0", cx3);
+        fctVx1.DefineConst("alpha", alpha);
+        fctVx2.DefineConst("x0", cx1);
+        fctVx2.DefineConst("y0", cx2);
+        fctVx2.DefineConst("z0", cx3);
+        fctVx2.DefineConst("alpha", alpha);
+        fctVx3.DefineConst("x0", cx1);
+        fctVx3.DefineConst("y0", cx2);
+        fctVx3.DefineConst("z0", cx3);
+        SPtr<BC> inflowAirBC5(new VelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, 0, BCFunction::INFCONST));
+        inflowAirBC5->setBCStrategy(SPtr<BCStrategy>(new VelocityBCStrategy()));
+        //SPtr<BC> inflowAirBC5(new MultiphaseVelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, phiL, 0, BCFunction::INFCONST));
+        //inflowAirBC5->setBCStrategy(SPtr<BCStrategy>(new MultiphaseVelocityBCStrategy()));
+
+        cx1 = -1.3077338898450492;
+        cx2 = 0.3998516560596088;
+        cx3 = 0.13843501416896437;
+        alpha = 300;
+        fctVx1.DefineConst("x0", cx1);
+        fctVx1.DefineConst("y0", cx2);
+        fctVx1.DefineConst("z0", cx3);
+        fctVx1.DefineConst("alpha", alpha);
+        fctVx2.DefineConst("x0", cx1);
+        fctVx2.DefineConst("y0", cx2);
+        fctVx2.DefineConst("z0", cx3);
+        fctVx2.DefineConst("alpha", alpha);
+        fctVx3.DefineConst("x0", cx1);
+        fctVx3.DefineConst("y0", cx2);
+        fctVx3.DefineConst("z0", cx3);
+        SPtr<BC> inflowAirBC6(new VelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, 0, BCFunction::INFCONST));
+        inflowAirBC6->setBCStrategy(SPtr<BCStrategy>(new VelocityBCStrategy()));
+        //SPtr<BC> inflowAirBC6(new MultiphaseVelocityBC(true, true, true, fctVx1, fctVx2, fctVx3, phiL, 0, BCFunction::INFCONST));
+        //inflowAirBC6->setBCStrategy(SPtr<BCStrategy>(new MultiphaseVelocityBCStrategy()));
+
+        // Pressure BC for air inlet
+        // SPtr<BC> inflowAirBC1(new DensityBC(p_air_LB));
+        // inflowAirBC1->setBCStrategy(SPtr<BCStrategy>(new MultiphasePressureBCStrategy()));
+
+        SPtr<BC> outflowBC(new DensityBC(rhoLB));
+        outflowBC->setBCStrategy(SPtr<BCStrategy>(new NonEqDensityBCStrategy()));
+        //outflowBC->setBCStrategy(SPtr<BCStrategy>(new MultiphasePressureBCStrategy()));
+        
+        // SPtr<BC> outflowBC(new DensityBC(rhoLB));
+        //outflowBC->setBCStrategy(SPtr<BCStrategy>(new MultiphaseNonReflectingOutflowBCStrategy()));
+        //////////////////////////////////////////////////////////////////////////////////
+        // BC visitor
+        BoundaryConditionsBlockVisitor bcVisitor;
+        //MultiphaseBoundaryConditionsBlockVisitor bcVisitor;
+        bcVisitor.addBC(noSlipBC);
+        //bcVisitor.addBC(inflowConcreteBC);
+        bcVisitor.addBC(inflowAirBC1);
+        bcVisitor.addBC(outflowBC);
+
+        // SPtr<LBMKernel> kernel   = make_shared<IBcumulantK17LBMKernel>();
+         //SPtr<LBMKernel> kernel   = make_shared<CumulantK17LBMKernel>();
+        // SPtr<LBMKernel> kernel = make_shared<MultiphaseTwoPhaseFieldsPressureFilterLBMKernel>();
+        // SPtr<LBMKernel> kernel = make_shared<MultiphaseSimpleVelocityBaseExternalPressureLBMKernel>();
+        //SPtr<LBMKernel> kernel = make_shared<MultiphaseSharpInterfaceLBMKernel>();
+        SPtr<LBMKernel> kernel = make_shared<IBcumulantK17LBMKernel>();
+        //SPtr<LBMKernel> kernel = make_shared<IBsharpInterfaceLBMKernel>();
+
+        kernel->setWithForcing(false);
+        kernel->setForcingX1(0.0);
+        kernel->setForcingX2(0.0);
+        kernel->setForcingX3(0.0);
+
+        kernel->setPhiL(phiL);
+        kernel->setPhiH(phiH);
+        kernel->setPhaseFieldRelaxation(tauH);
+        kernel->setMobility(mob);
+        kernel->setInterfaceWidth(interfaceThickness);
+
+        kernel->setCollisionFactorMultiphase(nu_h_LB, nu_l_LB);
+        kernel->setDensityRatio(densityRatio);
+        kernel->setMultiphaseModelParameters(beta, kappa);
+        kernel->setContactAngle(theta);
+        kernel->setSigma(sigma_LB);
+
+        SPtr<BCSet> bcProc = make_shared<BCSet>();
+        kernel->setBCSet(bcProc);
+
+        SPtr<Grid3D> grid = make_shared<Grid3D>(comm);
+        grid->setPeriodicX1(false);
+        grid->setPeriodicX2(false);
+        grid->setPeriodicX3(false);
+        grid->setDeltaX(dx);
+        grid->setBlockNX(blockNX[0], blockNX[1], blockNX[2]);
+        grid->setGhostLayerWidth(1);
+
+        string geoPath = "d:/Projects/TRR277/Project/WP4/NozzleGeo";
+
+        string outputPath = "d:/temp/NozzleFlowTest_SinglePhase_With_Part_fraction_0.13_vel_0.2_ogl";
+        UbSystem::makeDirectory(outputPath);
+        UbSystem::makeDirectory(outputPath + "/liggghts");
+
+        // if (myid == 0) {
+        //     stringstream logFilename;
+        //     logFilename << outputPath + "/logfile" + UbSystem::toString(UbSystem::getTimeStamp()) + ".txt";
+        //     UbLog::output_policy::setStream(logFilename.str());
+        // }
+
+        /////////////////////////////////////////////////////////////////////
+        //LIGGGHTS things
+        /////////////////////////////////////////////////////////////////////
+        string inFile1 = "d:/Projects/TRR277/Project/WP4/Config/in.nozzle";
+        // string inFile2 = "d:/Projects/VirtualFluids_LIGGGHTS_coupling/apps/cpu/LiggghtsApp/in2.lbdem";
+        MPI_Comm mpi_comm = *(MPI_Comm *)(comm->getNativeCommunicator());
+        LiggghtsCouplingWrapper wrapper(argv, mpi_comm);
+
+        double v_frac = 0.1;
+        double dt_phys = units->getFactorTimeLbToW();
+        int demSubsteps = 10;
+        double dt_dem = dt_phys / (double)demSubsteps;
+        int vtkSteps = 1000;
+        string demOutDir = outputPath + "/liggghts";
+
+        // wrapper.execCommand("echo none");
+
+        // wrapper.execFile((char*)inFile1.c_str());
+
+        //// set timestep and output directory
+        wrapper.setVariable("t_step", dt_dem);
+        wrapper.setVariable("dmp_stp", vtkSteps * demSubsteps);
+        wrapper.setVariable("dmp_dir", demOutDir);
+
+        wrapper.execFile((char *)inFile1.c_str());
+        //wrapper.runUpto(demSubsteps - 1);
+        // wrapper.runUpto(1000);
+
+        //LatticeDecomposition lDec((g_maxX1 - g_minX1) / dx, (g_maxX2 - g_minX2) / dx, (g_maxX3 - g_minX3) / dx, wrapper.lmp, grid);
+
+        SPtr<UbScheduler> lScheduler = make_shared<UbScheduler>(1);
+        SPtr<LiggghtsCouplingSimulationObserver> lcSimulationObserver = make_shared<LiggghtsCouplingSimulationObserver>(grid, lScheduler, comm, wrapper, demSubsteps, unitsAir);
+        //SPtr<Grid3DVisitor> partVisitor = make_shared<LiggghtsPartitioningGridVisitor>(std::ceil((g_maxX1 - g_minX1) / dx), std::ceil((g_maxX2 - g_minX2) / dx), std::ceil((g_maxX3 - g_minX3) / dx), wrapper.lmp);
+        SPtr<Grid3DVisitor> partVisitor = make_shared<LiggghtsPartitioningGridVisitor>(26,26,420, wrapper.lmp);
+        
+        /////////////////////////////////////////////////////////////////////
+        /////////////////////////////////////////////////////////////////////
+        
+        SPtr<Grid3DVisitor> metisVisitor(new MetisPartitioningGridVisitor(comm, MetisPartitioningGridVisitor::LevelBased, vf::lbm::dir::DIR_MMM, MetisPartitioner::RECURSIVE));
+
+        SPtr<GbObject3D> gridCube = make_shared<GbCuboid3D>(g_minX1, g_minX2, g_minX3, g_maxX1, g_maxX2, g_maxX3);
+        if (myid == 0) GbSystem3D::writeGeoObject(gridCube.get(), outputPath + "/geo/gridCube", WbWriterVtkXmlBinary::getInstance());
+
+        GenBlocksGridVisitor genBlocks(gridCube);
+        grid->accept(genBlocks);
+
+        // geo
+        //////////////////////////////////////////////////////////
+        int accuracy = Interactor3D::EDGES;
+        ///////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshNozzleAirDistributor = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleAirDistributor:start");
+        meshNozzleAirDistributor->readMeshFromSTLFileASCII(geoPath + "/01_Nozzle_Air_Distributor.stl", false);
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleAirDistributor:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshNozzleAirDistributor.get(), outputPath + "/geo/meshNozzleAirDistributor", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intrNozzleAirDistributor = std::make_shared<D3Q27TriFaceMeshInteractor>(meshNozzleAirDistributor, grid, noSlipBC, Interactor3D::SOLID, (Interactor3D::Accuracy)accuracy);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshNozzleAirInlet = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleAirInlet:start");
+        meshNozzleAirInlet->readMeshFromSTLFileASCII(geoPath + "/02_Nozzle_Air_Inlet.stl", false);
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleAirInlet:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshNozzleAirInlet.get(), outputPath + "/geo/meshNozzleAirInlet", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intrNozzleAirInlet = std::make_shared<D3Q27TriFaceMeshInteractor>(meshNozzleAirInlet, grid, noSlipBC, Interactor3D::SOLID, (Interactor3D::Accuracy)accuracy);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshNozzleSpacer = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleSpacer:start");
+        meshNozzleSpacer->readMeshFromSTLFileASCII(geoPath + "/03_Nozzle_Spacer.stl", true);
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleSpacer:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshNozzleSpacer.get(), outputPath + "/geo/meshNozzleSpacer", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intrNozzleSpacer = std::make_shared<D3Q27TriFaceMeshInteractor>(meshNozzleSpacer, grid, noSlipBC, Interactor3D::SOLID, (Interactor3D::Accuracy)accuracy);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshNozzleAccDistributor = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleAccDistributor:start");
+        meshNozzleAccDistributor->readMeshFromSTLFileASCII(geoPath + "/04_Nozzle_Acc_Distributor.stl", false);
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleAccDistributor:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshNozzleAccDistributor.get(), outputPath + "/geo/meshNozzleAccDistributor", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intrNozzleAccDistributor = std::make_shared<D3Q27TriFaceMeshInteractor>(meshNozzleAccDistributor, grid, noSlipBC, Interactor3D::SOLID, (Interactor3D::Accuracy)accuracy);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshNozzleAccInlet = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleAccInlet:start");
+        meshNozzleAccInlet->readMeshFromSTLFileASCII(geoPath + "/05_Nozzle_Acc_Inlet.stl", false);
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleAccInlet:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshNozzleAccInlet.get(), outputPath + "/geo/meshNozzleAccInlet", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intrNozzleAccInlet = std::make_shared<D3Q27TriFaceMeshInteractor>(meshNozzleAccInlet, grid, noSlipBC, Interactor3D::SOLID, (Interactor3D::Accuracy)accuracy);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshNozzleVolcanNozzle1 = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleVolcanNozzle1:start");
+        meshNozzleVolcanNozzle1->readMeshFromSTLFileBinary(geoPath + "/06_1_Nozzle_Volcan_Nozzle.stl", true);
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleVolcanNozzle1:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshNozzleVolcanNozzle1.get(), outputPath + "/geo/meshNozzleVolcanNozzle1", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intrNozzleVolcanNozzle1 = std::make_shared<D3Q27TriFaceMeshInteractor>(meshNozzleVolcanNozzle1, grid, noSlipBC, Interactor3D::SOLID, Interactor3D::EDGES);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshNozzleVolcanNozzle2 = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleVolcanNozzle2:start");
+        meshNozzleVolcanNozzle2->readMeshFromSTLFileBinary(geoPath + "/06_2_Nozzle_Volcan_Nozzle.stl", true);
+        if (myid == 0) UBLOG(logINFO, "Read meshNozzleVolcanNozzle2:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshNozzleVolcanNozzle2.get(), outputPath + "/geo/meshNozzleVolcanNozzle2", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intrNozzleVolcanNozzle2 = std::make_shared<D3Q27TriFaceMeshInteractor>(meshNozzleVolcanNozzle2, grid, noSlipBC, Interactor3D::SOLID, Interactor3D::POINTS);
+        ///////////////////////////////////////////////////////////
+        // box
+        SPtr<D3Q27Interactor> intrBox = SPtr<D3Q27Interactor>(new D3Q27Interactor(gridCube, grid, noSlipBC, Interactor3D::INVERSESOLID));
+        ///////////////////////////////////////////////////////////
+        // inflow
+        //GbCylinder3DPtr geoInflow(new GbCylinder3D(-1.30181 + 0.0005, 0.390872 - 0.00229, 0.20105, -1.30181 + 0.0005, 0.390872 - 0.00229, 0.23, 0.013));
+        GbCylinder3DPtr geoInflow(new GbCylinder3D(-1.30181 + 0.0005, 0.390872 - 0.00229, 0.175, -1.30181 + 0.0005, 0.390872 - 0.00229, 0.21, 0.013));
+        if (myid == 0) GbSystem3D::writeGeoObject(geoInflow.get(), outputPath + "/geo/geoInflow", WbWriterVtkXmlBinary::getInstance());
+        SPtr<D3Q27Interactor> intrInflow = SPtr<D3Q27Interactor>(new D3Q27Interactor(geoInflow, grid, inflowConcreteBC, Interactor3D::SOLID));
+        ///////////////////////////////////////////////////////////
+        // outflow
+        //GbCylinder3DPtr geoOutflow(new GbCylinder3D(-1.30181 + 0.0005, 0.390872 - 0.00229, -0.22, -1.30181 + 0.0005, 0.390872 - 0.00229, -0.21, 0.013));
+        //GbCylinder3DPtr geoOutflow(new GbCylinder3D(-1.30181 + 0.0005, 0.390872 - 0.00229, -0.426, -1.30181 + 0.0005, 0.390872 - 0.00229, -0.415, 0.013));
+        GbCylinder3DPtr geoOutflow(new GbCylinder3D(-1.30181 + 0.0005, 0.390872 - 0.00229, g_minX3, -1.30181 + 0.0005, 0.390872 - 0.00229, g_minX3+2.*dx, 0.013));
+        if (myid == 0) GbSystem3D::writeGeoObject(geoOutflow.get(), outputPath + "/geo/geoOutflow", WbWriterVtkXmlBinary::getInstance());
+        SPtr<D3Q27Interactor> intrOutflow = SPtr<D3Q27Interactor>(new D3Q27Interactor(geoOutflow, grid, outflowBC, Interactor3D::SOLID));
+        ///////////////////////////////////////////////////////////
+        // SPtr<GbTriFaceMesh3D> geoAirInlet = std::make_shared<GbTriFaceMesh3D>();
+        // if (myid == 0) UBLOG(logINFO, "Read Air_Inlet:start");
+        // geoAirInlet->readMeshFromSTLFileASCII(geoPath + "/Air_Inlet.stl", true);
+        // if (myid == 0) UBLOG(logINFO, "Read Air_Inlet:end");
+        // if (myid == 0) GbSystem3D::writeGeoObject(geoAirInlet.get(), outputPath + "/geo/geoAirInlet", WbWriterVtkXmlBinary::getInstance());
+        // SPtr<Interactor3D> intrAirInlet = std::make_shared<D3Q27TriFaceMeshInteractor>(geoAirInlet, grid, inflowAirBC1, Interactor3D::SOLID, Interactor3D::EDGES);
+        /////////////////////////////////////////////////////////////
+        // Fluid area
+        GbCylinder3DPtr geoFluidArea(new GbCylinder3D(-1.30181 + 0.0005, 0.390872 - 0.00229, g_minX3, -1.30181 + 0.0005, 0.390872 - 0.00229, g_maxX3, 0.013));
+        if (myid == 0) GbSystem3D::writeGeoObject(geoFluidArea.get(), outputPath + "/geo/geoFluidArea", WbWriterVtkXmlBinary::getInstance());
+        SPtr<D3Q27Interactor> intrFluidArea = SPtr<D3Q27Interactor>(new D3Q27Interactor(geoFluidArea, grid, noSlipBC, Interactor3D::INVERSESOLID));
+        ///////////////////////////////////////////////////////////
+        ///////////////////////////////////////////////////////////
+        GbCylinder3DPtr geoAirInflow(new GbCylinder3D(-1.31431 - 0.0005, 0.388587, 0.1383275, -1.31431, 0.388587, 0.1383275, 0.002765));
+        if (myid == 0) GbSystem3D::writeGeoObject(geoAirInflow.get(), outputPath + "/geo/geoAirInlet", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intrAirInflow = std::make_shared<D3Q27Interactor>(geoAirInflow, grid, inflowAirBC1, Interactor3D::SOLID, Interactor3D::EDGES);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshAirInlet1 = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet1:start");
+        meshAirInlet1->readMeshFromSTLFileASCII(geoPath + "/Air_Inlet_1.stl", true);
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet1:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshAirInlet1.get(), outputPath + "/geo/meshAirInlet1", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intAirInlet1 = std::make_shared<D3Q27TriFaceMeshInteractor>(meshAirInlet1, grid, inflowAirBC1, Interactor3D::SOLID, Interactor3D::POINTS);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshAirInlet2 = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet2:start");
+        meshAirInlet2->readMeshFromSTLFileASCII(geoPath + "/Air_Inlet_2.stl", true);
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet2:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshAirInlet2.get(), outputPath + "/geo/meshAirInlet2", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intAirInlet2 = std::make_shared<D3Q27TriFaceMeshInteractor>(meshAirInlet2, grid, inflowAirBC2, Interactor3D::SOLID, Interactor3D::POINTS);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshAirInlet3 = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet3:start");
+        meshAirInlet3->readMeshFromSTLFileASCII(geoPath + "/Air_Inlet_3.stl", true);
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet3:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshAirInlet3.get(), outputPath + "/geo/meshAirInlet3", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intAirInlet3 = std::make_shared<D3Q27TriFaceMeshInteractor>(meshAirInlet3, grid, inflowAirBC3, Interactor3D::SOLID, Interactor3D::POINTS);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshAirInlet4 = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet4:start");
+        meshAirInlet4->readMeshFromSTLFileASCII(geoPath + "/Air_Inlet_4.stl", true);
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet4:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshAirInlet4.get(), outputPath + "/geo/meshAirInlet4", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intAirInlet4 = std::make_shared<D3Q27TriFaceMeshInteractor>(meshAirInlet4, grid, inflowAirBC4, Interactor3D::SOLID, Interactor3D::POINTS);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshAirInlet5 = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet5:start");
+        meshAirInlet5->readMeshFromSTLFileASCII(geoPath + "/Air_Inlet_5.stl", true);
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet5:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshAirInlet5.get(), outputPath + "/geo/meshAirInlet5", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intAirInlet5 = std::make_shared<D3Q27TriFaceMeshInteractor>(meshAirInlet5, grid, inflowAirBC5, Interactor3D::SOLID, Interactor3D::POINTS);
+        ///////////////////////////////////////////////////////////
+        SPtr<GbTriFaceMesh3D> meshAirInlet6 = std::make_shared<GbTriFaceMesh3D>();
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet6:start");
+        meshAirInlet6->readMeshFromSTLFileASCII(geoPath + "/Air_Inlet_6.stl", true);
+        if (myid == 0) UBLOG(logINFO, "Read meshAirInlet6:end");
+        if (myid == 0) GbSystem3D::writeGeoObject(meshAirInlet6.get(), outputPath + "/geo/meshAirInlet6", WbWriterVtkXmlBinary::getInstance());
+        SPtr<Interactor3D> intAirInlet6 = std::make_shared<D3Q27TriFaceMeshInteractor>(meshAirInlet6, grid, inflowAirBC6, Interactor3D::SOLID, Interactor3D::POINTS);
+        ///////////////////////////////////////////////////////////
+
+        InteractorsHelper intHelper(grid, partVisitor, false);
+
+        intHelper.addInteractor(intrFluidArea);
+        intHelper.addInteractor(intrNozzleVolcanNozzle2);
+        // intHelper.addInteractor(intrBox);
+        //intHelper.addInteractor(intrInflow);
+        // intHelper.addInteractor(intrAirInflow);
+        intHelper.addInteractor(intAirInlet1);
+        intHelper.addInteractor(intAirInlet2);
+        intHelper.addInteractor(intAirInlet3);
+        intHelper.addInteractor(intAirInlet4);
+        intHelper.addInteractor(intAirInlet5);
+        intHelper.addInteractor(intAirInlet6);
+        intHelper.addInteractor(intrOutflow);
+
+        // intHelper.addInteractor(intrNozzleAirDistributor);
+        // intHelper.addInteractor(intrNozzleAirInlet);
+        // intHelper.addInteractor(intrNozzleSpacer);
+        // intHelper.addInteractor(intrNozzleAccDistributor);
+        // intHelper.addInteractor(intrNozzleAccInlet);
+        // intHelper.addInteractor(intrNozzleVolcanNozzle1);
+
+        intHelper.selectBlocks();
+
+        SPtr<SimulationObserver> ppblocks = make_shared<WriteBlocksSimulationObserver>(grid, SPtr<UbScheduler>(new UbScheduler(1)), outputPath, WbWriterVtkXmlBinary::getInstance(), comm);
+        ppblocks->update(0);
+        ppblocks.reset();
+
+        // if (myid == 0) UBLOG(logINFO, Utilities::toString(grid, comm->getNumberOfProcesses()));
+
+        SetKernelBlockVisitor kernelVisitor(kernel, nu_l_LB, comm->getNumberOfProcesses());
+        //MultiphaseSetKernelBlockVisitor kernelVisitor(kernel, nu_h_LB, nu_l_LB, 1e9, 1);
+        grid->accept(kernelVisitor);
+
+
+        intHelper.setBC();
+
+        // InitDistributionsBlockVisitor initVisitor;
+        // grid->accept(initVisitor);
+
+        double x1c = -1.31431 + R;
+        double x2c = 0.375582 + R;
+        double Ri = 5;
+        double x3c = 0.136 + Ri;
+
+        //R = 0.2 - 0.145; // 0.078-0.04; // 0.2;
+
+        mu::Parser fct1;
+        // fct1.SetExpr(" 0.5 - 0.5 * tanh(2 * (sqrt((x1 - x1c) ^ 2 + (x2 - x2c) ^ 2 + (x3 - x3c) ^ 2) - radius) / interfaceThickness)");
+        fct1.SetExpr(" 0.5 - 0.5 * tanh(2 * (sqrt((x1 - x1c) ^ 2 + (x2 - x2c) ^ 2 + (x3 - x3c) ^ 2) - radius) / interfaceThickness)");
+        fct1.DefineConst("x1c", x1c);
+        fct1.DefineConst("x2c", x2c);
+        fct1.DefineConst("x3c", x3c);
+        fct1.DefineConst("radius", Ri);
+        fct1.DefineConst("interfaceThickness", interfaceThickness * dx);
+
+        //MultiphaseVelocityFormInitDistributionsBlockVisitor initVisitor;
+        //initVisitor.setPhi(fct1);
+        //grid->accept(initVisitor);
+
+        InitDistributionsBlockVisitor initVisitor;
+        grid->accept(initVisitor);
+
+        // boundary conditions grid
+        {
+            SPtr<UbScheduler> geoSch(new UbScheduler(1));
+            SPtr<WriteBoundaryConditionsSimulationObserver> ppgeo(new WriteBoundaryConditionsSimulationObserver(grid, geoSch, outputPath, WbWriterVtkXmlBinary::getInstance(), comm));
+            ppgeo->update(0);
+            ppgeo.reset();
+        }
+
+        grid->accept(bcVisitor);
+
+        OneDistributionSetConnectorsBlockVisitor setConnsVisitor(comm);
+        //TwoDistributionsDoubleGhostLayerSetConnectorsBlockVisitor setConnsVisitor(comm);
+        // ThreeDistributionsDoubleGhostLayerSetConnectorsBlockVisitor setConnsVisitor(comm);
+        grid->accept(setConnsVisitor);
+
+        int numOfThreads = 1;
+        omp_set_num_threads(numOfThreads);
+
+        SPtr<UbScheduler> nupsSch = std::make_shared<UbScheduler>(10, 10, 100);
+        SPtr<NUPSCounterSimulationObserver> nupsSimulationObserver = make_shared<NUPSCounterSimulationObserver>(grid, nupsSch, numOfThreads, comm);
+
+        //// write data for visualization of macroscopic quantities
+        SPtr<UbScheduler> visSch(new UbScheduler(vtkSteps));
+        // SPtr<UbScheduler> visSch(new UbScheduler(1, 8700, 8800));
+        // visSch->addSchedule(1, 8700, 8800);
+        //SPtr<WriteSharpInterfaceQuantitiesSimulationObserver> writeMQSimulationObserver(new WriteSharpInterfaceQuantitiesSimulationObserver(grid, visSch, outputPath, WbWriterVtkXmlBinary::getInstance(), SPtr<LBMUnitConverter>(new LBMUnitConverter()), comm));
+        //writeMQSimulationObserver->update(0);
+
+        SPtr<WriteMacroscopicQuantitiesSimulationObserver> writeMQSimulationObserver(new WriteMacroscopicQuantitiesSimulationObserver(grid, visSch, outputPath, WbWriterVtkXmlBinary::getInstance(), SPtr<LBMUnitConverter>(new LBMUnitConverter()), comm));
+        writeMQSimulationObserver->update(0);
+
+        int endTime = 10000000;
+        SPtr<Simulation> simulation(new Simulation(grid, lScheduler, endTime));
+        simulation->addSimulationObserver(nupsSimulationObserver);
+        simulation->addSimulationObserver(lcSimulationObserver);
+        simulation->addSimulationObserver(writeMQSimulationObserver);
+
+        if (myid == 0) UBLOG(logINFO, "Simulation-start");
+        simulation->run();
+        if (myid == 0) UBLOG(logINFO, "Simulation-end");
+
+    } catch (std::exception &e) {
+        cerr << e.what() << endl << flush;
+    } catch (std::string &s) {
+        cerr << s << endl;
+    } catch (...) {
+        cerr << "unknown exception" << endl;
+    }
+    return 0;
+}
diff --git a/apps/cpu/OrganPipe/OrganPipe.cpp b/apps/cpu/OrganPipe/OrganPipe.cpp
index ad6ec5a1d0892b60f699b74ee4101a9f4ad047e3..b23c159110dce4d1415f4a558d9cd1910e0c2de4 100644
--- a/apps/cpu/OrganPipe/OrganPipe.cpp
+++ b/apps/cpu/OrganPipe/OrganPipe.cpp
@@ -389,9 +389,9 @@ void run(string configname)
          grid->setTimeStep(restartStep);
       }
       ////set connectors
-      //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
-      SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
-      dynamicPointerCast<CompressibleOffsetMomentsInterpolationProcessor>(iProcessor)->setBulkViscosity(nu_LB, bulckViscosity);
+      //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
+      SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolator());
+      dynamicPointerCast<CompressibleOffsetMomentsInterpolator>(iProcessor)->setBulkViscosity(nu_LB, bulckViscosity);
       SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
       grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/PoiseuilleFlow/pf2.cpp b/apps/cpu/PoiseuilleFlow/pf2.cpp
index f312bc37dacc3caadd9935f450cdcf808c945b4f..c339e06a6c9cac71b4ba9d340ef72027fd999f41 100644
--- a/apps/cpu/PoiseuilleFlow/pf2.cpp
+++ b/apps/cpu/PoiseuilleFlow/pf2.cpp
@@ -149,7 +149,7 @@
 //   grid->accept(initVisitor);
 //
 //   //set connectors
-//   InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+//   InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
 //   SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
 //   grid->accept(setConnsVisitor);
 //
diff --git a/apps/cpu/PoiseuilleFlow/pf3.cpp b/apps/cpu/PoiseuilleFlow/pf3.cpp
index a2eca67d593fd9e21641e99bd3910e4c775f00a9..fa01b68521fadb59c4101a82caef30377b3368fc 100644
--- a/apps/cpu/PoiseuilleFlow/pf3.cpp
+++ b/apps/cpu/PoiseuilleFlow/pf3.cpp
@@ -141,7 +141,7 @@
 //   grid->accept(initVisitor);
 //
 //   //set connectors
-//   InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+//   InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
 //   SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
 //   grid->accept(setConnsVisitor);
 //
diff --git a/apps/cpu/PoiseuilleFlow/pf4.cpp b/apps/cpu/PoiseuilleFlow/pf4.cpp
index 9b249f94e19fd6c53b6410702406c498c101ed42..2e419358e1d5b32ea0f9fc542f8d47b80aa6cae8 100644
--- a/apps/cpu/PoiseuilleFlow/pf4.cpp
+++ b/apps/cpu/PoiseuilleFlow/pf4.cpp
@@ -154,7 +154,7 @@
 //   grid->accept(initVisitor);
 //
 //   //set connectors
-//   InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+//   InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
 //   SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
 //   grid->accept(setConnsVisitor);
 //
diff --git a/apps/cpu/TPMSRow/TPMSRow.cpp b/apps/cpu/TPMSRow/TPMSRow.cpp
index 9adcaadde90454a64221d04e55712ff12c175e54..596b79d0525339d38ee18a3062a219459de8f305 100644
--- a/apps/cpu/TPMSRow/TPMSRow.cpp
+++ b/apps/cpu/TPMSRow/TPMSRow.cpp
@@ -447,7 +447,7 @@ void run(string configname)
                 UBLOG(logINFO, "Restart - end");
         }
         // set connectors
-        SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetInterpolationProcessor());
+        SPtr<Interpolator> iProcessor(new CompressibleOffsetInterpolator());
         //SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu, iProcessor);
         OneDistributionSetConnectorsBlockVisitor setConnsVisitor(comm);
         grid->accept(setConnsVisitor);
diff --git a/apps/cpu/aperm/aperm.cpp b/apps/cpu/aperm/aperm.cpp
index ecff1a453276444b706e31729012dea10597ac61..7591afe4d31c3b0c75097dd44a31477e852dbb00 100644
--- a/apps/cpu/aperm/aperm.cpp
+++ b/apps/cpu/aperm/aperm.cpp
@@ -320,7 +320,7 @@ void run(string configname)
          //////////////////////////////////////
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -467,7 +467,7 @@ void run(string configname)
          }
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/aperm/aperm.cpp.old b/apps/cpu/aperm/aperm.cpp.old
index 54dfe45fd86ff791d3965632a21acac0a3284aea..fd6f916d8155eda8719b3c8cf3382af513206989 100644
--- a/apps/cpu/aperm/aperm.cpp.old
+++ b/apps/cpu/aperm/aperm.cpp.old
@@ -285,7 +285,7 @@ void run(string configname)
          //////////////////////////////////////
 
          //set connectors
-         D3Q27InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         D3Q27InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -487,7 +487,7 @@ void run(string configname)
          }
 
          //set connectors
-         D3Q27InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         D3Q27InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/aperm/aperm.cpp.old2 b/apps/cpu/aperm/aperm.cpp.old2
index bd49f895a277a34608393a7cb53c0b6466526a95..8f0cf83e2f8ae1731dd0e76dccb4a50bddc00ba5 100644
--- a/apps/cpu/aperm/aperm.cpp.old2
+++ b/apps/cpu/aperm/aperm.cpp.old2
@@ -303,7 +303,7 @@ void run(string configname)
          //////////////////////////////////////
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -450,7 +450,7 @@ void run(string configname)
          }
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/bChannelA/bChannelA.cpp b/apps/cpu/bChannelA/bChannelA.cpp
index d50e87437b5fa17353b0f8adb298ec91ecc9d964..01725f2a3b883c0c0a53c6578dc581eadb0c8dc5 100644
--- a/apps/cpu/bChannelA/bChannelA.cpp
+++ b/apps/cpu/bChannelA/bChannelA.cpp
@@ -385,8 +385,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          ////set connectors
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -409,7 +409,7 @@ void run(string configname)
          //migCoProcessor->restart((int)restartStep);
          grid->setTimeStep(restartStep);
          ////////////////////////////////////////////////////////////////////////////
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/f16Test/f16test.cpp b/apps/cpu/f16Test/f16test.cpp
index a73949c8cef45cfa1b576070cb004041f2ac7a0f..2360d962a59015c0c73d869cd97a68d65d3afeee 100644
--- a/apps/cpu/f16Test/f16test.cpp
+++ b/apps/cpu/f16Test/f16test.cpp
@@ -571,8 +571,8 @@ void run(string configname)
          grid->accept(initVisitor);
 
          ////set connectors
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -591,7 +591,7 @@ void run(string configname)
       }
       else
       {
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/levels/levels.cpp b/apps/cpu/levels/levels.cpp
index 0fe328df129ea3f64a135f74f51e425c8d33bd52..a5ac8588023b76b3043d333e6056426147fa4689 100644
--- a/apps/cpu/levels/levels.cpp
+++ b/apps/cpu/levels/levels.cpp
@@ -208,7 +208,7 @@ void run(string configname)
 
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -290,7 +290,7 @@ void run(string configname)
          UBLOG(logINFO, "SetConnectors - start, id="<<myid);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          //D3Q27SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          SPtr<ConnectorFactory> cFactory(new Block3DConnectorFactory());
          ConnectorBlockVisitor setConnsVisitor(comm, nuLB, iProcessor, cFactory);
diff --git a/apps/cpu/mirror/mirror.cpp b/apps/cpu/mirror/mirror.cpp
index 68902fdb7d0dcb74d3eb59d884a0619c8bb0cf6b..b85d9b249ba60e10584d00ba95eda73da915ef5b 100644
--- a/apps/cpu/mirror/mirror.cpp
+++ b/apps/cpu/mirror/mirror.cpp
@@ -488,7 +488,7 @@ void run(string configname)
          grid->accept(initVisitor);
 
          ////set connectors
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -506,7 +506,7 @@ void run(string configname)
       }
       else
       {
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/mpi_benchmark/mpib.cpp b/apps/cpu/mpi_benchmark/mpib.cpp
index 6c13de98b743ad251bb1000dafc609660ca4ba46..797efbc7ed5ea87b31b30cfc3b6258a239fbd5d2 100644
--- a/apps/cpu/mpi_benchmark/mpib.cpp
+++ b/apps/cpu/mpi_benchmark/mpib.cpp
@@ -211,7 +211,7 @@ void run(string configname)
 
       //set connectors
       if (myid==0) UBLOG(logINFO, "SetConnectorsBlockVisitor:start");
-      InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+      InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
       SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nueLB, iProcessor);
       grid->accept(setConnsVisitor);
       if (myid==0) UBLOG(logINFO, "SetConnectorsBlockVisitor:end");
diff --git a/apps/cpu/pChannel/pChannel.cpp b/apps/cpu/pChannel/pChannel.cpp
index c2b32108037389ddd18351ff7092cd3d680492ea..72292679f3ef53eaf81e1f26fa54659f5b002584 100644
--- a/apps/cpu/pChannel/pChannel.cpp
+++ b/apps/cpu/pChannel/pChannel.cpp
@@ -536,7 +536,7 @@ void run(string configname)
          grid->accept(initVisitor);
 
          ////set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -559,7 +559,7 @@ void run(string configname)
          migCoProcessor->restart((int)restartStep);
          grid->setTimeStep(restartStep);
          ////////////////////////////////////////////////////////////////////////////
-         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/perm/perm.cpp b/apps/cpu/perm/perm.cpp
index 7fae63025a198a09af2a30da3776f940441dbcc2..ff0af00b8d10af2715542aaee8adf53abf633db4 100644
--- a/apps/cpu/perm/perm.cpp
+++ b/apps/cpu/perm/perm.cpp
@@ -415,7 +415,7 @@ void perm(string configname)
       }
       
       ////set connectors
-      SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
+      SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolator());
       SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
       grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/poiseuille_example/poiseuille.cpp b/apps/cpu/poiseuille_example/poiseuille.cpp
index d5de62d10edb0ddcfb7790febe494f937317f6e9..52fede221deb1dd8ffa800fae711ff8517895054 100644
--- a/apps/cpu/poiseuille_example/poiseuille.cpp
+++ b/apps/cpu/poiseuille_example/poiseuille.cpp
@@ -79,7 +79,7 @@ int main()
     grid->accept(kernelVisitor);
     interactorsHelper.setBC();
 
-    const auto interpolationProcessor(std::make_shared<CompressibleOffsetMomentsInterpolationProcessor>());
+    const auto interpolationProcessor(std::make_shared<CompressibleOffsetMomentsInterpolator>());
     interpolationProcessor->setBulkViscosity(latticeViscosity, latticeViscosity * bulkViscosityFactor);
 
     SetConnectorsBlockVisitor setConnsVisitor(communicator,
diff --git a/apps/cpu/screw/screw.cpp b/apps/cpu/screw/screw.cpp
index c1eea3f960cf6b4b64757843d08d126e4fac14b9..7ba90a58644e8d19181847dd0825abb57366daf5 100644
--- a/apps/cpu/screw/screw.cpp
+++ b/apps/cpu/screw/screw.cpp
@@ -146,8 +146,8 @@ int main(int argc, char* argv[])
          //////////////////////////////////////
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
-         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
+         //InterpolationProcessorPtr iProcessor(new CompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -220,7 +220,7 @@ int main(int argc, char* argv[])
          grid->accept(bcVisitor);
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/cpu/sphere/sphere.cpp b/apps/cpu/sphere/sphere.cpp
index 8a5ef89b8bf09e765236153f37cb259e075bf15e..1f0f5c116988f9d4bb8d068768d057db376a42d0 100644
--- a/apps/cpu/sphere/sphere.cpp
+++ b/apps/cpu/sphere/sphere.cpp
@@ -267,14 +267,14 @@ void run(string configname)
 
       UBLOG(logINFO, "SetConnectors - start, id=" << myid);
       //set connectors
-      //SPtr<InterpolationProcessor> iProcessor(new  IncompressibleOffsetInterpolationProcessor());
-      //SPtr<CompressibleOffsetMomentsInterpolationProcessor> iProcessor(new  CompressibleOffsetMomentsInterpolationProcessor());
+      //SPtr<Interpolator> iProcessor(new  IncompressibleOffsetInterpolator());
+      //SPtr<CompressibleOffsetMomentsInterpolator> iProcessor(new  CompressibleOffsetMomentsInterpolator());
       //SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nuLB, iProcessor);
 
       OneDistributionSetConnectorsBlockVisitor setConnsVisitor(comm);
       grid->accept(setConnsVisitor);
 
-      SPtr<InterpolationProcessor> iProcessor(new CompressibleOffsetMomentsInterpolationProcessor());
+      SPtr<Interpolator> iProcessor(new CompressibleOffsetMomentsInterpolator());
       SetInterpolationConnectorsBlockVisitor setInterConnsVisitor(comm, nuLB, iProcessor);
       grid->accept(setInterConnsVisitor);
 
diff --git a/apps/cpu/teperm/teperm.cpp b/apps/cpu/teperm/teperm.cpp
index aecdb3745f3da37c03b07eb7b103374a99df4302..9c4c1585ffaee5dce85eb6d1d9d0de993e033d7b 100644
--- a/apps/cpu/teperm/teperm.cpp
+++ b/apps/cpu/teperm/teperm.cpp
@@ -356,7 +356,7 @@ void run(string configname)
          //////////////////////////////////////
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
@@ -501,7 +501,7 @@ void run(string configname)
          }
 
          //set connectors
-         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolationProcessor());
+         InterpolationProcessorPtr iProcessor(new IncompressibleOffsetInterpolator());
          SetConnectorsBlockVisitor setConnsVisitor(comm, true, D3Q27System::ENDDIR, nu_LB, iProcessor);
          grid->accept(setConnsVisitor);
 
diff --git a/apps/gpu/LBM/ActuatorLine/ActuatorLine.cpp b/apps/gpu/LBM/ActuatorLine/ActuatorLine.cpp
index 368e80a726c1f6e75bd5300ad3de60fd840ba119..9c7394951e795055d22be9b155166464c998c098 100644
--- a/apps/gpu/LBM/ActuatorLine/ActuatorLine.cpp
+++ b/apps/gpu/LBM/ActuatorLine/ActuatorLine.cpp
@@ -236,21 +236,28 @@ void multipleLevel(const std::string& configPath)
     para->addActuator( actuator_farm );
 
 
-    // SPtr<PointProbe> pointProbe = std::make_shared<PointProbe>("pointProbe", para->getOutputPath(), 100, 1, 500, 100);
-    // std::vector<real> probeCoordsX = {reference_diameter,2*reference_diameter,5*reference_diameter};
-    // std::vector<real> probeCoordsY = {3*reference_diameter,3*reference_diameter,3*reference_diameter};
-    // std::vector<real> probeCoordsZ = {3*reference_diameter,3*reference_diameter,3*reference_diameter};
-    // pointProbe->addProbePointsFromList(probeCoordsX, probeCoordsY, probeCoordsZ);
-    // // pointProbe->addProbePointsFromXNormalPlane(2*D, 0.0, 0.0, L_y, L_z, (uint)L_y/dx, (uint)L_z/dx);
-
-    // pointProbe->addStatistic(Statistic::Means);
-    // pointProbe->addStatistic(Statistic::Variances);
-    // para->addProbe( pointProbe );
-
-    // SPtr<PlaneProbe> planeProbe = std::make_shared<PlaneProbe>("planeProbe", para->getOutputPath(), 100, 500, 100, 100);
-    // planeProbe->setProbePlane(5*reference_diameter, 0, 0, dx, L_y, L_z);
-    // planeProbe->addStatistic(Statistic::Means);
-    // para->addProbe( planeProbe );
+    SPtr<PointProbe> pointProbe = std::make_shared<PointProbe>("pointProbe", para->getOutputPath(), 100, 1, 500, 100, false);
+    std::vector<real> probeCoordsX = {reference_diameter,2*reference_diameter,5*reference_diameter};
+    std::vector<real> probeCoordsY = {3*reference_diameter,3*reference_diameter,3*reference_diameter};
+    std::vector<real> probeCoordsZ = {3*reference_diameter,3*reference_diameter,3*reference_diameter};
+
+    pointProbe->addProbePointsFromList(probeCoordsX, probeCoordsY, probeCoordsZ);
+    // pointProbe->addProbePointsFromXNormalPlane(2*D, 0.0, 0.0, L_y, L_z, (uint)L_y/dx, (uint)L_z/dx);
+
+    pointProbe->addStatistic(Statistic::Means);
+    pointProbe->addStatistic(Statistic::Variances);
+    para->addProbe( pointProbe );
+
+    SPtr<PointProbe> timeseriesProbe = std::make_shared<PointProbe>("timeProbe", para->getOutputPath(), 100, 1, 500, 100, true);
+    timeseriesProbe->addProbePointsFromList(probeCoordsX, probeCoordsY, probeCoordsZ);
+    timeseriesProbe->addStatistic(Statistic::Instantaneous);
+    timeseriesProbe->addStatistic(Statistic::Means);
+    para->addProbe( timeseriesProbe );
+
+    SPtr<PlaneProbe> planeProbe = std::make_shared<PlaneProbe>("planeProbe", para->getOutputPath(), 100, 500, 100, 100);
+    planeProbe->setProbePlane(5*reference_diameter, 0, 0, dx, L_y, L_z);
+    planeProbe->addStatistic(Statistic::Means);
+    para->addProbe( planeProbe );
 
 
     auto cudaMemoryManager = std::make_shared<CudaMemoryManager>(para);
diff --git a/apps/gpu/LBM/BoundaryLayer/configBoundaryLayer.txt b/apps/gpu/LBM/BoundaryLayer/configBoundaryLayer.txt
index 83e7861a5fb85ea800d187699f1c6c1409422f0a..1b415aa6ce14109c2d93a17ae78463786a7b7608 100644
--- a/apps/gpu/LBM/BoundaryLayer/configBoundaryLayer.txt
+++ b/apps/gpu/LBM/BoundaryLayer/configBoundaryLayer.txt
@@ -23,8 +23,7 @@ Ma = 0.1
 nz = 96 
 
 bodyForce = true
-UseAMD = true
-SGSconstant = 0.2
+TurbulenceModel = QR
 QuadricLimiterP = 100000.0
 QuadricLimiterM = 100000.0
 QuadricLimiterD = 100000.0
diff --git a/apps/gpu/LBM/DrivenCavityMultiGPU/DrivenCavityMultiGPU.cpp b/apps/gpu/LBM/DrivenCavityMultiGPU/DrivenCavityMultiGPU.cpp
index d7f6dace74a07ba8477085b94f2146cf4500d7d1..d6b6703659aaca6d254a1fc2f7692be4e9f22593 100755
--- a/apps/gpu/LBM/DrivenCavityMultiGPU/DrivenCavityMultiGPU.cpp
+++ b/apps/gpu/LBM/DrivenCavityMultiGPU/DrivenCavityMultiGPU.cpp
@@ -517,7 +517,7 @@ int main(int argc, char *argv[])
 
         try {
             VF_LOG_TRACE("For the default config path to work, execute the app from the project root.");
-            vf::basics::ConfigurationFile config = vf::basics::ConfigurationFile::loadConfig(argc, argv, "./apps/gpu/LBM/DrivenCavityMultiGPU/configDrivenCavityMultiGPU.txt");
+            vf::basics::ConfigurationFile config = vf::basics::loadConfig(argc, argv, "./apps/gpu/LBM/DrivenCavityMultiGPU/configDrivenCavityMultiGPU.txt");
             runVirtualFluids(config);
 
             //////////////////////////////////////////////////////////////////////////
diff --git a/apps/gpu/LBM/DrivenCavityMultiGPU/configPhoenix4GPU_regressionTest.txt b/apps/gpu/LBM/DrivenCavityMultiGPU/configPhoenix4GPU_regressionTest.txt
index c5789cdf96049b7c0a31ce693c29cd2db4952a58..9b8c6e42de49997cc218a2a0ee6f832b903d142b 100644
--- a/apps/gpu/LBM/DrivenCavityMultiGPU/configPhoenix4GPU_regressionTest.txt
+++ b/apps/gpu/LBM/DrivenCavityMultiGPU/configPhoenix4GPU_regressionTest.txt
@@ -1,7 +1,7 @@
 ##################################################
 #GPU Mapping
 ##################################################
-Devices="0 1 2 3"
+Devices=0 1 2 3
 NumberOfDevices=4
 
 ##################################################
diff --git a/apps/gpu/LBM/DrivenCavityMultiGPU/configPhoenix8GPU_regressionTest.txt b/apps/gpu/LBM/DrivenCavityMultiGPU/configPhoenix8GPU_regressionTest.txt
index c5789cdf96049b7c0a31ce693c29cd2db4952a58..9b8c6e42de49997cc218a2a0ee6f832b903d142b 100644
--- a/apps/gpu/LBM/DrivenCavityMultiGPU/configPhoenix8GPU_regressionTest.txt
+++ b/apps/gpu/LBM/DrivenCavityMultiGPU/configPhoenix8GPU_regressionTest.txt
@@ -1,7 +1,7 @@
 ##################################################
 #GPU Mapping
 ##################################################
-Devices="0 1 2 3"
+Devices=0 1 2 3
 NumberOfDevices=4
 
 ##################################################
diff --git a/apps/gpu/LBM/MusselOyster/MusselOyster.cpp b/apps/gpu/LBM/MusselOyster/MusselOyster.cpp
index 1cff9cf2675fbe9d42f4765c6c9e1bcea4bd7065..5a5830d442ff83e33208ddee226e9ea34c84a2ef 100644
--- a/apps/gpu/LBM/MusselOyster/MusselOyster.cpp
+++ b/apps/gpu/LBM/MusselOyster/MusselOyster.cpp
@@ -584,7 +584,7 @@ int main(int argc, char *argv[])
 
         try {
             VF_LOG_TRACE("For the default config path to work, execute the app from the project root.");
-            vf::basics::ConfigurationFile config = vf::basics::ConfigurationFile::loadConfig(argc, argv, "./apps/gpu/LBM/MusselOyster/configMusselOyster.txt");
+            vf::basics::ConfigurationFile config = vf::basics::loadConfig(argc, argv, "./apps/gpu/LBM/MusselOyster/configMusselOyster.txt");
             runVirtualFluids(config);
 
             //////////////////////////////////////////////////////////////////////////
diff --git a/apps/gpu/LBM/SphereGPU/Sphere.cpp b/apps/gpu/LBM/SphereGPU/Sphere.cpp
index f70188bbd81a22088affbbc45d43dafdd418fe46..7794217f4e42f79070b1037c86b3e74b1f94d967 100644
--- a/apps/gpu/LBM/SphereGPU/Sphere.cpp
+++ b/apps/gpu/LBM/SphereGPU/Sphere.cpp
@@ -103,7 +103,7 @@ int main(int argc, char *argv[])
         vf::basics::ConfigurationFile config;
         if (useConfigFile) {
             VF_LOG_TRACE("For the default config path to work, execute the app from the project root.");
-            vf::basics::ConfigurationFile config = vf::basics::ConfigurationFile::loadConfig(argc, argv, "./apps/gpu/LBM/SphereGPU/config.txt");
+            vf::basics::ConfigurationFile config = vf::basics::loadConfig(argc, argv, "./apps/gpu/LBM/SphereGPU/config.txt");
             para = std::make_shared<Parameter>(&config);
         } else {
             para = std::make_shared<Parameter>();
diff --git a/apps/gpu/LBM/SphereScaling/SphereScaling.cpp b/apps/gpu/LBM/SphereScaling/SphereScaling.cpp
index e4291f81a288528397246f2fb56f95aa3c04ac0c..a5ed466c94cb8a3c40e8dcb87cc6a15b843a3d2c 100755
--- a/apps/gpu/LBM/SphereScaling/SphereScaling.cpp
+++ b/apps/gpu/LBM/SphereScaling/SphereScaling.cpp
@@ -658,7 +658,7 @@ int main(int argc, char *argv[])
 
         try {
             VF_LOG_INFO("For the default config path to work, execute the app from the project root.");
-            vf::basics::ConfigurationFile config = vf::basics::ConfigurationFile::loadConfig(argc, argv, "./apps/gpu/LBM/SphereScaling/config.txt");
+            vf::basics::ConfigurationFile config = vf::basics::loadConfig(argc, argv, "./apps/gpu/LBM/SphereScaling/config.txt");
             runVirtualFluids(config);
 
             //////////////////////////////////////////////////////////////////////////
diff --git a/apps/gpu/LBM/SphereScaling/configPhoenix4GPU_regressionTest.txt b/apps/gpu/LBM/SphereScaling/configPhoenix4GPU_regressionTest.txt
index c5789cdf96049b7c0a31ce693c29cd2db4952a58..9b8c6e42de49997cc218a2a0ee6f832b903d142b 100644
--- a/apps/gpu/LBM/SphereScaling/configPhoenix4GPU_regressionTest.txt
+++ b/apps/gpu/LBM/SphereScaling/configPhoenix4GPU_regressionTest.txt
@@ -1,7 +1,7 @@
 ##################################################
 #GPU Mapping
 ##################################################
-Devices="0 1 2 3"
+Devices=0 1 2 3
 NumberOfDevices=4
 
 ##################################################
diff --git a/apps/gpu/LBM/SphereScaling/configPhoenix8GPU_regressionTest.txt b/apps/gpu/LBM/SphereScaling/configPhoenix8GPU_regressionTest.txt
index c5789cdf96049b7c0a31ce693c29cd2db4952a58..9b8c6e42de49997cc218a2a0ee6f832b903d142b 100644
--- a/apps/gpu/LBM/SphereScaling/configPhoenix8GPU_regressionTest.txt
+++ b/apps/gpu/LBM/SphereScaling/configPhoenix8GPU_regressionTest.txt
@@ -1,7 +1,7 @@
 ##################################################
 #GPU Mapping
 ##################################################
-Devices="0 1 2 3"
+Devices=0 1 2 3
 NumberOfDevices=4
 
 ##################################################
diff --git a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/ListOfLists/MathematicaListOfListsImp.cpp b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/ListOfLists/MathematicaListOfListsImp.cpp
index 58a4128fbd1ae54f59c625cb7b7ca4f851885962..6821f270428a32c2b579174a6c3e1662d0ccc55b 100644
--- a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/ListOfLists/MathematicaListOfListsImp.cpp
+++ b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/ListOfLists/MathematicaListOfListsImp.cpp
@@ -1,6 +1,7 @@
 #include "MathematicaListOfListsImp.h"
 
 #include <iomanip>
+#include <limits>
 
 std::shared_ptr<MathematicaListOfLists> MathematicaListOfListsImp::getNewInstance(std::string listName, std::vector<std::vector<double>> listOfLists)
 {
diff --git a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/ListOfLists/MathematicaListOfListsImp.h b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/ListOfLists/MathematicaListOfListsImp.h
index ba19ba20dde6f9810f1003fb56964c9915cb425b..a1e82892ca92fc8b3b484440edb30bfbf957d965 100644
--- a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/ListOfLists/MathematicaListOfListsImp.h
+++ b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/ListOfLists/MathematicaListOfListsImp.h
@@ -1,5 +1,5 @@
 #ifndef MATHEMATICA_LIST_OF_LISTS_IMP_H
-#define MATHEMATICA_LIST_OF_LISTS_IMÜ_H
+#define MATHEMATICA_LIST_OF_LISTS_IMP_H
 
 #include "MathematicaListOfLists.h"
 
diff --git a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/PointList/MathematicaPointListImp.cpp b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/PointList/MathematicaPointListImp.cpp
index 6689d5f14ad94cad908584c2847cc02536df60a6..cd00dddf194903666dc36abba86985c0a643d310 100644
--- a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/PointList/MathematicaPointListImp.cpp
+++ b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/MathematicaFunction/PointList/MathematicaPointListImp.cpp
@@ -4,6 +4,7 @@
 #include "MathematicaPointList.h"
 
 #include <iomanip>
+#include <limits>
 
 std::shared_ptr<MathematicaPointList> MathematicaPointListImp::getNewInstance(std::string listName, std::vector<std::shared_ptr<DataPoint> > plotData)
 {
diff --git a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReader.h b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReader.h
index 4ac2f917f904f32a80427514bffeeccc4dce53e9..21ee18ef262a24ed5ba978c9f1623ebc0ce5a286 100644
--- a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReader.h
+++ b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReader.h
@@ -9,6 +9,7 @@ class PostProcessingConfigData;
 class PostProcessingConfigFileReader
 {
 public:
+	virtual ~PostProcessingConfigFileReader() = default;
 	virtual std::shared_ptr<PostProcessingConfigData> readConfigFile(std::string filePath) = 0;
 };
 #endif
\ No newline at end of file
diff --git a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReaderImp.cpp b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReaderImp.cpp
index 6c52eeb93f3e556ebfad4e993eb56c63c95b56fd..968af578a868b9e2655f4062d89fda8fed37941b 100644
--- a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReaderImp.cpp
+++ b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReaderImp.cpp
@@ -64,7 +64,3 @@ std::shared_ptr<PostProcessingConfigData> PostProcessingConfigFileReaderImp::rea
 	
 	return data;
 }
-
-PostProcessingConfigFileReaderImp::PostProcessingConfigFileReaderImp()
-{
-}
diff --git a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReaderImp.h b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReaderImp.h
index a47d53820807a6ac2fada77d7cb7efc09f658e07..e5355a708adb753e78089a68dc9f889df9a83fc5 100644
--- a/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReaderImp.h
+++ b/apps/gpu/tests/NumericalTestPostProcessing/Utilities/PostProcessingConfigFileReader/PostProcessingConfigFileReaderImp.h
@@ -8,10 +8,10 @@ class PostProcessingConfigFileReaderImp : public PostProcessingConfigFileReader
 public:
 	static std::shared_ptr<PostProcessingConfigFileReader> getNewInstance();
 
-	std::shared_ptr<PostProcessingConfigData> readConfigFile(std::string filePath);
+	std::shared_ptr<PostProcessingConfigData> readConfigFile(std::string filePath) override;
 
 private:
-	PostProcessingConfigFileReaderImp();
+	PostProcessingConfigFileReaderImp() = default;
 
 };
 #endif
\ No newline at end of file
diff --git a/apps/gpu/tests/NumericalTestPostProcessing/main.cpp b/apps/gpu/tests/NumericalTestPostProcessing/main.cpp
index bf88ad153d49bea167e148bab1abba8fa760b70f..e5dbeef9c7d3928c039049627129689ab92c653b 100644
--- a/apps/gpu/tests/NumericalTestPostProcessing/main.cpp
+++ b/apps/gpu/tests/NumericalTestPostProcessing/main.cpp
@@ -39,12 +39,12 @@ int main(int argc, char **argv)
 	std::shared_ptr<MathematicaAssistantFactory> assistantFactory = MathematicaAssistantFactoryImp::getNewInstance();
 	std::vector<std::shared_ptr<MathematicaAssistant> > mathematicaAssistants = assistantFactory->makeMathematicaAssistants(configData->getAssistants(), functionFactory);
 
-	for (int sim = 0; sim < configData->getSimulations().size(); sim++) {
-		for (int comb = 0; comb < configData->getDataCombinations().size(); comb++) {
+	for (uint sim = 0; sim < configData->getSimulations().size(); sim++) {
+		for (uint comb = 0; comb < configData->getDataCombinations().size(); comb++) {
 			std::shared_ptr<LogFileDataAssistantStrategy> strategy = assistentStrategyFactory->makeLogFileDataAssistantStrategy(configData->getSimulations().at(sim));
 			std::vector<std::shared_ptr<LogFileDataGroup> > logFileDataSorted = assistentLogFile->findDataCombination(logFileDataVector, strategy, configData->getDataCombinations().at(comb));
-			for (int i = 0; i < logFileDataSorted.size(); i++) {
-				for (int j = 0; j < mathematicaAssistants.size(); j++)
+			for (uint i = 0; i < logFileDataSorted.size(); i++) {
+				for (uint j = 0; j < mathematicaAssistants.size(); j++)
 					mathematicaAssistants.at(j)->makeMathematicaOutput(logFileDataSorted.at(i), aMathmaticaFile);
 			}
 		}
diff --git a/apps/gpu/tests/NumericalTests/Tests/PhiTest/PhiTest.cpp b/apps/gpu/tests/NumericalTests/Tests/PhiTest/PhiTest.cpp
index bf93a95f450ff1a21062644d9be098eb2c2c235f..a8a4a4df2e4d04564dbeb2a881cebd95ce6a1a9f 100644
--- a/apps/gpu/tests/NumericalTests/Tests/PhiTest/PhiTest.cpp
+++ b/apps/gpu/tests/NumericalTests/Tests/PhiTest/PhiTest.cpp
@@ -17,7 +17,7 @@ std::shared_ptr<PhiTest> PhiTest::getNewInstance(std::shared_ptr<ColorConsoleOut
 
 void PhiTest::evaluate()
 {
-	for (int i = 0; i < postProStrategies.size(); i++)
+	for (uint i = 0; i < postProStrategies.size(); i++)
 		phiDiff.push_back(postProStrategies.at(i)->getPhiDiff(dataToCalculate));
 	
 	orderOfAccuracy = calcOrderOfAccuracy(phiDiff);
@@ -46,7 +46,7 @@ std::string PhiTest::getDataToCalculate()
 std::vector<int> PhiTest::getLx()
 {
 	std::vector<int> lxINT;
-	for (int i = 0; i < lx.size(); i++)
+	for (uint i = 0; i < lx.size(); i++)
 		lxINT.push_back((int)lx.at(i));
 	return lxINT;
 }
@@ -62,7 +62,7 @@ double PhiTest::getOrderOfAccuracy()
 }
 
 PhiTest::PhiTest(std::shared_ptr<ColorConsoleOutput> colorOutput, double viscosity, std::shared_ptr<PhiTestParameterStruct> testPara, std::string dataToCalculate)
-	: TestImp(colorOutput), viscosity(viscosity), dataToCalculate(dataToCalculate)
+	: TestImp(colorOutput), dataToCalculate(dataToCalculate)
 {
 	minOrderOfAccuracy = testPara->minOrderOfAccuracy;
 	startStepCalculation = testPara->startTimeStepCalculation;
@@ -92,7 +92,7 @@ std::vector<std::string> PhiTest::buildTestOutput()
 	std::vector<std::string> output = buildBasicTestOutput();
 	std::ostringstream oss;
 
-	for (int i = 0; i < phiDiff.size(); i++) {
+	for (uint i = 0; i < phiDiff.size(); i++) {
 		oss << "PhiDiff" << simInfos.at(i)->getLx() << ": " << phiDiff.at(i);
 		output.push_back(oss.str());
 		oss.str(std::string());
@@ -125,7 +125,7 @@ std::vector<std::string> PhiTest::buildBasicTestOutput()
 	output.push_back(oss.str());
 	oss.str(std::string());
 
-	for (int i = 0; i < simInfos.size(); i++) {
+	for (uint i = 0; i < simInfos.size(); i++) {
 		oss << "L: " << std::setfill(' ') << std::right << std::setw(4) << simInfos.at(i)->getLx() << simInfos.at(i)->getSimulationParameterString();
 		output.push_back(oss.str());
 		oss.str(std::string());
diff --git a/apps/gpu/tests/NumericalTests/Tests/PhiTest/PhiTest.h b/apps/gpu/tests/NumericalTests/Tests/PhiTest/PhiTest.h
index 84b1d33896a89834460c9d8495f1e068a2221364..4bf1c02f85e35b9cf1766642b6a0e9b58e6b4d07 100644
--- a/apps/gpu/tests/NumericalTests/Tests/PhiTest/PhiTest.h
+++ b/apps/gpu/tests/NumericalTests/Tests/PhiTest/PhiTest.h
@@ -40,7 +40,6 @@ private:
 	std::vector<double> phiDiff;
 	double orderOfAccuracy;
 	double minOrderOfAccuracy;
-	double viscosity;
 	std::string dataToCalculate;
 
 	std::vector<std::shared_ptr<PhiTestPostProcessingStrategy> > postProStrategies;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/Calculator/L2NormCalculator/L2NormCalculator.h b/apps/gpu/tests/NumericalTests/Utilities/Calculator/L2NormCalculator/L2NormCalculator.h
index 21ab49017188b92a97ea59a53d7ce28e51a694a8..5c90fa1ae0fe1332608d2932f2fa40435bb21fc5 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/Calculator/L2NormCalculator/L2NormCalculator.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/Calculator/L2NormCalculator/L2NormCalculator.h
@@ -8,6 +8,7 @@
 class L2NormCalculator
 {
 public:
+	virtual ~L2NormCalculator() = default;
 	virtual double calc(std::vector<double> basicData, std::vector<double> divergentData, std::vector<unsigned int> level, double lx, double lz, double l0) = 0;
 	virtual std::string getErrorMessage() = 0;
 
diff --git a/apps/gpu/tests/NumericalTests/Utilities/Calculator/L2NormCalculator/L2NormCalculatorFactory/L2NormCalculatorFactory.h b/apps/gpu/tests/NumericalTests/Utilities/Calculator/L2NormCalculator/L2NormCalculatorFactory/L2NormCalculatorFactory.h
index 2b13f7ca3ca1337d8cbd7181ce4fc556e831a248..ffd1030cfa2abf8fb8b82699fe209dcf4e2416de 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/Calculator/L2NormCalculator/L2NormCalculatorFactory/L2NormCalculatorFactory.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/Calculator/L2NormCalculator/L2NormCalculatorFactory/L2NormCalculatorFactory.h
@@ -9,6 +9,7 @@ class L2NormCalculator;
 class L2NormCalculatorFactory
 {
 public:
+	virtual ~L2NormCalculatorFactory() = default;
 	virtual std::shared_ptr<L2NormCalculator> makeL2NormCalculator(std::string type) = 0;
 
 };
diff --git a/apps/gpu/tests/NumericalTests/Utilities/ColorConsoleOutput/ColorConsoleOutput.h b/apps/gpu/tests/NumericalTests/Utilities/ColorConsoleOutput/ColorConsoleOutput.h
index 73b5dff2a02af7a60d3bccc9df6c0ec90c8c5940..5c9f03658f40e77cdd9d8ce8f82d3cd08e2c02d6 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/ColorConsoleOutput/ColorConsoleOutput.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/ColorConsoleOutput/ColorConsoleOutput.h
@@ -12,6 +12,7 @@ class SimulationInfo;
 class ColorConsoleOutput
 {
 public:
+	virtual ~ColorConsoleOutput() = default;
 	virtual void makeSimulationHeadOutput(std::shared_ptr<SimulationInfo> simInfo) = 0;
 	virtual void makeTestOutput(std::vector<std::string> testOutput, TestStatus status) = 0;
 	virtual void makeFinalTestOutputHead(int numberOfTests, int numberOfExecutedTest, int numberOfPassedTest, int numberOfFailedTest, int numberOfErrorTest, int numberOfNotExecutedTest) = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriter.h b/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriter.h
index 3af764aeeaa8b6f29831ead54b1f312d3be54e9f..a6e1eecf4a976e8c8e6a34c34f8b1e5e08887fd1 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriter.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriter.h
@@ -10,7 +10,7 @@ class AnalyticalResults;
 class AnalyticalResults2DToVTKWriter
 {
 public:
-
+	virtual ~AnalyticalResults2DToVTKWriter() = default;
 	virtual void writeAnalyticalResult(std::shared_ptr<Parameter> para, std::shared_ptr<AnalyticalResults> analyticalResult) = 0;
 
 };
diff --git a/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriterImp.cpp b/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriterImp.cpp
index 126ff07a31c4f434cc82b4bb8b7e1d944b22cae1..15032a8fd4ec6ce8f7684c33ceae0085d92f54c4 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriterImp.cpp
+++ b/apps/gpu/tests/NumericalTests/Utilities/DataWriter/AnalyticalResults2DToVTKWriter/AnalyticalResults2DToVTKWriterImp.cpp
@@ -40,7 +40,7 @@ void AnalyticalResults2DToVTKWriterImp::writeAnalyticalResult(std::shared_ptr<Pa
         for (int level = para->getCoarse(); level <= para->getFine(); level++) {
 #pragma omp parallel for
             for (int timeStep = 0; timeStep < analyticalResult->getNumberOfTimeSteps(); timeStep++) {
-                const unsigned int numberOfParts = para->getParH(level)->size_Mat / para->getlimitOfNodesForVTK() + 1;
+                const unsigned int numberOfParts = para->getParH(level)->size_Mat / para->getLimitOfNodesForVTK() + 1;
                 std::vector<std::string> fname;
                 unsigned int time =
                     analyticalResult->getTimeSteps().at(timeStep) * analyticalResult->getTimeStepLength();
@@ -93,13 +93,13 @@ void AnalyticalResults2DToVTKWriterImp::writeTimeStep(std::shared_ptr<Parameter>
     std::vector<double> vz = analyticalResult->getVz()[timeStep];
 
     for (unsigned int part = 0; part < fname.size(); part++) {
-        if (((part + 1) * para->getlimitOfNodesForVTK()) > para->getParH(level)->size_Mat)
-            sizeOfNodes = para->getParH(level)->size_Mat - (part * para->getlimitOfNodesForVTK());
+        if (((part + 1) * para->getLimitOfNodesForVTK()) > para->getParH(level)->size_Mat)
+            sizeOfNodes = para->getParH(level)->size_Mat - (part * para->getLimitOfNodesForVTK());
         else
-            sizeOfNodes = para->getlimitOfNodesForVTK();
+            sizeOfNodes = para->getLimitOfNodesForVTK();
 
         //////////////////////////////////////////////////////////////////////////
-        startpos = part * para->getlimitOfNodesForVTK();
+        startpos = part * para->getLimitOfNodesForVTK();
         endpos = startpos + sizeOfNodes;
         //////////////////////////////////////////////////////////////////////////
         cells.clear();
diff --git a/apps/gpu/tests/NumericalTests/Utilities/InitialCondition/InitialCondition.h b/apps/gpu/tests/NumericalTests/Utilities/InitialCondition/InitialCondition.h
index 0735f39696efe134393f6fca66a5d318d59bcb13..1c9b322a29c80c28173d5791adc75e3756f22bbc 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/InitialCondition/InitialCondition.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/InitialCondition/InitialCondition.h
@@ -11,6 +11,7 @@ class Parameter;
 class InitialCondition
 {
 public:
+	virtual ~InitialCondition() = default;
 	virtual void setParameter(std::shared_ptr<Parameter> para) = 0;
 	virtual void init(const int level) = 0;
 	virtual real getInitVX(int i, int level) = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/KernelConfiguration/KernelConfiguration.h b/apps/gpu/tests/NumericalTests/Utilities/KernelConfiguration/KernelConfiguration.h
index dbcb9b003579b34be5f5a6be09154d3762576086..7407fe4cc33da0a929d090a30878b8fe628f03bf 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/KernelConfiguration/KernelConfiguration.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/KernelConfiguration/KernelConfiguration.h
@@ -7,7 +7,8 @@
 class KernelConfiguration
 {
 public:
-    virtual std::string getMainKernel()              = 0;
+    virtual ~KernelConfiguration() = default;
+    virtual std::string getMainKernel() = 0;
 	virtual bool getMultiKernelOn() = 0;
 	virtual	std::vector<int> getMultiKernelLevel() = 0;
     virtual std::vector<std::string> getMultiKernel() = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/BasicSimulationInfo/BasicSimulationInfo.h b/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/BasicSimulationInfo/BasicSimulationInfo.h
index 20897bc5f8de3c94f7659b67b4ba6bdb3598d958..a8f14cab134f821b5dd46116e2b690779cab8176 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/BasicSimulationInfo/BasicSimulationInfo.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/BasicSimulationInfo/BasicSimulationInfo.h
@@ -12,7 +12,7 @@ public:
 	std::string getOutput();
 
 private:
-	BasicSimulationInfo() {};
+	BasicSimulationInfo() = default;
     BasicSimulationInfo(int numberOfTimeSteps, double viscosity, int basicTimeStepLength, std::string kernel);
 
 	int numberOfTimeSteps;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/LogFileInformation.h b/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/LogFileInformation.h
index 6c035169a8d74cd51aa0e94281b2f01bf3b4fc33..b234c86551603df780613da31b07aa5836f528d0 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/LogFileInformation.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/LogFileInformation.h
@@ -1,11 +1,12 @@
 #ifndef LOGFILE_INFORMATION_H
 #define LOGFILE_INFORMATION_H
 
-#include <iostream>
+#include <string>
 
 class LogFileInformation
 {
 public:
+	virtual ~LogFileInformation() = default;
 	virtual std::string getOutput() = 0;
 
 private:
diff --git a/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/LogFileInformationImp.h b/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/LogFileInformationImp.h
index 83c4cff969f8910cabdd4ef4f57c8ef3f8fe8925..c89decfe90014d2090a6d9a89ec3b8d79d49ce8d 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/LogFileInformationImp.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/LogFileInformationImp.h
@@ -8,6 +8,7 @@
 class LogFileInformationImp : public LogFileInformation
 {
 public:
+	LogFileInformationImp() = default;
 	virtual std::string getOutput() = 0;
 
 protected:
diff --git a/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/SimulationLogFileInformation/SimulationLogFileInformation.h b/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/SimulationLogFileInformation/SimulationLogFileInformation.h
index ce72f8f124a1273e9c2124e2ea30b9a055237733..45a41cc1f43eae3d1fa6fb17457b77a83826e7d6 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/SimulationLogFileInformation/SimulationLogFileInformation.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/LogFileInformation/SimulationLogFileInformation/SimulationLogFileInformation.h
@@ -9,6 +9,7 @@
 class SimulationLogFileInformation : public LogFileInformationImp
 {
 public:
+	virtual ~SimulationLogFileInformation() = default;
 	virtual std::string getOutput() = 0;
 
 	virtual std::vector<std::string> getFilePathExtension() = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueue.h b/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueue.h
index cb8c413d13769551ef2b9c23592d02f03f14c291..013d553901a93328fbd5f44c0b035ecd24b49d3e 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueue.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueue.h
@@ -1,13 +1,10 @@
 #ifndef LOGFILE_QUEUE_H
 #define LOGFILE_QUEUE_H
 
-#include <memory>
-
-class LogFileWriter;
-
 class LogFileQueue
 {
 public:
+	virtual ~LogFileQueue() = default;
 	virtual void writeLogFiles() = 0;
 
 private:
diff --git a/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueueImp.cpp b/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueueImp.cpp
index 9decb8a93ccaa3bf8e1b198bb646f4f499ada72f..fa6b0b2b5a6c7e296dd4dc3b9034c027c416cbc5 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueueImp.cpp
+++ b/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueueImp.cpp
@@ -13,7 +13,7 @@ std::shared_ptr<LogFileQueueImp> LogFileQueueImp::getNewInstance(std::string bas
 
 void LogFileQueueImp::writeLogFiles()
 {
-	for (int i = 0; i < logFileWriter.size(); i++){
+	for (uint i = 0; i < logFileWriter.size(); i++){
 		logFileWriter.at(i)->writeLogFile(basicLogFilePath);
 	}
 }
diff --git a/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueueImp.h b/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueueImp.h
index 3fe27faeb0d8f48bf087c76fb8c57c36cb0a4bb1..133924382995d2a91abfbb51185bccdd7fe33e63 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueueImp.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/LogFileQueue/LogFileQueueImp.h
@@ -5,17 +5,20 @@
 
 #include <string>
 #include <vector>
+#include <memory>
+
+class LogFileWriter;
 
 class LogFileQueueImp : public LogFileQueue 
 {
 public:
 	static std::shared_ptr<LogFileQueueImp> getNewInstance(std::string basicLogFilePath);
 
-	void writeLogFiles();
+	void writeLogFiles() override;
 	void addLogFileWriter(std::shared_ptr<LogFileWriter> aLogFileWriter);
 
 private:
-	LogFileQueueImp() {};
+	LogFileQueueImp() = default;
 	LogFileQueueImp(std::string basicLogFilePath);
 
 	std::string calcDateAndTime();
diff --git a/apps/gpu/tests/NumericalTests/Utilities/LogFileWriter/LogFileWriter.h b/apps/gpu/tests/NumericalTests/Utilities/LogFileWriter/LogFileWriter.h
index d828256c677e1fece336845de68fb1fc3d3868df..396deec9d1a771fd74e9ca7f3e23910a6c9c7fcb 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/LogFileWriter/LogFileWriter.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/LogFileWriter/LogFileWriter.h
@@ -6,6 +6,7 @@
 class LogFileWriter
 {
 public:
+	virtual ~LogFileWriter() = default;
 	virtual void writeLogFile(std::string basicFilePath) = 0;
 	
 private:
diff --git a/apps/gpu/tests/NumericalTests/Utilities/NumericalTestFactory/NumericalTestFactory.h b/apps/gpu/tests/NumericalTests/Utilities/NumericalTestFactory/NumericalTestFactory.h
index b5facb26a1dd1e2e0439a415fae2c692340449fe..d21deb7bda97df58830ec9f4dc3dcb8445915911 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/NumericalTestFactory/NumericalTestFactory.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/NumericalTestFactory/NumericalTestFactory.h
@@ -12,6 +12,7 @@ class LogFileQueue;
 class NumericalTestFactory
 {
 public:
+	virtual ~NumericalTestFactory() = default;
 	virtual std::vector<std::shared_ptr<TestSimulation> > getTestSimulations() = 0;
 	virtual std::shared_ptr<TestQueue> getTestQueue() = 0;
 	virtual std::shared_ptr<LogFileQueue> getLogFileQueue() = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/NumericalTestFactory/NumericalTestFactoryImp.h b/apps/gpu/tests/NumericalTests/Utilities/NumericalTestFactory/NumericalTestFactoryImp.h
index 1d9b33d357406de2e94c6eb7f2ef9a570ce59e21..ff9753a4afde382e48fc8d07a8763f26f4c6b23d 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/NumericalTestFactory/NumericalTestFactoryImp.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/NumericalTestFactory/NumericalTestFactoryImp.h
@@ -93,7 +93,7 @@ private:
 
 	int simID;
 	int numberOfSimulations;
-	int simPerKernel, numberOfTestGroupsBetweenKernels, numberOfTestsForOneSimulation, numberOfTestsBetweenKernels;
-	int posBasicSimulationForL2Test, posDivergentSimulationForL2Test;
+	// int simPerKernel, numberOfTestGroupsBetweenKernels, numberOfTestsForOneSimulation, numberOfTestsBetweenKernels;
+	// int posBasicSimulationForL2Test, posDivergentSimulationForL2Test;
 };
-#endif
\ No newline at end of file
+#endif
diff --git a/apps/gpu/tests/NumericalTests/Utilities/NumericalTestGridReader/NumericalTestGridReader.cpp b/apps/gpu/tests/NumericalTests/Utilities/NumericalTestGridReader/NumericalTestGridReader.cpp
index cdf82c32ef982dec19df49ae347e5601017a538b..b0368e4e4215aca06cda79faf47403d7a2650f8d 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/NumericalTestGridReader/NumericalTestGridReader.cpp
+++ b/apps/gpu/tests/NumericalTests/Utilities/NumericalTestGridReader/NumericalTestGridReader.cpp
@@ -13,7 +13,7 @@ std::shared_ptr<NumericalTestGridReader> NumericalTestGridReader::getNewInstance
 	return std::shared_ptr<NumericalTestGridReader>(new NumericalTestGridReader(para, initialCondition, cudaManager));
 }
 
-void NumericalTestGridReader::setInitalNodeValues(uint numberOfNodes, int level) const
+void NumericalTestGridReader::setInitialNodeValues(uint numberOfNodes, int level) const
 {
 	initialCondition->init(level);
 	for (uint j = 0; j <= numberOfNodes; j++){
diff --git a/apps/gpu/tests/NumericalTests/Utilities/NumericalTestGridReader/NumericalTestGridReader.h b/apps/gpu/tests/NumericalTests/Utilities/NumericalTestGridReader/NumericalTestGridReader.h
index 84f5d72705db06349f0b31a42eb99ded45bb0e1d..99363655817874672eaf5b898fb087cb20effb02 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/NumericalTestGridReader/NumericalTestGridReader.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/NumericalTestGridReader/NumericalTestGridReader.h
@@ -13,7 +13,7 @@ public:
 	static std::shared_ptr<NumericalTestGridReader> getNewInstance(std::shared_ptr<Parameter> para, std::shared_ptr<InitialCondition> initialCondition, std::shared_ptr<CudaMemoryManager> cudaManager);
 
 protected:
-	virtual void setInitalNodeValues(uint numberOfNodes, int level) const override;
+	virtual void setInitialNodeValues(uint numberOfNodes, int level) const override;
     
 private:
 	NumericalTestGridReader(std::shared_ptr<Parameter> para, std::shared_ptr<InitialCondition> initialCondition, std::shared_ptr<CudaMemoryManager> cudaManager);
diff --git a/apps/gpu/tests/NumericalTests/Utilities/NumericalTestSimulation/NumericalTestSimulation.h b/apps/gpu/tests/NumericalTests/Utilities/NumericalTestSimulation/NumericalTestSimulation.h
index b3835c11bf101c3a0e10beddba0095d0f1f0bef3..0e3c9fcb23964922b8ed155a89ca8c3504aa67fc 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/NumericalTestSimulation/NumericalTestSimulation.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/NumericalTestSimulation/NumericalTestSimulation.h
@@ -10,6 +10,7 @@ enum SimulationStatus { initialized , executed, crashed};
 class NumericalTestSimulation
 {
 public:
+	virtual ~NumericalTestSimulation() = default;
 	virtual void run() = 0;
 	virtual SimulationStatus getSimulationStatus() = 0;
 	virtual void registerSimulationObserver(std::shared_ptr<SimulationObserver> simObserver) = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/PostProcessingStrategy/PostProcessingStrategy.h b/apps/gpu/tests/NumericalTests/Utilities/PostProcessingStrategy/PostProcessingStrategy.h
index 686c2300e75257717820b6bb97554b37493d46e3..e995bd4de187da87bce2cc987ac460138e3ffcb8 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/PostProcessingStrategy/PostProcessingStrategy.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/PostProcessingStrategy/PostProcessingStrategy.h
@@ -10,6 +10,7 @@ class SimulationResults;
 class PostProcessingStrategy
 {
 public:
+	virtual ~PostProcessingStrategy() = default;
 	virtual void evaluate() = 0;
 };
 #endif
\ No newline at end of file
diff --git a/apps/gpu/tests/NumericalTests/Utilities/Results/AnalyticalResults/AnalyticalResult.h b/apps/gpu/tests/NumericalTests/Utilities/Results/AnalyticalResults/AnalyticalResult.h
index 7ed53fce60606e8a91b52330cb87822207f36f94..979c57ec3a2fd2bc26f85d07db06e31169b5aa7a 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/Results/AnalyticalResults/AnalyticalResult.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/Results/AnalyticalResults/AnalyticalResult.h
@@ -10,6 +10,7 @@ class SimulationResults;
 class AnalyticalResults : public ResultsImp
 {
 public:
+	virtual ~AnalyticalResults() = default;
 	virtual void calc(std::shared_ptr<SimulationResults> simResults) = 0;
 	virtual bool isCalculated() = 0;
 };
diff --git a/apps/gpu/tests/NumericalTests/Utilities/Results/Results.h b/apps/gpu/tests/NumericalTests/Utilities/Results/Results.h
index 264831a96b1df5cf212b033f2a8dc2acfb03ae5a..3744bf591d98769cee398fcfde78dac1d14737ae 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/Results/Results.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/Results/Results.h
@@ -6,6 +6,7 @@
 class Results
 {
 public:
+	virtual ~Results() = default;
 	virtual int getNumberOfTimeSteps() = 0;
 	virtual std::vector<std::vector<double> > getVx() = 0;
 	virtual std::vector<std::vector<double> > getVy() = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/SimulationInfo/SimulationInfo.h b/apps/gpu/tests/NumericalTests/Utilities/SimulationInfo/SimulationInfo.h
index cd0c29e9c41765b3c877fb4830d66d41f5c98ee7..aa49cba4875a6ad2090cdd715da9971b6bec8967 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/SimulationInfo/SimulationInfo.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/SimulationInfo/SimulationInfo.h
@@ -10,6 +10,7 @@ class TimeInfo;
 class SimulationInfo
 {
 public:
+	virtual ~SimulationInfo() = default;
 	virtual std::string getKernelName() = 0;
 	virtual double getViscosity() = 0;
 	virtual std::string getSimulationName() = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/SimulationParameter/SimulationParameter.h b/apps/gpu/tests/NumericalTests/Utilities/SimulationParameter/SimulationParameter.h
index b9ca9b2e332f4a7f3a79ca0ffae65f621b942230..7de661ce17d681c88fdeef50aebb56ce9af36202 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/SimulationParameter/SimulationParameter.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/SimulationParameter/SimulationParameter.h
@@ -11,6 +11,7 @@ class KernelConfiguration;
 class SimulationParameter
 {
 public:
+	virtual ~SimulationParameter() = default;
 	virtual std::shared_ptr<KernelConfiguration> getKernelConfiguration() = 0;
 	virtual double getViscosity() = 0;
 	virtual std::string getGridPath() = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/Test/SimulationObserver.h b/apps/gpu/tests/NumericalTests/Utilities/Test/SimulationObserver.h
index 9cf022b558255ee2dbb3862caf78ccea8c0e1873..ac579cdc97015c16b5bb8cf27ae664c82aa86655 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/Test/SimulationObserver.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/Test/SimulationObserver.h
@@ -4,6 +4,7 @@
 class SimulationObserver
 {
 public:
+	virtual ~SimulationObserver() = default;
 	virtual void update() = 0;
 
 };
diff --git a/apps/gpu/tests/NumericalTests/Utilities/Test/Test.h b/apps/gpu/tests/NumericalTests/Utilities/Test/Test.h
index c5809671330d2ac5a32f13f3db0d6d3690f06b6f..994bf272eeae9c1d93f15748def233fa0672812c 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/Test/Test.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/Test/Test.h
@@ -10,8 +10,8 @@
 class Test : public SimulationObserver 
 {
 public:
+	virtual ~Test() = default;
 	virtual void run() = 0;
-	virtual void update() = 0;
 
 	virtual TestStatus getTestStatus() = 0;
 	virtual void makeConsoleOutput() = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/Test/TestImp.h b/apps/gpu/tests/NumericalTests/Utilities/Test/TestImp.h
index f4fc758ec75f3c0e12b79faf2efb74a2e749e00e..06c2b3013e22f9de7280dc42b86ad2c1974b1b40 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/Test/TestImp.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/Test/TestImp.h
@@ -16,9 +16,9 @@ class TestImp : public Test
 {
 public:
 	void run() override;
-	void update();
-	TestStatus getTestStatus();
-	virtual void makeConsoleOutput();
+	void update() override;
+	TestStatus getTestStatus() override;
+	void makeConsoleOutput() override;
 
 	void addSimulation(std::shared_ptr<NumericalTestSimulation> sim, std::shared_ptr<SimulationInfo> simInfo, std::shared_ptr<PostProcessingStrategy> postProStrategy);
 		
diff --git a/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueue.h b/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueue.h
index dcc0ece599e45539fd1416b3cd06bb67576a915a..736146d5a9aa3ce295e661fcd0bd3340f0a56ad0 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueue.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueue.h
@@ -6,6 +6,7 @@ enum TestSuiteResult { PASSED, FAILED };
 class TestQueue
 {
 public:
+    virtual ~TestQueue() = default;
     virtual TestSuiteResult run() = 0;
     virtual void makeFinalOutput() = 0;
     virtual int getNumberOfFailedTests() const noexcept = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueueImp.cpp b/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueueImp.cpp
index c7ceef408bcc7d098810aa0f8fd82498902ee211..f55b932bf8f55b3bbab7983a17646b0826484915 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueueImp.cpp
+++ b/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueueImp.cpp
@@ -6,7 +6,7 @@
 
 TestSuiteResult TestQueueImp::run()
 {
-    for (const auto test : tests)
+    for (const auto& test : tests)
         test->run();
 
     makeFinalOutput();
@@ -19,7 +19,7 @@ void TestQueueImp::makeFinalOutput()
     calcTestNumbers();
     colorOutput->makeFinalTestOutputHead(numberOfTests, numberOfExecutedTest, numberOfPassedTest, numberOfFailedTest,
                                          numberOfErrorTest, numberOfNotExecutedTest);
-    for (int i = 0; i < tests.size(); i++)
+    for (uint i = 0; i < tests.size(); i++)
         tests.at(i)->makeConsoleOutput();
     colorOutput->makeFinalTestOutputFoot(numberOfTests, numberOfExecutedTest, numberOfPassedTest, numberOfFailedTest,
                                          numberOfErrorTest, numberOfNotExecutedTest);
@@ -54,7 +54,7 @@ void TestQueueImp::calcTestNumbers()
     numberOfErrorTest = 0;
     numberOfNotExecutedTest = 0;
 
-    for (int i = 0; i < tests.size(); i++) {
+    for (uint i = 0; i < tests.size(); i++) {
         switch (tests.at(i)->getTestStatus()) {
             case passed:
                 numberOfPassedTest++;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueueImp.h b/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueueImp.h
index 89952773f810a983d34f9e35e9508e9d0d7e3ce3..386b5805fb1ff7068ee75e764d6374f2e2fda767 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueueImp.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/TestQueue/TestQueueImp.h
@@ -13,7 +13,7 @@ class TestQueueImp : public TestQueue
 {
 public:
 	TestSuiteResult run() override;
-	void makeFinalOutput();
+	void makeFinalOutput() override;
 
 	int getNumberOfFailedTests() const noexcept override;
 
diff --git a/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulation.h b/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulation.h
index 729ca06a3a57bfc1202d4f93728a68b18a57f8db..1f356304f05b1d08a52ed8c1842959af8f2965c1 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulation.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulation.h
@@ -15,6 +15,7 @@ class Parameter;
 class TestSimulation
 {
 public:
+    virtual ~TestSimulation() = default;
     virtual void run() = 0;
 	virtual void makeSimulationHeadOutput() = 0;
 	virtual void startPostProcessing() = 0;
diff --git a/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulationImp.cpp b/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulationImp.cpp
index dc4aca9b35b0bea92b3d8e3e5b07cb8ed3e054d5..2dd40ef77149c408e3f8ded6f3a7349761fa3a0b 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulationImp.cpp
+++ b/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulationImp.cpp
@@ -87,7 +87,7 @@ std::vector<std::string> TestSimulationImp::getDataToCalcTests()
 
 void TestSimulationImp::notifyObserver()
 {
-    for (int i = 0; i < simObserver.size(); i++)
+    for (uint i = 0; i < simObserver.size(); i++)
         simObserver.at(i)->update();
 }
 
diff --git a/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulationImp.h b/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulationImp.h
index b876cb079f241226bbb3455f7b4bc97b80039131..2a36fda25912ea15f2ee5a8b64d6fe0f7a982180 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulationImp.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/TestSimulation/TestSimulationImp.h
@@ -5,7 +5,7 @@
 #include "Utilities/NumericalTestSimulation/NumericalTestSimulation.h"
 
 #include <functional>
-#include <time.h>
+#include <ctime>
 #include <vector>
 
 class ToVectorWriter;
@@ -28,20 +28,20 @@ public:
                       std::shared_ptr<ColorConsoleOutput> colorOutput);
     void run() override;
 
-    std::shared_ptr<SimulationParameter> getSimulationParameter();
+    std::shared_ptr<SimulationParameter> getSimulationParameter() override;
     std::shared_ptr<SimulationInfo> getSimulationInfo();
-    std::shared_ptr<TimeTracking> getTimeTracking();
+    std::shared_ptr<TimeTracking> getTimeTracking() override;
 
-    SimulationStatus getSimulationStatus();
+    SimulationStatus getSimulationStatus() override;
 
-    void makeSimulationHeadOutput();
-    void startPostProcessing();
+    void makeSimulationHeadOutput() override;
+    void startPostProcessing() override;
 
-    void setParameter(std::shared_ptr<Parameter> para);
+    void setParameter(std::shared_ptr<Parameter> para) override;
 
     std::shared_ptr<SimulationResults> getSimulationResults();
     std::shared_ptr<AnalyticalResults> getAnalyticalResults();
-    void registerSimulationObserver(std::shared_ptr<SimulationObserver> simObserver);
+    void registerSimulationObserver(std::shared_ptr<SimulationObserver> simObserver) override;
     std::vector<std::string> getDataToCalcTests();
 
 private:
diff --git a/apps/gpu/tests/NumericalTests/Utilities/Time/TimeImp.h b/apps/gpu/tests/NumericalTests/Utilities/Time/TimeImp.h
index 87e14e74fb08f6e7f0ceba7923e3adf4db39d455..f6f6c39ef9e641c67af5ae8a7c5af220f68c7c66 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/Time/TimeImp.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/Time/TimeImp.h
@@ -5,26 +5,26 @@
 #include "TimeTracking.h"
 
 #include <memory>
-#include <time.h>
+#include <ctime>
 
 class TimeImp : public TimeTracking, public TimeInfo
 {
 public:
 	static std::shared_ptr<TimeImp> getNewInstance();
 
-	void setSimulationStartTime();
-	void setSimulationEndTime();
-	void setTestStartTime();
-	void setTestEndTime();
-	void setAnalyticalResultWriteStartTime();
-	void setAnalyticalResultWriteEndTime();
-	void setResultCheckStartTime();
-	void setResultCheckEndTime();
+	void setSimulationStartTime() override;
+	void setSimulationEndTime() override;
+	void setTestStartTime() override;
+	void setTestEndTime() override;
+	void setAnalyticalResultWriteStartTime() override;
+	void setAnalyticalResultWriteEndTime() override;
+	void setResultCheckStartTime() override;
+	void setResultCheckEndTime() override;
 
-	std::string getSimulationTime();
-	std::string getResultCheckTime();
-	std::string getTestTime();
-	std::string getAnalyticalResultWriteTime();
+	std::string getSimulationTime() override;
+	std::string getResultCheckTime() override;
+	std::string getTestTime() override;
+	std::string getAnalyticalResultWriteTime() override;
 
 private:
 	TimeImp();
diff --git a/apps/gpu/tests/NumericalTests/Utilities/Time/TimeInfo.h b/apps/gpu/tests/NumericalTests/Utilities/Time/TimeInfo.h
index 11e49b28406ecf08f83f13cfc5cbe09c3ebd8a84..02cf14c5c6db3de64595e58e51acf6771baa1e21 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/Time/TimeInfo.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/Time/TimeInfo.h
@@ -6,9 +6,10 @@
 class TimeInfo
 {
 public:
-	virtual std::string getSimulationTime() = 0;
-	virtual std::string getResultCheckTime() = 0;
-	virtual std::string getTestTime() = 0;
-	virtual std::string getAnalyticalResultWriteTime() = 0;
+    virtual ~TimeInfo() = default;
+    virtual std::string getSimulationTime() = 0;
+    virtual std::string getResultCheckTime() = 0;
+    virtual std::string getTestTime() = 0;
+    virtual std::string getAnalyticalResultWriteTime() = 0;
 };
-#endif
\ No newline at end of file
+#endif
diff --git a/apps/gpu/tests/NumericalTests/Utilities/Time/TimeTracking.h b/apps/gpu/tests/NumericalTests/Utilities/Time/TimeTracking.h
index 736ca764116934dc31e18d7d7c910ead554b253b..663456d6a2c0d428f23a373448ac3c93ad19067f 100644
--- a/apps/gpu/tests/NumericalTests/Utilities/Time/TimeTracking.h
+++ b/apps/gpu/tests/NumericalTests/Utilities/Time/TimeTracking.h
@@ -4,6 +4,7 @@
 class TimeTracking
 {
 public:
+	virtual ~TimeTracking() = default;
 	virtual void setSimulationStartTime() = 0;
 	virtual void setSimulationEndTime() = 0;
 
@@ -16,4 +17,4 @@ public:
 	virtual void setAnalyticalResultWriteStartTime() = 0;
 	virtual void setAnalyticalResultWriteEndTime() = 0;
 };
-#endif
\ No newline at end of file
+#endif
diff --git a/pyproject.toml b/pyproject.toml
index 257da6fd95d683081dbff865c864079eae9c675d..df0b13b9c22718ef4172d4698fd29b8e85f0ad22 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,9 +1,46 @@
 [build-system]
-requires = [
-    "setuptools>=42",
-    "scikit-build",
-    "cmake",
-    "ninja; platform_system!='Windows'"
+requires = ["scikit-build-core"]
+build-backend = "scikit_build_core.build"
+
+[project]
+name = "pyfluids"
+version = "0.1.0"
+description = "Python bindings for VirtualFluids"
+readme = "README.md"
+requires-python = ">=3.6"
+classifiers = [
+  "Programming Language :: Python :: 3 :: Only",
+  "Programming Language :: Python :: 3.6",
+  "Programming Language :: Python :: 3.7",
+  "Programming Language :: Python :: 3.8",
+  "Programming Language :: Python :: 3.9",
+  "Programming Language :: Python :: 3.10",
+  "Programming Language :: Python :: 3.11",
 ]
-build-backend = "setup_builder"
-backend-path = ["utilities"]
\ No newline at end of file
+url = "https://git.rz.tu-bs.de/irmb/virtualfluids"
+
+[tool.cmake]
+jobs = 8
+
+[tool.scikit-build]
+build-dir = "build"
+strict-config = true
+logging.level = "INFO"
+
+[tool.scikit-build.wheel]
+packages = ["pythonbindings/pyfluids", "pythonbindings/pyfluids-stubs", "pythonbindings/pymuparser"]
+
+[tool.scikit_build.cmake]
+verbose = true
+build-type = "Release"
+
+[tool.scikit-build.cmake.define]
+BUILD_VF_PYTHON_BINDINGS = "ON"
+BUILD_SHARED_LIBS = "OFF"
+BUILD_VF_UNIT_TESTS = "OFF"
+BUILD_WARNINGS_AS_ERRORS = "OFF"
+
+
+[mypy]
+plugins = "numpy.typing.mypy_plugin"
+
diff --git a/pythonbindings/CMakeLists.txt b/pythonbindings/CMakeLists.txt
index 037b68baf53d5da8a1ccd20155cb0e7be483176b..c9bef9ef080e6e995b903837475f7c2e401152ee 100644
--- a/pythonbindings/CMakeLists.txt
+++ b/pythonbindings/CMakeLists.txt
@@ -6,27 +6,78 @@ endif()
 
 project(VirtualFluidsPython LANGUAGES ${PYFLUIDS_LANGUAGES})
 
-pybind11_add_module(python_bindings MODULE src/VirtualFluids.cpp)
-target_compile_definitions(python_bindings PUBLIC VF_DOUBLE_ACCURACY)
+add_custom_target(python_bindings)
 
-set_target_properties(  python_bindings PROPERTIES
-                        LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/pythonbindings/pyfluids
-                        OUTPUT_NAME "bindings")
+set(PYFLUIDS_DIR ${SKBUILD_PLATLIB_DIR}/pyfluids)
+set(PYMUPRASER_DIR ${SKBUILD_PLATLIB_DIR}/pymuparser)
+
+
+pybind11_add_module(basics_bindings MODULE src/basics/basics.cpp)
+set_target_properties(  basics_bindings PROPERTIES
+                        LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR}
+                        OUTPUT_NAME "basics")
+target_link_libraries(basics_bindings PRIVATE basics)
+target_include_directories(basics_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
+target_include_directories(basics_bindings PRIVATE ${CMAKE_BINARY_DIR})
+add_dependencies(python_bindings basics_bindings)
+
+
+pybind11_add_module(logger_bindings MODULE src/logger.cpp)
+set_target_properties(  logger_bindings PROPERTIES
+                        LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR}
+                        OUTPUT_NAME "logger")
+target_link_libraries(logger_bindings PRIVATE logger)
+target_include_directories(logger_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
+target_include_directories(logger_bindings PRIVATE ${CMAKE_BINARY_DIR})
+add_dependencies(python_bindings logger_bindings)
+
+
+pybind11_add_module(lbm_bindings MODULE src/lbm.cpp)
+set_target_properties(  lbm_bindings PROPERTIES
+                        LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR}
+                        OUTPUT_NAME "lbm")
+target_link_libraries(lbm_bindings PRIVATE lbm)
+target_include_directories(lbm_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
+target_include_directories(lbm_bindings PRIVATE ${CMAKE_BINARY_DIR})
+add_dependencies(python_bindings lbm_bindings)
 
-target_link_libraries(python_bindings PRIVATE basics logger mpi lbm)
 
 IF(BUILD_VF_GPU)
-    set_source_files_properties(src/VirtualFluids.cpp PROPERTIES LANGUAGE CUDA)
+    pybind11_add_module(gpu_bindings MODULE src/gpu/gpu.cpp)
+    set_target_properties(  gpu_bindings PROPERTIES
+                            LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR}
+                            OUTPUT_NAME "gpu")
+    target_link_libraries(gpu_bindings PRIVATE basics)
+    set_source_files_properties(src/gpu/gpu.cpp PROPERTIES LANGUAGE CUDA)
+
+    target_include_directories(gpu_bindings PRIVATE ${VF_THIRD_DIR}/cuda_samples/)
 
-    target_include_directories(python_bindings PRIVATE ${VF_THIRD_DIR}/cuda_samples/)
-    target_compile_definitions(python_bindings PRIVATE VF_GPU_PYTHONBINDINGS)
+    target_link_libraries(gpu_bindings PRIVATE GridGenerator VirtualFluids_GPU)
+
+    target_include_directories(gpu_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
+    target_include_directories(gpu_bindings PRIVATE ${CMAKE_BINARY_DIR})
+    add_dependencies(python_bindings gpu_bindings)
 
-    target_link_libraries(python_bindings PRIVATE GridGenerator VirtualFluids_GPU)
 ENDIF()
 
 IF(BUILD_VF_CPU)
-    target_compile_definitions(python_bindings PRIVATE VF_METIS VF_MPI VF_CPU_PYTHONBINDINGS)
-    target_link_libraries(python_bindings PRIVATE simulationconfig VirtualFluidsCore muparser)
+    pybind11_add_module(cpu_bindings MODULE src/cpu/cpu.cpp)
+    set_target_properties(  cpu_bindings PROPERTIES
+                            LIBRARY_OUTPUT_DIRECTORY ${PYFLUIDS_DIR}
+                            OUTPUT_NAME "cpu")
+    target_link_libraries(cpu_bindings PRIVATE simulationconfig VirtualFluidsCore muparser)
+
+    target_include_directories(cpu_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
+    target_include_directories(cpu_bindings PRIVATE ${CMAKE_BINARY_DIR})
+
+    target_compile_definitions(cpu_bindings PUBLIC VF_DOUBLE_ACCURACY) # TODO: remove this and always set it dynamically
+    target_compile_definitions(basics_bindings PUBLIC VF_DOUBLE_ACCURACY)
+    target_compile_definitions(logger_bindings PUBLIC VF_DOUBLE_ACCURACY)
+    target_compile_definitions(lbm_bindings PUBLIC VF_DOUBLE_ACCURACY)
+
+    target_compile_definitions(cpu_bindings PRIVATE VF_METIS VF_MPI)
+    add_dependencies(python_bindings cpu_bindings)
+
 
     # include bindings for muparsers
     pybind11_add_module(pymuparser MODULE src/muParser.cpp)
@@ -40,7 +91,3 @@ IF(BUILD_VF_CPU)
     target_compile_definitions(pymuparser PRIVATE VF_METIS VF_MPI)
     target_link_libraries(pymuparser PRIVATE muparser)
 ENDIF()
-
-
-target_include_directories(python_bindings PRIVATE ${CMAKE_SOURCE_DIR}/src/)
-target_include_directories(python_bindings PRIVATE ${CMAKE_BINARY_DIR})
\ No newline at end of file
diff --git a/pythonbindings/pyfluids-stubs/__init__.pyi b/pythonbindings/pyfluids-stubs/__init__.pyi
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..df0d398713cd56ef06bf96637d3aca0f6032dc58 100644
--- a/pythonbindings/pyfluids-stubs/__init__.pyi
+++ b/pythonbindings/pyfluids-stubs/__init__.pyi
@@ -0,0 +1,6 @@
+from . import basics as basics
+from . import logger as logger
+from . import lbm as lbm
+from . import gpu as gpu
+from . import cpu as cpu
+
diff --git a/pythonbindings/pyfluids-stubs/bindings/basics/__init__.pyi b/pythonbindings/pyfluids-stubs/basics/__init__.pyi
similarity index 95%
rename from pythonbindings/pyfluids-stubs/bindings/basics/__init__.pyi
rename to pythonbindings/pyfluids-stubs/basics/__init__.pyi
index a646f7e590e2aba91ab1c367f75b8c6ebe8f79ae..ed74e648a0b6739b31853c9633d63eeac3b91df4 100644
--- a/pythonbindings/pyfluids-stubs/bindings/basics/__init__.pyi
+++ b/pythonbindings/pyfluids-stubs/basics/__init__.pyi
@@ -32,10 +32,13 @@ r"""
 ! \author Henry Korb
 =======================================================================================
 """
-from typing import ClassVar
+from __future__ import annotations
 
-from typing import overload
+from typing import ClassVar, overload
 
+from . import logger as logger
+
+from pyfluids.bindings.basics import logger as logger
 class ConfigurationFile:
     def __init__(self) -> None: ...
     def contains(self, key: str) -> bool: ...
diff --git a/pythonbindings/pyfluids-stubs/bindings/__init__.pyi b/pythonbindings/pyfluids-stubs/bindings/__init__.pyi
deleted file mode 100644
index 4e7f353eab97cc536f8f18e72319af1cd7a1916a..0000000000000000000000000000000000000000
--- a/pythonbindings/pyfluids-stubs/bindings/__init__.pyi
+++ /dev/null
@@ -1,38 +0,0 @@
-r"""
-=======================================================================================
- ____          ____    __    ______     __________   __      __       __        __
- \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
-  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
-   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
-    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
-     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
-      \    \  |    |   ________________________________________________________________
-       \    \ |    |  |  ______________________________________________________________|
-        \    \|    |  |  |         __          __     __     __     ______      _______
-         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
-          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
-           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
-            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
-
-  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 __init__.pyi
-! \ingroup bindings
-! \author Henry Korb
-=======================================================================================
-"""
-class ostream_redirect:
-    def __init__(self, stdout: bool = ..., stderr: bool = ...) -> None: ...
-    def __enter__(self) -> None: ...
-    def __exit__(self, *args) -> None: ...
diff --git a/pythonbindings/pyfluids-stubs/bindings/lbm.pyi b/pythonbindings/pyfluids-stubs/bindings/lbm.pyi
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/pythonbindings/pyfluids-stubs/bindings/gpu/__init__.pyi b/pythonbindings/pyfluids-stubs/gpu/__init__.pyi
similarity index 81%
rename from pythonbindings/pyfluids-stubs/bindings/gpu/__init__.pyi
rename to pythonbindings/pyfluids-stubs/gpu/__init__.pyi
index 64a598ee1974b089393b328566def02fb3600005..cc6e3906477e5206a7d3be159cda15909aa1ba68 100644
--- a/pythonbindings/pyfluids-stubs/bindings/gpu/__init__.pyi
+++ b/pythonbindings/pyfluids-stubs/gpu/__init__.pyi
@@ -32,77 +32,88 @@ r"""
 ! \author Henry Korb
 =======================================================================================
 """
-from typing import Any, Callable, ClassVar, List, Optional
+from __future__ import annotations
+from typing import Callable, ClassVar, List, Optional
 
-from typing import overload
-import numpy
-import pyfluids.bindings.basics
-import pyfluids.bindings.gpu.grid_generator as grid_generator
+from typing import overload, Union
+import numpy as np
+import numpy.typing as npt
+import basics
+
+from . import grid_generator as grid_generator
+from . import probes as probes
+
+class PreCollisionInteractor:
+    def __init__(self, *args, **kwargs) -> None: ...
+
+
+class FileCollection:
+    def __init__(self, *args, **kwargs) -> None: ...
 
 class ActuatorFarm(PreCollisionInteractor):
     def __init__(self, number_of_blades_per_turbine: int, density: float, number_of_nodes_per_blade: int, epsilon: float, level: int, delta_t: float, delta_x: float, use_host_arrays: bool) -> None: ...
     def add_turbine(self, posX: float, posY: float, posZ: float, diameter: float, omega: float, azimuth: float, yaw: float, bladeRadii: List[float]) -> None: ...
     def calc_blade_forces(self) -> None: ...
-    def get_all_azimuths(self) -> numpy.ndarray[numpy.float32]: ...
-    def get_all_blade_coords_x(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_azimuths(self) -> npt.NDArray[np.float32]: ...
+    def get_all_blade_coords_x(self) -> npt.NDArray[np.float32]: ...
     def get_all_blade_coords_x_device(self) -> int: ...
-    def get_all_blade_coords_y(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_coords_y(self) -> npt.NDArray[np.float32]: ...
     def get_all_blade_coords_y_device(self) -> int: ...
-    def get_all_blade_coords_z(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_coords_z(self) -> npt.NDArray[np.float32]: ...
     def get_all_blade_coords_z_device(self) -> int: ...
-    def get_all_blade_forces_x(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_forces_x(self) -> npt.NDArray[np.float32]: ...
     def get_all_blade_forces_x_device(self) -> int: ...
-    def get_all_blade_forces_y(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_forces_y(self) -> npt.NDArray[np.float32]: ...
     def get_all_blade_forces_y_device(self) -> int: ...
-    def get_all_blade_forces_z(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_forces_z(self) -> npt.NDArray[np.float32]: ...
     def get_all_blade_forces_z_device(self) -> int: ...
-    def get_all_blade_radii(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_radii(self) -> npt.NDArray[np.float32]: ...
     def get_all_blade_radii_device(self) -> int: ...
-    def get_all_blade_velocities_x(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_velocities_x(self) -> npt.NDArray[np.float32]: ...
     def get_all_blade_velocities_x_device(self) -> int: ...
-    def get_all_blade_velocities_y(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_velocities_y(self) -> npt.NDArray[np.float32]: ...
     def get_all_blade_velocities_y_device(self) -> int: ...
-    def get_all_blade_velocities_z(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_blade_velocities_z(self) -> npt.NDArray[np.float32]: ...
     def get_all_blade_velocities_z_device(self) -> int: ...
-    def get_all_omegas(self) -> numpy.ndarray[numpy.float32]: ...
-    def get_all_turbine_pos_x(self) -> numpy.ndarray[numpy.float32]: ...
-    def get_all_turbine_pos_y(self) -> numpy.ndarray[numpy.float32]: ...
-    def get_all_turbine_pos_z(self) -> numpy.ndarray[numpy.float32]: ...
-    def get_all_yaws(self) -> numpy.ndarray[numpy.float32]: ...
+    def get_all_omegas(self) -> npt.NDArray[np.float32]: ...
+    def get_all_turbine_pos_x(self) -> npt.NDArray[np.float32]: ...
+    def get_all_turbine_pos_y(self) -> npt.NDArray[np.float32]: ...
+    def get_all_turbine_pos_z(self) -> npt.NDArray[np.float32]: ...
+    def get_all_yaws(self) -> npt.NDArray[np.float32]: ...
     def get_turbine_azimuth(self, turbine: int) -> float: ...
-    def get_turbine_blade_coords_x(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_coords_x(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_blade_coords_x_device(self, turbine: int) -> int: ...
-    def get_turbine_blade_coords_y(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_coords_y(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_blade_coords_y_device(self, turbine: int) -> int: ...
-    def get_turbine_blade_coords_z(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_coords_z(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_blade_coords_z_device(self, turbine: int) -> int: ...
-    def get_turbine_blade_forces_x(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_forces_x(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_blade_forces_x_device(self, turbine: int) -> int: ...
-    def get_turbine_blade_forces_y(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_forces_y(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_blade_forces_y_device(self, turbine: int) -> int: ...
-    def get_turbine_blade_forces_z(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_forces_z(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_blade_forces_z_device(self, turbine: int) -> int: ...
-    def get_turbine_blade_radii(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_radii(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_blade_radii_device(self, turbine: int) -> int: ...
-    def get_turbine_blade_velocities_x(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_velocities_x(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_blade_velocities_x_device(self, turbine: int) -> int: ...
-    def get_turbine_blade_velocities_y(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_velocities_y(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_blade_velocities_y_device(self, turbine: int) -> int: ...
-    def get_turbine_blade_velocities_z(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_blade_velocities_z(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_blade_velocities_z_device(self, turbine: int) -> int: ...
     def get_turbine_omega(self, turbine: int) -> float: ...
-    def get_turbine_pos(self, turbine: int) -> numpy.ndarray[numpy.float32]: ...
+    def get_turbine_pos(self, turbine: int) -> npt.NDArray[np.float32]: ...
     def get_turbine_yaw(self, turbine: int) -> float: ...
-    def set_all_azimuths(self, azimuths: numpy.ndarray[numpy.float32]) -> None: ...
-    def set_all_blade_coords(self, blade_coords_x: numpy.ndarray[numpy.float32], blade_coords_y: numpy.ndarray[numpy.float32], blade_coords_z: numpy.ndarray[numpy.float32]) -> None: ...
-    def set_all_blade_forces(self, blade_forces_x: numpy.ndarray[numpy.float32], blade_forces_y: numpy.ndarray[numpy.float32], blade_forces_z: numpy.ndarray[numpy.float32]) -> None: ...
-    def set_all_blade_velocities(self, blade_velocities_x: numpy.ndarray[numpy.float32], blade_velocities_y: numpy.ndarray[numpy.float32], blade_velocities_z: numpy.ndarray[numpy.float32]) -> None: ...
-    def set_all_omegas(self, omegas: numpy.ndarray[numpy.float32]) -> None: ...
-    def set_all_yaws(self, yaws: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_all_azimuths(self, azimuths: npt.NDArray[np.float32]) -> None: ...
+    def set_all_blade_coords(self, blade_coords_x: npt.NDArray[np.float32], blade_coords_y: npt.NDArray[np.float32], blade_coords_z: npt.NDArray[np.float32]) -> None: ...
+    def set_all_blade_forces(self, blade_forces_x: npt.NDArray[np.float32], blade_forces_y: npt.NDArray[np.float32], blade_forces_z: npt.NDArray[np.float32]) -> None: ...
+    def set_all_blade_velocities(self, blade_velocities_x: npt.NDArray[np.float32], blade_velocities_y: npt.NDArray[np.float32], blade_velocities_z: npt.NDArray[np.float32]) -> None: ...
+    def set_all_omegas(self, omegas: npt.NDArray[np.float32]) -> None: ...
+    def set_all_yaws(self, yaws: npt.NDArray[np.float32]) -> None: ...
     def set_turbine_azimuth(self, turbine: int, azimuth: float) -> None: ...
-    def set_turbine_blade_coords(self, turbine: int, blade_coords_x: numpy.ndarray[numpy.float32], blade_coords_y: numpy.ndarray[numpy.float32], blade_coords_z: numpy.ndarray[numpy.float32]) -> None: ...
-    def set_turbine_blade_forces(self, turbine: int, blade_forces_x: numpy.ndarray[numpy.float32], blade_forces_y: numpy.ndarray[numpy.float32], blade_forces_z: numpy.ndarray[numpy.float32]) -> None: ...
-    def set_turbine_blade_velocities(self, turbine: int, blade_velocities_x: numpy.ndarray[numpy.float32], blade_velocities_y: numpy.ndarray[numpy.float32], blade_velocities_z: numpy.ndarray[numpy.float32]) -> None: ...
+    def set_turbine_blade_coords(self, turbine: int, blade_coords_x: npt.NDArray[np.float32], blade_coords_y: npt.NDArray[np.float32], blade_coords_z: npt.NDArray[np.float32]) -> None: ...
+    def set_turbine_blade_forces(self, turbine: int, blade_forces_x: npt.NDArray[np.float32], blade_forces_y: npt.NDArray[np.float32], blade_forces_z: npt.NDArray[np.float32]) -> None: ...
+    def set_turbine_blade_velocities(self, turbine: int, blade_velocities_x: npt.NDArray[np.float32], blade_velocities_y: npt.NDArray[np.float32], blade_velocities_z: npt.NDArray[np.float32]) -> None: ...
     def set_turbine_omega(self, turbine: int, omega: float) -> None: ...
     def set_turbine_yaw(self, turbine: int, yaw: float) -> None: ...
     @property
@@ -116,21 +127,23 @@ class ActuatorFarm(PreCollisionInteractor):
     @property
     def number_of_indices(self) -> int: ...
     @property
-    def number_of_nodes(self) -> int: ...
+    def number_of_grid_nodes(self) -> int: ...
     @property
     def number_of_nodes_per_blade(self) -> int: ...
     @property
     def number_of_turbines(self) -> int: ...
 
+
 class BoundaryConditionFactory:
     def __init__(self) -> None: ...
-    def set_geometry_boundary_condition(self, boundary_condition_type) -> None: ...
-    def set_no_slip_boundary_condition(self, boundary_condition_type) -> None: ...
-    def set_precursor_boundary_condition(self, boundary_condition_type) -> None: ...
-    def set_pressure_boundary_condition(self, boundary_condition_type) -> None: ...
-    def set_slip_boundary_condition(self, boundary_condition_type) -> None: ...
-    def set_stress_boundary_condition(self, boundary_condition_type) -> None: ...
-    def set_velocity_boundary_condition(self, boundary_condition_type) -> None: ...
+    def set_geometry_boundary_condition(self, boundary_condition_type: Union[SlipBC, VelocityBC, NoSlipBC]) -> None: ...
+    def set_no_slip_boundary_condition(self, boundary_condition_type: NoSlipBC) -> None: ...
+    def set_precursor_boundary_condition(self, boundary_condition_type: PrecursorBC) -> None: ...
+    def set_pressure_boundary_condition(self, boundary_condition_type: PressureBC) -> None: ...
+    def set_slip_boundary_condition(self, boundary_condition_type: SlipBC) -> None: ...
+    def set_stress_boundary_condition(self, boundary_condition_type: StressBC) -> None: ...
+    def set_velocity_boundary_condition(self, boundary_condition_type: VelocityBC) -> None: ...
+
 
 class MpiCommunicator:
     def __init__(self, *args, **kwargs) -> None: ...
@@ -139,9 +152,11 @@ class MpiCommunicator:
     def get_number_of_process(self) -> int: ...
     def get_pid(self) -> int: ...
 
+
 class CudaMemoryManager:
     def __init__(self, parameter: Parameter) -> None: ...
 
+
 class FileType:
     __members__: ClassVar[dict] = ...  # read-only
     VTK: ClassVar[FileType] = ...
@@ -157,10 +172,13 @@ class FileType:
     @property
     def name(self) -> str: ...
 
+
 class GridProvider:
     def __init__(self, *args, **kwargs) -> None: ...
     @staticmethod
-    def make_grid_generator(builder: grid_generator.GridBuilder, para: Parameter, cuda_memory_manager: CudaMemoryManager, communicator: Communicator) -> GridProvider: ...
+    def make_grid_generator(builder: grid_generator.GridBuilder, para: Parameter, cuda_memory_manager: CudaMemoryManager, communicator: MpiCommunicator) -> GridProvider: ...
+
+
 
 class GridScaling:
     __members__: ClassVar[dict] = ...  # read-only
@@ -179,10 +197,12 @@ class GridScaling:
     @property
     def name(self) -> str: ...
 
+
 class GridScalingFactory:
     def __init__(self) -> None: ...
     def set_scaling_factory(self, scaling_type) -> None: ...
 
+
 class NoSlipBC:
     __members__: ClassVar[dict] = ...  # read-only
     NoSlip3rdMomentsCompressible: ClassVar[NoSlipBC] = ...
@@ -202,6 +222,7 @@ class NoSlipBC:
     @property
     def name(self) -> str: ...
 
+
 class OutputVariable:
     __members__: ClassVar[dict] = ...  # read-only
     Distributions: ClassVar[OutputVariable] = ...
@@ -218,13 +239,14 @@ class OutputVariable:
     @property
     def name(self) -> str: ...
 
+
 class Parameter:
     @overload
-    def __init__(self, number_of_processes: int, my_ID: int, config_data: Optional[pyfluids.bindings.basics.ConfigurationFile]) -> None: ...
+    def __init__(self, number_of_processes: int, my_ID: int, config_data: Optional[basics.ConfigurationFile]) -> None: ...
     @overload
     def __init__(self, number_of_processes: int, my_ID: int) -> None: ...
     @overload
-    def __init__(self, config_data: pyfluids.bindings.basics.ConfigurationFile) -> None: ...
+    def __init__(self, config_data: basics.ConfigurationFile) -> None: ...
     def add_actuator(self, actuator: PreCollisionInteractor) -> None: ...
     def add_probe(self, probe: PreCollisionInteractor) -> None: ...
     def get_SGS_constant(self) -> float: ...
@@ -245,7 +267,7 @@ class Parameter:
     def set_diff_on(self, is_diff: bool) -> None: ...
     def set_forcing(self, forcing_x: float, forcing_y: float, forcing_z: float) -> None: ...
     def set_has_wall_model_monitor(self, has_wall_monitor: bool) -> None: ...
-    def set_initial_condition(self, init_func: Callable[[float,float,float],List[float]]) -> None: ...
+    def set_initial_condition(self, init_func: Callable[[float, float, float], List[float]]) -> None: ...
     def set_initial_condition_log_law(self, u_star: float, z0: float, velocity_ratio: float) -> None: ...
     def set_initial_condition_perturbed_log_law(self, u_star: float, z0: float, length_x: float, length_z: float, height: float, velocity_ratio: float) -> None: ...
     def set_initial_condition_uniform(self, velocity_x: float, velocity_y: float, velocity_z: float) -> None: ...
@@ -270,8 +292,6 @@ class Parameter:
     def set_viscosity_LB(self, viscosity: float) -> None: ...
     def set_viscosity_ratio(self, viscosity_ratio: float) -> None: ...
 
-class PreCollisionInteractor:
-    def __init__(self, *args, **kwargs) -> None: ...
 
 class PrecursorBC:
     __members__: ClassVar[dict] = ...  # read-only
@@ -290,9 +310,11 @@ class PrecursorBC:
     @property
     def name(self) -> str: ...
 
+
 class PrecursorWriter(PreCollisionInteractor):
     def __init__(self, filename: str, output_path: str, x_pos: float, y_min: float, y_max: float, z_min: float, z_max: float, t_start_out: int, t_save: int, output_variable: OutputVariable, max_timesteps_per_file: int) -> None: ...
 
+
 class PressureBC:
     __members__: ClassVar[dict] = ...  # read-only
     NotSpecified: ClassVar[PressureBC] = ...
@@ -314,6 +336,7 @@ class PressureBC:
     @property
     def name(self) -> str: ...
 
+
 class SideType:
     __members__: ClassVar[dict] = ...  # read-only
     GEOMETRY: ClassVar[SideType] = ...
@@ -335,6 +358,7 @@ class SideType:
     @property
     def name(self) -> str: ...
 
+
 class Simulation:
     @overload
     def __init__(self, parameter: Parameter, memoryManager: CudaMemoryManager, communicator, gridProvider: GridProvider, bcFactory: BoundaryConditionFactory, gridScalingFactory: GridScalingFactory) -> None: ...
@@ -346,6 +370,7 @@ class Simulation:
     def addKineticEnergyAnalyzer(self, t_analyse: int) -> None: ...
     def run(self) -> None: ...
 
+
 class SlipBC:
     __members__: ClassVar[dict] = ...  # read-only
     NotSpecified: ClassVar[SlipBC] = ...
@@ -366,6 +391,7 @@ class SlipBC:
     @property
     def name(self) -> str: ...
 
+
 class StressBC:
     __members__: ClassVar[dict] = ...  # read-only
     NotSpecified: ClassVar[StressBC] = ...
@@ -384,6 +410,7 @@ class StressBC:
     @property
     def name(self) -> str: ...
 
+
 class TurbulenceModel:
     __members__: ClassVar[dict] = ...  # read-only
     AMD: ClassVar[TurbulenceModel] = ...
@@ -402,15 +429,18 @@ class TurbulenceModel:
     @property
     def name(self) -> str: ...
 
+
 class TurbulenceModelFactory:
     def __init__(self, para: Parameter) -> None: ...
-    def read_config_file(self, config_data: pyfluids.bindings.basics.ConfigurationFile) -> None: ...
+    def read_config_file(self, config_data: basics.ConfigurationFile) -> None: ...
     def set_model_constant(self, model_constant: float) -> None: ...
     def set_turbulence_model(self, turbulence_model: TurbulenceModel) -> None: ...
 
+
 class VTKFileCollection(FileCollection):
     def __init__(self, prefix: str) -> None: ...
 
+
 class VelocityBC:
     __members__: ClassVar[dict] = ...  # read-only
     NotSpecified: ClassVar[VelocityBC] = ...
@@ -430,7 +460,5 @@ class VelocityBC:
     @property
     def name(self) -> str: ...
 
-class FileCollection:
-    def __init__(self, *args, **kwargs) -> None: ...
 
 def create_file_collection(prefix: str, type: FileType) -> FileCollection: ...
diff --git a/pythonbindings/pyfluids-stubs/bindings/gpu/grid_generator.pyi b/pythonbindings/pyfluids-stubs/gpu/grid_generator.pyi
similarity index 79%
rename from pythonbindings/pyfluids-stubs/bindings/gpu/grid_generator.pyi
rename to pythonbindings/pyfluids-stubs/gpu/grid_generator.pyi
index 433a20e7efe472bd791b1d2a0f43859676e8fcf0..b1afd89f6455b5fdf5df568c7e03656229d69c1d 100644
--- a/pythonbindings/pyfluids-stubs/bindings/gpu/grid_generator.pyi
+++ b/pythonbindings/pyfluids-stubs/gpu/grid_generator.pyi
@@ -32,15 +32,23 @@ r"""
 ! \author Henry Korb
 =======================================================================================
 """
-from typing import Any, List
+from __future__ import annotations
+
+from typing import List
 
 from typing import overload
-import pyfluids.bindings.basics
-import pyfluids.bindings.gpu
+import gpu
+
+
 
 class BoundingBox:
     def __init__(self, min_x: float, max_x: float, min_y: float, max_y: float, min_z: float, max_z: float) -> None: ...
 
+
+class Object:
+    def __init__(self, *args, **kwargs) -> None: ...
+
+
 class Conglomerate(Object):
     def __init__(self, *args, **kwargs) -> None: ...
     def add(self, object: Object) -> None: ...
@@ -48,27 +56,33 @@ class Conglomerate(Object):
     def make_shared() -> Conglomerate: ...
     def subtract(self, object: Object) -> None: ...
 
+
 class Cuboid(Object):
     def __init__(self, min_x1: float, min_x2: float, min_x3: float, max_x1: float, max_x2: float, max_x3: float) -> None: ...
 
+
 class GridBuilder:
     def __init__(self, *args, **kwargs) -> None: ...
     def get_number_of_grid_levels(self) -> int: ...
 
+
 class GridFactory:
     def __init__(self, *args, **kwargs) -> None: ...
     @staticmethod
     def make() -> GridFactory: ...
 
+
 class LevelGridBuilder(GridBuilder):
     def __init__(self, *args, **kwargs) -> None: ...
-    def set_no_slip_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType) -> None: ...
+    def set_no_slip_boundary_condition(self, side_type: gpu.SideType) -> None: ...
     def set_periodic_boundary_condition(self, periodic_x: bool, periodic_y: bool, periodic_z: bool) -> None: ...
-    def set_precursor_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType, file_collection: pyfluids.bindings.gpu.VelocityFileCollection, n_t_read: int, velocity_x: float = ..., velocity_y: float = ..., velocity_z: float = ..., file_level_to_grid_level_map: List[int] = ...) -> None: ...
-    def set_pressure_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType, rho: float) -> None: ...
-    def set_slip_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType, normal_x: float, normal_y: float, normal_z: float) -> None: ...
-    def set_stress_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType, normal_x: float, normal_y: float, normal_z: float, sampling_offset: int, z0: float, dx: float, q: float) -> None: ...
-    def set_velocity_boundary_condition(self, side_type: pyfluids.bindings.gpu.SideType, vx: float, vy: float, vz: float) -> None: ...
+    def set_precursor_boundary_condition(self, side_type: gpu.SideType, file_collection: gpu.FileCollection, n_t_read: int, velocity_x: float = ..., velocity_y: float = ..., velocity_z: float = ..., file_level_to_grid_level_map: List[int] = ...) -> None: ...
+    def set_pressure_boundary_condition(self, side_type: gpu.SideType, rho: float) -> None: ...
+    def set_slip_boundary_condition(self, side_type: gpu.SideType, normal_x: float, normal_y: float, normal_z: float) -> None: ...
+    def set_stress_boundary_condition(self, side_type: gpu.SideType, normal_x: float, normal_y: float, normal_z: float, sampling_offset: int, z0: float, dx: float, q: float = ...) -> None: ...
+    def set_velocity_boundary_condition(self, side_type: gpu.SideType, vx: float, vy: float, vz: float) -> None: ...
+
+
 
 class MultipleGridBuilder(LevelGridBuilder):
     def __init__(self, *args, **kwargs) -> None: ...
@@ -86,14 +100,13 @@ class MultipleGridBuilder(LevelGridBuilder):
     @staticmethod
     def make_shared(grid_factory: GridFactory) -> MultipleGridBuilder: ...
 
-class Object:
-    def __init__(self, *args, **kwargs) -> None: ...
 
 class Sphere(Object):
     def __init__(self, *args, **kwargs) -> None: ...
     @staticmethod
     def make_shared() -> Sphere: ...
 
+
 class TriangularMesh(Object):
     def __init__(self, *args, **kwargs) -> None: ...
     @staticmethod
diff --git a/pythonbindings/pyfluids-stubs/bindings/gpu/probes.pyi b/pythonbindings/pyfluids-stubs/gpu/probes.pyi
similarity index 95%
rename from pythonbindings/pyfluids-stubs/bindings/gpu/probes.pyi
rename to pythonbindings/pyfluids-stubs/gpu/probes.pyi
index af9c40078e6009efebda4450b5c5e23586aa1e83..4c275d1d6f2eb2bc6a63ae0a8a015d5b0eee6472 100644
--- a/pythonbindings/pyfluids-stubs/bindings/gpu/probes.pyi
+++ b/pythonbindings/pyfluids-stubs/gpu/probes.pyi
@@ -32,27 +32,11 @@ r"""
 ! \author Henry Korb
 =======================================================================================
 """
+from __future__ import annotations
 from typing import ClassVar, List
 
-import pyfluids.bindings.gpu
+import gpu
 
-class PlanarAverageProbe(Probe):
-    def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_start_tmp_avg: int, t_avg: int, t_start_out: int, t_out: int, plane_normal: str) -> None: ...
-
-class PlaneProbe(Probe):
-    def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_avg: int, t_start_out: int, t_out: int) -> None: ...
-    def set_probe_plane(self, pos_x: float, pos_y: float, pos_z: float, delta_x: float, delta_y: float, delta_z: float) -> None: ...
-
-class PointProbe(Probe):
-    def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_avg: int, t_start_out: int, t_out: int, output_timeseries: bool) -> None: ...
-    def add_probe_points_from_list(self, point_coords_x: List[float], point_coords_y: List[float], point_coords_z: List[float]) -> None: ...
-    def add_probe_points_from_x_normal_plane(self, pos_x: float, pos0_y: float, pos0_z: float, pos1_y: float, pos1_z: float, n_y: int, n_z: int) -> None: ...
-
-class Probe(pyfluids.bindings.gpu.PreCollisionInteractor):
-    def __init__(self, *args, **kwargs) -> None: ...
-    def add_all_available_statistics(self) -> None: ...
-    def add_statistic(self, variable: Statistic) -> None: ...
-    def set_file_name_to_n_out(self) -> None: ...
 
 class Statistic:
     __members__: ClassVar[dict] = ...  # read-only
@@ -79,6 +63,30 @@ class Statistic:
     @property
     def name(self) -> str: ...
 
+
+class Probe(gpu.PreCollisionInteractor):
+    def __init__(self, *args, **kwargs) -> None: ...
+    def add_all_available_statistics(self) -> None: ...
+    def add_statistic(self, variable: Statistic) -> None: ...
+    def set_file_name_to_n_out(self) -> None: ...
+
+
+class PlanarAverageProbe(Probe):
+    def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_start_tmp_avg: int, t_avg: int, t_start_out: int, t_out: int, plane_normal: str) -> None: ...
+
+
+class PlaneProbe(Probe):
+    def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_avg: int, t_start_out: int, t_out: int) -> None: ...
+    def set_probe_plane(self, pos_x: float, pos_y: float, pos_z: float, delta_x: float, delta_y: float, delta_z: float) -> None: ...
+
+
+class PointProbe(Probe):
+    def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_avg: int, t_start_out: int, t_out: int, output_timeseries: bool) -> None: ...
+    def add_probe_point(self, point_coord_x: float, point_coord_y: float, point_coord_z: float) -> None: ...
+    def add_probe_points_from_list(self, point_coords_x: List[float], point_coords_y: List[float], point_coords_z: List[float]) -> None: ...
+    def add_probe_points_from_x_normal_plane(self, pos_x: float, pos0_y: float, pos0_z: float, pos1_y: float, pos1_z: float, n_y: int, n_z: int) -> None: ...
+
+
 class WallModelProbe(Probe):
     def __init__(self, probe_name: str, output_path: str, t_start_avg: int, t_start_tmp_avg: int, t_avg: int, t_start_out: int, t_out: int) -> None: ...
     def set_evaluate_pressure_gradient(self, eval_press_grad: bool) -> None: ...
diff --git a/pythonbindings/pyfluids-stubs/bindings/logger.pyi b/pythonbindings/pyfluids-stubs/logger.pyi
similarity index 98%
rename from pythonbindings/pyfluids-stubs/bindings/logger.pyi
rename to pythonbindings/pyfluids-stubs/logger.pyi
index fe84eeb18f3245ef72ed023b2de9db7b9131d144..91c1346c2de2313de2c8df4a0b6d5eb4f4ab87bd 100644
--- a/pythonbindings/pyfluids-stubs/bindings/logger.pyi
+++ b/pythonbindings/pyfluids-stubs/logger.pyi
@@ -32,12 +32,16 @@ r"""
 ! \author Henry Korb
 =======================================================================================
 """
+from __future__ import annotations
+
+
 class Logger:
     @staticmethod
     def change_log_path(path: str) -> None: ...
     @staticmethod
     def initialize_logger() -> None: ...
 
+
 def vf_log_critical(message: str) -> None: ...
 def vf_log_debug(message: str) -> None: ...
 def vf_log_info(message: str) -> None: ...
diff --git a/pythonbindings/pyfluids/timeseries_probe_reader.py b/pythonbindings/pyfluids/timeseries_probe_reader.py
new file mode 100644
index 0000000000000000000000000000000000000000..d8aa7af05a82b92a1a9cab9ea791de897ac89c13
--- /dev/null
+++ b/pythonbindings/pyfluids/timeseries_probe_reader.py
@@ -0,0 +1,47 @@
+import numpy as np
+from pathlib import Path
+import pandas as pd
+#%%
+
+
+class TimeseriesProbeReader:
+    def __init__(self, file: Path):
+        self.file = file
+        self.quants, self.positions, self.data = \
+            self.read_file()
+
+    def read_file(self):
+        with open(self.file, "rb") as f:
+            header_length = 0
+            header_length += len(f.readline()) # first line
+            quant_line = f.readline()
+            header_length += len(f.readline()) # number of points
+            number_of_points_line = f.readline()
+            header_length += len(f.readline()) # positions
+            n_points = int(number_of_points_line)
+            positions = np.zeros((n_points, 3))
+            for i in range(n_points):
+                pos_line = f.readline()
+                header_length += len(pos_line)
+                positions[i] = [float(pos) for pos in pos_line.split(b", ")]
+
+        header_length += len(quant_line)
+        header_length += len(number_of_points_line)
+
+        quants = quant_line.decode().split(" ")[1:-1]
+        n_quants = len(quants)
+        data = np.fromfile(self.file, dtype=np.float32, offset=header_length)
+        n_timesteps = len(data)//(n_quants*n_points+1)
+        return quants, positions, data.reshape(n_timesteps, n_points*n_quants+1)
+    
+    def get_data(self):
+        return self.data
+    
+    def get_positions(self):
+        return self.positions
+    
+    def get_quantities(self):
+        return self.quants
+    
+    def to_dataframe(self):
+        return pd.DataFrame(self.data[:,1:], columns=self.quants, index=self.data[:,0])
\ No newline at end of file
diff --git a/pythonbindings/src/basics/basics.cpp b/pythonbindings/src/basics/basics.cpp
index 0b294b7a8de2f4f396dac418b0544b5f99ecec3d..126d8614e1b40ba0658a5335d5eb9d147309eae0 100644
--- a/pythonbindings/src/basics/basics.cpp
+++ b/pythonbindings/src/basics/basics.cpp
@@ -37,12 +37,8 @@ namespace basics
 {
     namespace py = pybind11;
 
-    py::module makeModule(py::module_ &parentModule)
+    PYBIND11_MODULE(basics, m)
     {
-        py::module basicsModule = parentModule.def_submodule("basics");
-
-        configuration::makeModule(basicsModule);
-
-        return basicsModule;
+        configuration::makeModule(m);
     }
 }
\ No newline at end of file
diff --git a/pythonbindings/src/basics/submodules/configuration_file.cpp b/pythonbindings/src/basics/submodules/configuration_file.cpp
index 7fcd48c34824b9370eeac1872c899bf980176a52..cb9154e23aa9df3dae66163b4703bfe4ecae0c31 100644
--- a/pythonbindings/src/basics/submodules/configuration_file.cpp
+++ b/pythonbindings/src/basics/submodules/configuration_file.cpp
@@ -53,7 +53,7 @@ namespace configuration
         .def("get_double_value", static_cast<double      (vf::basics::ConfigurationFile::*)(const std::string&, double     ) const>(&vf::basics::ConfigurationFile::getValue), py::arg("key"), py::arg("default_value"))
         .def("get_bool_value"  , static_cast<bool        (vf::basics::ConfigurationFile::*)(const std::string&) const>(&vf::basics::ConfigurationFile::getValue), py::arg("key"))
         .def("get_bool_value"  , static_cast<bool        (vf::basics::ConfigurationFile::*)(const std::string&, bool       ) const>(&vf::basics::ConfigurationFile::getValue), py::arg("key"), py::arg("default_value"))
-        .def("get_string_value", static_cast<std::string (vf::basics::ConfigurationFile::*)(const std::string&) const>(&vf::basics::ConfigurationFile::getValue), py::arg("key"))
+        .def("get_string_value", static_cast<std::string (vf::basics::ConfigurationFile::*)(const std::string&) const>(&vf::basics::ConfigurationFile::getValue<std::string>), py::arg("key"))
         .def("get_string_value", static_cast<std::string (vf::basics::ConfigurationFile::*)(const std::string&, std::string) const>(&vf::basics::ConfigurationFile::getValue), py::arg("key"), py::arg("default_value"));
     }
 }
\ No newline at end of file
diff --git a/pythonbindings/src/cpu/cpu.cpp b/pythonbindings/src/cpu/cpu.cpp
index 75143d913596c74a26f25ce64f1e6d214a442e34..baced0fc11afd6a12721759780d82f8a26d56cfc 100644
--- a/pythonbindings/src/cpu/cpu.cpp
+++ b/pythonbindings/src/cpu/cpu.cpp
@@ -38,18 +38,16 @@
 #include "submodules/simulationparameters.cpp"
 #include "submodules/writer.cpp"
 
-namespace cpu
+namespace cpu_bindings
 {
     namespace py = pybind11;
-    py::module makeModule(py::module_ &parentModule)
+    PYBIND11_MODULE(cpu, m)
     {
-        py::module cpuModule = parentModule.def_submodule("cpu");
-        boundaryconditions::makeModule(cpuModule);
-        simulation::makeModule(cpuModule);
-        geometry::makeModule(cpuModule);
-        kernel::makeModule(cpuModule);
-        parameters::makeModule(cpuModule);
-        writer::makeModule(cpuModule);
-        return cpuModule;
+        boundaryconditions::makeModule(m);
+        simulation::makeModule(m);
+        geometry::makeModule(m);
+        kernel::makeModule(m);
+        parameters::makeModule(m);
+        writer::makeModule(m);
     }
 }
\ No newline at end of file
diff --git a/pythonbindings/src/gpu/gpu.cpp b/pythonbindings/src/gpu/gpu.cpp
index 9eb160ae7765f16a6437e343cb878bb4b80877bf..8946b1d8af7655682a19e793119b27ab77f6f542 100644
--- a/pythonbindings/src/gpu/gpu.cpp
+++ b/pythonbindings/src/gpu/gpu.cpp
@@ -46,27 +46,25 @@
 #include "submodules/actuator_farm.cpp"
 #include "submodules/grid_scaling_factory.cpp"
 
-namespace gpu
+namespace gpu_bindings
 {
     namespace py = pybind11;
 
-    py::module makeModule(py::module_ &parentModule)
+    PYBIND11_MODULE(gpu, m)
     {
-        py::module gpuModule = parentModule.def_submodule("gpu");
-        simulation::makeModule(gpuModule);
-        parameter::makeModule(gpuModule);
-        pre_collision_interactor::makeModule(gpuModule);
-        actuator_farm::makeModule(gpuModule);
-        boundary_conditions::makeModule(gpuModule);
-        transient_bc_setter::makeModule(gpuModule);
-        communicator::makeModule(gpuModule); 
-        cuda_memory_manager::makeModule(gpuModule);
-        probes::makeModule(gpuModule);
-        precursor_writer::makeModule(gpuModule);
-        grid_generator::makeModule(gpuModule);
-        grid_provider::makeModule(gpuModule);
-        turbulence_model::makeModule(gpuModule);
-        grid_scaling_factory::makeModule(gpuModule);
-        return gpuModule;
+        simulation::makeModule(m);
+        parameter::makeModule(m);
+        pre_collision_interactor::makeModule(m);
+        actuator_farm::makeModule(m);
+        boundary_conditions::makeModule(m);
+        transient_bc_setter::makeModule(m);
+        communicator::makeModule(m); 
+        cuda_memory_manager::makeModule(m);
+        probes::makeModule(m);
+        precursor_writer::makeModule(m);
+        grid_generator::makeModule(m);
+        grid_provider::makeModule(m);
+        turbulence_model::makeModule(m);
+        grid_scaling_factory::makeModule(m);
     }
 }
\ No newline at end of file
diff --git a/pythonbindings/src/gpu/submodules/actuator_farm.cpp b/pythonbindings/src/gpu/submodules/actuator_farm.cpp
index a930616db3e0d0713bdf57157387d75d171603de..86e3f5a42152e60d6b62e32fb894406efc8384ea 100644
--- a/pythonbindings/src/gpu/submodules/actuator_farm.cpp
+++ b/pythonbindings/src/gpu/submodules/actuator_farm.cpp
@@ -30,10 +30,13 @@
 //! \ingroup submodules
 //! \author Henry Korb
 //=======================================================================================
+
 #include <pybind11/pybind11.h>
 #include <pybind11/numpy.h>
 #include <gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.h>
 #include <gpu/VirtualFluids_GPU/PreCollisionInteractor/PreCollisionInteractor.h>
+
+
 class PyActuatorFarm : public ActuatorFarm 
 {
 public:
@@ -43,13 +46,20 @@ public:
         PYBIND11_OVERRIDE_NAME(void, ActuatorFarm, "calc_blade_forces", calcBladeForces); 
     }
 };
+
 namespace actuator_farm
 {
     namespace py = pybind11;
 
+    template<class dtype>
+    dtype* np_to_arr(py::array_t<dtype, py::array::c_style> array){ return static_cast<dtype *>(array.request().ptr); };
+
+    template<class dtype>
+    intptr_t arr_to_cp(dtype* array){ return reinterpret_cast<intptr_t>(array); };
+
     void makeModule(py::module_ &parentModule)
     {
-        using arr = py::array_t<float, py::array::c_style>;
+        using arr = py::array_t<real, py::array::c_style>;
         
         py::class_<ActuatorFarm, PreCollisionInteractor, PyActuatorFarm, std::shared_ptr<ActuatorFarm>>(parentModule, "ActuatorFarm", py::dynamic_attr())
         .def(py::init<  const uint,
@@ -71,7 +81,7 @@ namespace actuator_farm
         .def_property_readonly("number_of_turbines", &ActuatorFarm::getNumberOfTurbines)
         .def_property_readonly("number_of_nodes_per_blade", &ActuatorFarm::getNumberOfNodesPerBlade)
         .def_property_readonly("number_of_blades_per_turbine", &ActuatorFarm::getNumberOfBladesPerTurbine)
-        .def_property_readonly("number_of_nodes", &ActuatorFarm::getNumberOfNodes)
+        .def_property_readonly("number_of_grid_nodes", &ActuatorFarm::getNumberOfGridNodes)
         .def_property_readonly("number_of_indices", &ActuatorFarm::getNumberOfIndices)
         .def_property_readonly("density", &ActuatorFarm::getDensity)
         .def_property_readonly("delta_t", &ActuatorFarm::getDeltaT)
@@ -79,7 +89,9 @@ namespace actuator_farm
 
         .def("add_turbine", &ActuatorFarm::addTurbine, py::arg("posX"), py::arg("posY"), py::arg("posZ"), py::arg("diameter"), py::arg("omega"), py::arg("azimuth"), py::arg("yaw"), py::arg("bladeRadii"))
 
-        .def("get_turbine_pos", [](ActuatorFarm& al, uint turbine){ real position[3] = {al.getTurbinePosX(turbine), al.getTurbinePosY(turbine), al.getTurbinePosZ(turbine)}; return arr(3,  position); }, py::arg("turbine"))
+        .def("get_turbine_pos", [](ActuatorFarm& al, uint turbine){ 
+            real position[3] = {al.getTurbinePosX(turbine), al.getTurbinePosY(turbine), al.getTurbinePosZ(turbine)}; return arr(3,  position);
+            }, py::arg("turbine"))
         .def("get_turbine_azimuth", &ActuatorFarm::getTurbineAzimuth, py::arg("turbine"))
         .def("get_turbine_yaw", &ActuatorFarm::getTurbineYaw, py::arg("turbine"))
         .def("get_turbine_omega", &ActuatorFarm::getTurbineOmega, py::arg("turbine"))
@@ -112,59 +124,53 @@ namespace actuator_farm
         .def("get_turbine_blade_forces_y", [](ActuatorFarm& al, uint turbine){ return arr({al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getTurbineBladeForcesYDevice(turbine)); }, py::arg("turbine") )
         .def("get_turbine_blade_forces_z", [](ActuatorFarm& al, uint turbine){ return arr({al.getNumberOfBladesPerTurbine(), al.getNumberOfNodesPerBlade()}, al.getTurbineBladeForcesZDevice(turbine)); }, py::arg("turbine") )
 
-        .def("get_all_blade_radii_device", [](ActuatorFarm& al) -> intptr_t { return reinterpret_cast<intptr_t>(al.getAllBladeRadiiDevice()); } )
-        .def("get_all_blade_coords_x_device", [](ActuatorFarm& al) -> intptr_t { return reinterpret_cast<intptr_t> (al.getAllBladeCoordsXDevice()); } )
-        .def("get_all_blade_coords_y_device", [](ActuatorFarm& al) -> intptr_t { return reinterpret_cast<intptr_t> (al.getAllBladeCoordsYDevice()); } )
-        .def("get_all_blade_coords_z_device", [](ActuatorFarm& al) -> intptr_t { return reinterpret_cast<intptr_t> (al.getAllBladeCoordsZDevice()); } )        
-        .def("get_all_blade_velocities_x_device", [](ActuatorFarm& al) -> intptr_t { return reinterpret_cast<intptr_t> (al.getAllBladeVelocitiesXDevice()); } )
-        .def("get_all_blade_velocities_y_device", [](ActuatorFarm& al) -> intptr_t { return reinterpret_cast<intptr_t> (al.getAllBladeVelocitiesYDevice()); } )
-        .def("get_all_blade_velocities_z_device", [](ActuatorFarm& al) -> intptr_t { return reinterpret_cast<intptr_t> (al.getAllBladeVelocitiesZDevice()); } )
-        .def("get_all_blade_forces_x_device", [](ActuatorFarm& al) -> intptr_t { return reinterpret_cast<intptr_t> (al.getAllBladeForcesXDevice()); } )
-        .def("get_all_blade_forces_y_device", [](ActuatorFarm& al) -> intptr_t { return reinterpret_cast<intptr_t> (al.getAllBladeForcesYDevice()); } )
-        .def("get_all_blade_forces_z_device", [](ActuatorFarm& al) -> intptr_t { return reinterpret_cast<intptr_t> (al.getAllBladeForcesZDevice()); } )
+        .def("get_all_blade_radii_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeRadiiDevice()); } )
+        .def("get_all_blade_coords_x_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeCoordsXDevice()); } )
+        .def("get_all_blade_coords_y_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeCoordsYDevice()); } )
+        .def("get_all_blade_coords_z_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeCoordsZDevice()); } )        
+        .def("get_all_blade_velocities_x_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeVelocitiesXDevice()); } )
+        .def("get_all_blade_velocities_y_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeVelocitiesYDevice()); } )
+        .def("get_all_blade_velocities_z_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeVelocitiesZDevice()); } )
+        .def("get_all_blade_forces_x_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeForcesXDevice()); } )
+        .def("get_all_blade_forces_y_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeForcesYDevice()); } )
+        .def("get_all_blade_forces_z_device", [](ActuatorFarm& al) -> intptr_t { return arr_to_cp(al.getAllBladeForcesZDevice()); } )
 
-        .def("get_turbine_blade_radii_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return reinterpret_cast<intptr_t>(al.getTurbineBladeRadiiDevice(turbine)); }, py::arg("turbine") )
-        .def("get_turbine_blade_coords_x_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return reinterpret_cast<intptr_t>(al.getTurbineBladeCoordsXDevice(turbine)); }, py::arg("turbine") )
-        .def("get_turbine_blade_coords_y_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return reinterpret_cast<intptr_t>(al.getTurbineBladeCoordsYDevice(turbine)); }, py::arg("turbine") )
-        .def("get_turbine_blade_coords_z_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return reinterpret_cast<intptr_t>(al.getTurbineBladeCoordsZDevice(turbine)); }, py::arg("turbine") )        
-        .def("get_turbine_blade_velocities_x_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return reinterpret_cast<intptr_t>(al.getTurbineBladeVelocitiesXDevice(turbine)); }, py::arg("turbine") )
-        .def("get_turbine_blade_velocities_y_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return reinterpret_cast<intptr_t>(al.getTurbineBladeVelocitiesYDevice(turbine)); }, py::arg("turbine") )
-        .def("get_turbine_blade_velocities_z_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return reinterpret_cast<intptr_t>(al.getTurbineBladeVelocitiesZDevice(turbine)); }, py::arg("turbine") )
-        .def("get_turbine_blade_forces_x_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return reinterpret_cast<intptr_t>(al.getTurbineBladeForcesXDevice(turbine)); }, py::arg("turbine") )
-        .def("get_turbine_blade_forces_y_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return reinterpret_cast<intptr_t>(al.getTurbineBladeForcesYDevice(turbine)); }, py::arg("turbine") )
-        .def("get_turbine_blade_forces_z_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return reinterpret_cast<intptr_t>(al.getTurbineBladeForcesZDevice(turbine)); }, py::arg("turbine") )
+        .def("get_turbine_blade_radii_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeRadiiDevice(turbine)); }, py::arg("turbine") )
+        .def("get_turbine_blade_coords_x_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeCoordsXDevice(turbine)); }, py::arg("turbine") )
+        .def("get_turbine_blade_coords_y_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeCoordsYDevice(turbine)); }, py::arg("turbine") )
+        .def("get_turbine_blade_coords_z_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeCoordsZDevice(turbine)); }, py::arg("turbine") )        
+        .def("get_turbine_blade_velocities_x_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeVelocitiesXDevice(turbine)); }, py::arg("turbine") )
+        .def("get_turbine_blade_velocities_y_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeVelocitiesYDevice(turbine)); }, py::arg("turbine") )
+        .def("get_turbine_blade_velocities_z_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeVelocitiesZDevice(turbine)); }, py::arg("turbine") )
+        .def("get_turbine_blade_forces_x_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeForcesXDevice(turbine)); }, py::arg("turbine") )
+        .def("get_turbine_blade_forces_y_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeForcesYDevice(turbine)); }, py::arg("turbine") )
+        .def("get_turbine_blade_forces_z_device", [](ActuatorFarm& al, uint turbine) -> intptr_t { return arr_to_cp(al.getTurbineBladeForcesZDevice(turbine)); }, py::arg("turbine") )
 
-        .def("set_all_azimuths", [](ActuatorFarm& al, arr azimuths){ al.setAllAzimuths(static_cast<float *>(azimuths.request().ptr)); }, py::arg("azimuths"))
-        .def("set_all_yaws", [](ActuatorFarm& al, arr yaws){ al.setAllYaws(static_cast<float *>(yaws.request().ptr)); }, py::arg("yaws"))
-        .def("set_all_omegas", [](ActuatorFarm& al, arr omegas){ al.setAllOmegas(static_cast<float *>(omegas.request().ptr)); }, py::arg("omegas"))
+        .def("set_all_azimuths", [](ActuatorFarm& al, arr azimuths){ al.setAllAzimuths(np_to_arr(azimuths)); }, py::arg("azimuths"))
+        .def("set_all_yaws", [](ActuatorFarm& al, arr yaws){ al.setAllYaws(np_to_arr(yaws)); }, py::arg("yaws"))
+        .def("set_all_omegas", [](ActuatorFarm& al, arr omegas){ al.setAllOmegas(np_to_arr(omegas)); }, py::arg("omegas"))
 
         .def("set_turbine_azimuth", &ActuatorFarm::setTurbineAzimuth, py::arg("turbine"), py::arg("azimuth"))
         .def("set_turbine_yaw", &ActuatorFarm::setTurbineYaw, py::arg("turbine"), py::arg("yaw"))
         .def("set_turbine_omega", &ActuatorFarm::setTurbineOmega, py::arg("turbine"), py::arg("omega"))
 
-        .def("set_all_blade_coords", [](ActuatorFarm& al, arr coordsX, arr coordsY, arr coordsZ)
-        { 
-            al.setAllBladeCoords(static_cast<float *>(coordsX.request().ptr), static_cast<float *>(coordsY.request().ptr), static_cast<float *>(coordsZ.request().ptr)); 
+        .def("set_all_blade_coords", [](ActuatorFarm& al, arr coordsX, arr coordsY, arr coordsZ){ 
+            al.setAllBladeCoords(np_to_arr(coordsX), np_to_arr(coordsY), np_to_arr(coordsZ)); 
         }, py::arg("blade_coords_x"), py::arg("blade_coords_y"), py::arg("blade_coords_z") )
-        .def("set_all_blade_velocities", [](ActuatorFarm& al, arr velocitiesX, arr velocitiesY, arr velocitiesZ)
-        { 
-            al.setAllBladeVelocities(static_cast<float *>(velocitiesX.request().ptr), static_cast<float *>(velocitiesY.request().ptr), static_cast<float *>(velocitiesZ.request().ptr)); 
+        .def("set_all_blade_velocities", [](ActuatorFarm& al, arr velocitiesX, arr velocitiesY, arr velocitiesZ){ 
+            al.setAllBladeVelocities(np_to_arr(velocitiesX), np_to_arr(velocitiesY), np_to_arr(velocitiesZ)); 
         }, py::arg("blade_velocities_x"), py::arg("blade_velocities_y"), py::arg("blade_velocities_z") )
-        .def("set_all_blade_forces", [](ActuatorFarm& al, arr forcesX, arr forcesY, arr forcesZ)
-        { 
-            al.setAllBladeForces(static_cast<float *>(forcesX.request().ptr), static_cast<float *>(forcesY.request().ptr), static_cast<float *>(forcesZ.request().ptr));
+        .def("set_all_blade_forces", [](ActuatorFarm& al, arr forcesX, arr forcesY, arr forcesZ){ 
+            al.setAllBladeForces(np_to_arr(forcesX), np_to_arr(forcesY), np_to_arr(forcesZ));
         }, py::arg("blade_forces_x"), py::arg("blade_forces_y"), py::arg("blade_forces_z") )     
-        .def("set_turbine_blade_coords", [](ActuatorFarm& al, uint turbine, arr coordsX, arr coordsY, arr coordsZ)
-        { 
-            al.setTurbineBladeCoords(turbine, static_cast<float *>(coordsX.request().ptr), static_cast<float *>(coordsY.request().ptr), static_cast<float *>(coordsZ.request().ptr)); 
+        .def("set_turbine_blade_coords", [](ActuatorFarm& al, uint turbine, arr coordsX, arr coordsY, arr coordsZ){ 
+            al.setTurbineBladeCoords(turbine, np_to_arr(coordsX), np_to_arr(coordsY), np_to_arr(coordsZ)); 
         }, py::arg("turbine"), py::arg("blade_coords_x"), py::arg("blade_coords_y"), py::arg("blade_coords_z") )
-        .def("set_turbine_blade_velocities", [](ActuatorFarm& al, uint turbine, arr velocitiesX, arr velocitiesY, arr velocitiesZ)
-        {
-            al.setTurbineBladeVelocities(turbine, static_cast<float *>(velocitiesX.request().ptr), static_cast<float *>(velocitiesY.request().ptr), static_cast<float *>(velocitiesZ.request().ptr)); 
+        .def("set_turbine_blade_velocities", [](ActuatorFarm& al, uint turbine, arr velocitiesX, arr velocitiesY, arr velocitiesZ){
+            al.setTurbineBladeVelocities(turbine, np_to_arr(velocitiesX), np_to_arr(velocitiesY), np_to_arr(velocitiesZ)); 
         }, py::arg("turbine"), py::arg("blade_velocities_x"), py::arg("blade_velocities_y"), py::arg("blade_velocities_z") )
-        .def("set_turbine_blade_forces", [](ActuatorFarm& al, uint turbine, arr forcesX, arr forcesY, arr forcesZ)
-        { 
-            al.setTurbineBladeForces(turbine, static_cast<float *>(forcesX.request().ptr), static_cast<float *>(forcesY.request().ptr), static_cast<float *>(forcesZ.request().ptr)); 
+        .def("set_turbine_blade_forces", [](ActuatorFarm& al, uint turbine, arr forcesX, arr forcesY, arr forcesZ){ 
+            al.setTurbineBladeForces(turbine, np_to_arr(forcesX), np_to_arr(forcesY), np_to_arr(forcesZ)); 
         }, py::arg("turbine"), py::arg("blade_forces_x"), py::arg("blade_forces_y"), py::arg("blade_forces_z") )
         .def("calc_blade_forces", &ActuatorFarm::calcBladeForces);
     }
diff --git a/pythonbindings/src/gpu/submodules/grid_generator.cpp b/pythonbindings/src/gpu/submodules/grid_generator.cpp
index 59d0bd5708b11f246664d1e8c7ee198f986d80c1..f4c2b733e7b099309b3fdc238ee71c22d940cced 100644
--- a/pythonbindings/src/gpu/submodules/grid_generator.cpp
+++ b/pythonbindings/src/gpu/submodules/grid_generator.cpp
@@ -42,6 +42,10 @@
 #include "gpu/GridGenerator/grid/GridBuilder/GridBuilder.h"
 #include "gpu/GridGenerator/grid/GridBuilder/LevelGridBuilder.h"
 #include "gpu/GridGenerator/grid/GridBuilder/MultipleGridBuilder.h"
+#include "basics/constants/NumericConstants.h"
+
+using namespace vf::basics::constant;
+
 
 namespace grid_generator
 {
@@ -91,16 +95,16 @@ namespace grid_generator
         .def("set_pressure_boundary_condition", &LevelGridBuilder::setPressureBoundaryCondition, py::arg("side_type"), py::arg("rho"))
         .def("set_periodic_boundary_condition", &LevelGridBuilder::setPeriodicBoundaryCondition, py::arg("periodic_x"), py::arg("periodic_y"), py::arg("periodic_z"))
         .def("set_no_slip_boundary_condition", &LevelGridBuilder::setNoSlipBoundaryCondition, py::arg("side_type"))
-        .def("set_precursor_boundary_condition", &LevelGridBuilder::setPrecursorBoundaryCondition, py::arg("side_type"), py::arg("file_collection"), py::arg("n_t_read"), py::arg("velocity_x")=0.0f, py::arg("velocity_y")=0.0f, py::arg("velocity_z")=0.0f, py::arg("file_level_to_grid_level_map")=std::vector<uint>())
+        .def("set_precursor_boundary_condition", &LevelGridBuilder::setPrecursorBoundaryCondition, py::arg("side_type"), py::arg("file_collection"), py::arg("n_t_read"), py::arg("velocity_x")=c0o1, py::arg("velocity_y")=c0o1, py::arg("velocity_z")=c0o1, py::arg("file_level_to_grid_level_map")=std::vector<uint>())
         .def("set_stress_boundary_condition", &LevelGridBuilder::setStressBoundaryCondition, py::arg("side_type"), py::arg("normal_x"), py::arg("normal_y"), py::arg("normal_z"), py::arg("sampling_offset"), py::arg("z0"), py::arg("dx"));
 
         py::class_<MultipleGridBuilder, LevelGridBuilder, std::shared_ptr<MultipleGridBuilder>>(gridGeneratorModule, "MultipleGridBuilder")
         .def_static("make_shared", &MultipleGridBuilder::makeShared, py::return_value_policy::reference, py::arg("grid_factory"))
         .def("add_coarse_grid", &MultipleGridBuilder::addCoarseGrid, py::arg("start_x"), py::arg("start_y"), py::arg("start_z"), py::arg("end_x"), py::arg("end_y"), py::arg("end_z"), py::arg("delta"))
-        .def("add_grid", py::overload_cast<Object*>(&MultipleGridBuilder::addGrid), py::arg("grid_shape"))
-        .def("add_grid", py::overload_cast<Object*, uint>(&MultipleGridBuilder::addGrid), py::arg("grid_shape"), py::arg("level_fine"))
-        .def("add_geometry", py::overload_cast<Object*>(&MultipleGridBuilder::addGeometry), py::arg("solid_object"))
-        .def("add_geometry", py::overload_cast<Object*, uint>(&MultipleGridBuilder::addGeometry), py::arg("solid_object"), py::arg("level"))
+        .def("add_grid", py::overload_cast<SPtr<Object>>(&MultipleGridBuilder::addGrid), py::arg("grid_shape"))
+        .def("add_grid", py::overload_cast<SPtr<Object>, uint>(&MultipleGridBuilder::addGrid), py::arg("grid_shape"), py::arg("level_fine"))
+        .def("add_geometry", py::overload_cast<SPtr<Object>>(&MultipleGridBuilder::addGeometry), py::arg("solid_object"))
+        .def("add_geometry", py::overload_cast<SPtr<Object>, uint>(&MultipleGridBuilder::addGeometry), py::arg("solid_object"), py::arg("level"))
         .def("get_number_of_levels", &MultipleGridBuilder::getNumberOfLevels)
         .def("build_grids", &MultipleGridBuilder::buildGrids, py::arg("enable_thin_walls"))
         .def("set_subdomain_box", &MultipleGridBuilder::setSubDomainBox, py::arg("bounding_box"))
diff --git a/pythonbindings/src/gpu/submodules/probes.cpp b/pythonbindings/src/gpu/submodules/probes.cpp
index 7c26958df81a60f00c9909a91f5576a5931652d4..9c3fc8ab15234013a093dbe00f6654ea3257d4b0 100644
--- a/pythonbindings/src/gpu/submodules/probes.cpp
+++ b/pythonbindings/src/gpu/submodules/probes.cpp
@@ -72,13 +72,16 @@ namespace probes
                         uint,
                         uint, 
                         uint,
-                        uint>(), 
+                        uint,
+                        bool>(), 
                         py::arg("probe_name"),
                         py::arg("output_path"),
                         py::arg("t_start_avg"),
                         py::arg("t_avg"),
                         py::arg("t_start_out"),
-                        py::arg("t_out"))
+                        py::arg("t_out"),
+                        py::arg("output_timeseries"))
+        .def("add_probe_point", &PointProbe::addProbePoint, py::arg("point_coord_x"), py::arg("point_coord_y"), py::arg("point_coord_z"))
         .def("add_probe_points_from_list", &PointProbe::addProbePointsFromList, py::arg("point_coords_x"), py::arg("point_coords_y"), py::arg("point_coords_z"))
         .def("add_probe_points_from_x_normal_plane", &PointProbe::addProbePointsFromXNormalPlane, py::arg("pos_x"), py::arg("pos0_y"), py::arg("pos0_z"), py::arg("pos1_y"), py::arg("pos1_z"), py::arg("n_y"), py::arg("n_z"));
 
diff --git a/pythonbindings/src/lbm/lbm.cpp b/pythonbindings/src/lbm.cpp
similarity index 93%
rename from pythonbindings/src/lbm/lbm.cpp
rename to pythonbindings/src/lbm.cpp
index 90fd4a71b0101469666936c89974de316e0e2b18..622cc9742fdaa98f2ff6d974e495e6b8b490a2c2 100644
--- a/pythonbindings/src/lbm/lbm.cpp
+++ b/pythonbindings/src/lbm.cpp
@@ -32,14 +32,11 @@
 //=======================================================================================
 #include <pybind11/pybind11.h>
 
-namespace lbm
+namespace lbm_bindings
 {
     namespace py = pybind11;
 
-    py::module makeModule(py::module_ &parentModule)
+    PYBIND11_MODULE(lbm, m)
     {
-        py::module lbmModule = parentModule.def_submodule("lbm");
-
-        return lbmModule;
     }
 }
\ No newline at end of file
diff --git a/pythonbindings/src/logger/logger.cpp b/pythonbindings/src/logger.cpp
similarity index 73%
rename from pythonbindings/src/logger/logger.cpp
rename to pythonbindings/src/logger.cpp
index c4c99c0a5077303b398e0726eaba0420ddb0dceb..367ae693475eca064c128de47c88e56fca91a58e 100644
--- a/pythonbindings/src/logger/logger.cpp
+++ b/pythonbindings/src/logger.cpp
@@ -33,25 +33,23 @@
 #include <pybind11/pybind11.h>
 #include <logger/Logger.h>
 
-namespace logging
+namespace logger_bindings
 {
+
     namespace py = pybind11;
 
-    py::module makeModule(py::module_ &parentModule)
+    PYBIND11_MODULE(logger, m)
     {
-        py::module loggerModule = parentModule.def_submodule("logger");
-
-        py::class_<vf::logging::Logger>(loggerModule, "Logger")
+        py::class_<vf::logging::Logger>(m, "Logger")
         .def_static("initialize_logger", &vf::logging::Logger::initializeLogger)
         .def_static("change_log_path", &vf::logging::Logger::changeLogPath, py::arg("path"));
 
         // use f-strings (f"text {float}") in python for compounded messages
-        loggerModule.def("vf_log_trace", [](std::string message){ VF_LOG_TRACE(message); }, py::arg("message"));        
-        loggerModule.def("vf_log_debug", [](std::string message){ VF_LOG_DEBUG(message); }, py::arg("message"));        
-        loggerModule.def("vf_log_info", [](std::string message){ VF_LOG_INFO(message); }, py::arg("message"));        
-        loggerModule.def("vf_log_warning", [](std::string message){ VF_LOG_WARNING(message); }, py::arg("message"));        
-        loggerModule.def("vf_log_critical", [](std::string message){ VF_LOG_CRITICAL(message); }, py::arg("message"));        
-
-        return loggerModule;
+        m.def("vf_log_trace", [](std::string message){ VF_LOG_TRACE(message); }, py::arg("message"));        
+        m.def("vf_log_debug", [](std::string message){ VF_LOG_DEBUG(message); }, py::arg("message"));        
+        m.def("vf_log_info", [](std::string message){ VF_LOG_INFO(message); }, py::arg("message"));        
+        m.def("vf_log_warning", [](std::string message){ VF_LOG_WARNING(message); }, py::arg("message"));        
+        m.def("vf_log_critical", [](std::string message){ VF_LOG_CRITICAL(message); }, py::arg("message"));       
     }
-} // namespace logging
+}
+
diff --git a/regression-tests/flow_around_cylinder_test.sh b/regression-tests/flow_around_cylinder_test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..63f90886b79002dcffe6beb24e626922ca95fe78
--- /dev/null
+++ b/regression-tests/flow_around_cylinder_test.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+source ./regression-tests/__regression_test_executer.sh
+
+
+# 1. set reference data directory (must match the folder structure in https://github.com/irmb/test_data)
+REFERENCE_DATA_DIR=regression_tests/cpu/FlowAroundCylinder_2023_04
+
+# 2. set cmake flags for the build of VirtualFluids
+CMAKE_FLAGS="--preset=make_cpu -DCMAKE_BUILD_TYPE=Release"
+
+# 3. define the application to be executed
+APPLICATION="./build/bin/FlowAroundCylinder ./apps/cpu/FlowAroundCylinder/cylinder.cfg"
+
+# 4. set the path to the produced data
+RESULT_DATA_DIR=output/FlowAroundCylinder
+
+
+run_regression_test "$REFERENCE_DATA_DIR" "$CMAKE_FLAGS" "$APPLICATION" "$RESULT_DATA_DIR"
diff --git a/regression-tests/multigpu_test/rocket4GPU.yml b/regression-tests/multigpu_test/rocket4GPU.yml
index a05ffea6ad04e0d5cfb8d7749111726dfceb4609..a7ece055707c26a7a27e9c12be3447dc1b77855f 100755
--- a/regression-tests/multigpu_test/rocket4GPU.yml
+++ b/regression-tests/multigpu_test/rocket4GPU.yml
@@ -37,7 +37,7 @@ copy:
 
 collect:
   - from: multigpu_test/output/4GPU/
-    to: output/4GPU
+    to: output/4GPU/
     overwrite: true
 
   - from: multigpu_test/slurm4GPU.out
@@ -45,7 +45,7 @@ collect:
     overwrite: true
 
 clean:
-  - multigpu_test/output/*
+  - multigpu_test/*
 
 sbatch: multigpu_test/slurm4GPU.job
 continue_if_job_fails: true
diff --git a/regression-tests/multigpu_test/rocket8GPU.yml b/regression-tests/multigpu_test/rocket8GPU.yml
index e8cc08a9fa39425686a16d193dba1743533994bc..4b434fc8a2433dab513649800dbe3f160d986edd 100755
--- a/regression-tests/multigpu_test/rocket8GPU.yml
+++ b/regression-tests/multigpu_test/rocket8GPU.yml
@@ -37,7 +37,7 @@ copy:
 
 collect:
   - from: multigpu_test/output/8GPU/
-    to: output/8GPU
+    to: output/8GPU/
     overwrite: true
 
   - from: multigpu_test/slurm8GPU.out
@@ -45,7 +45,7 @@ collect:
     overwrite: true
 
 clean:
-  - multigpu_test/output/*
+  - multigpu_test/*
 
 sbatch: multigpu_test/slurm8GPU.job
 continue_if_job_fails: true
diff --git a/regression-tests/multigpu_test/slurm4GPU.job b/regression-tests/multigpu_test/slurm4GPU.job
index 70b33f07f4a4a7be7f5b50990098f3322238af4a..0be42c51bac9a341b56eb705f9bdb518883f507d 100755
--- a/regression-tests/multigpu_test/slurm4GPU.job
+++ b/regression-tests/multigpu_test/slurm4GPU.job
@@ -2,14 +2,19 @@
 
 #SBATCH --partition=gpu01_queue
 #SBATCH --nodes=1
-#SBATCH --time=10:00:00
+#SBATCH --time=03:00:00
 #SBATCH --job-name=Regr4GPU
 #SBATCH --ntasks-per-node=4
 #SBATCH --gres=gpu:4
 #SBATCH --output=multigpu_test/slurm4GPU.out
 ##SBATCH --exclusive
 
-module purge 
+echo "SLURM_JOBID="$SLURM_JOBID
+echo "SLURM_JOB_NODELIST"=$SLURM_JOB_NODELIST
+echo "SLURM_NNODES"=$SLURM_NNODES
+echo "SLURM_TASKS_PER_NODE"=$SLURM_TASKS_PER_NODE
+
+module purge
 module load comp/gcc/10.2.0
 module load mpi/openmpi/4.0.5_gcc_9.3/openmpi
 module load cuda/11.3
@@ -19,7 +24,7 @@ PATH=/home/irmb/tools/cmake-3.20.3-linux-x86_64/bin:$PATH
 module list
 
 cd multigpu_test
-rm -r build && mkdir -p build
+rm -rf build && mkdir -p build
 cd build
 cmake .. -DBUILD_VF_GPU=ON -DCMAKE_CUDA_ARCHITECTURES=60 -DUSER_APPS=apps/gpu/LBM/DrivenCavityMultiGPU\;apps/gpu/LBM/SphereScaling
 make -j 16
diff --git a/regression-tests/multigpu_test/slurm8GPU.job b/regression-tests/multigpu_test/slurm8GPU.job
index b91d7d473d935d4d0fbe8deba344dbaa58cf5080..bb7bf55c70eb6b178eff3f52e18c35d7cafd6938 100755
--- a/regression-tests/multigpu_test/slurm8GPU.job
+++ b/regression-tests/multigpu_test/slurm8GPU.job
@@ -2,14 +2,19 @@
 
 #SBATCH --partition=gpu01_queue
 #SBATCH --nodes=2
-#SBATCH --time=10:00:00
+#SBATCH --time=03:00:00
 #SBATCH --job-name=Regr8GPU
 #SBATCH --ntasks-per-node=4
 #SBATCH --gres=gpu:4
 #SBATCH --output=multigpu_test/slurm8GPU.out
 ##SBATCH --exclusive
 
-module purge 
+echo "SLURM_JOBID="$SLURM_JOBID
+echo "SLURM_JOB_NODELIST"=$SLURM_JOB_NODELIST
+echo "SLURM_NNODES"=$SLURM_NNODES
+echo "SLURM_TASKS_PER_NODE"=$SLURM_TASKS_PER_NODE
+
+module purge
 module load comp/gcc/10.2.0
 module load mpi/openmpi/4.0.5_gcc_9.3/openmpi
 module load cuda/11.3
@@ -19,7 +24,7 @@ PATH=/home/irmb/tools/cmake-3.20.3-linux-x86_64/bin:$PATH
 module list
 
 cd multigpu_test
-rm -r build && mkdir -p build
+rm -rf build && mkdir -p build
 cd build
 cmake .. -DBUILD_VF_GPU=ON -DCMAKE_CUDA_ARCHITECTURES=60 -DUSER_APPS=apps/gpu/LBM/DrivenCavityMultiGPU\;apps/gpu/LBM/SphereScaling
 make -j 16
diff --git a/regression-tests/multigpu_test/utilities/parsejobid.py b/regression-tests/multigpu_test/utilities/parsejobid.py
new file mode 100644
index 0000000000000000000000000000000000000000..f209f6d3d0ac20243a94d16f89d2aaddeeae24f7
--- /dev/null
+++ b/regression-tests/multigpu_test/utilities/parsejobid.py
@@ -0,0 +1,20 @@
+from pathlib import Path
+import sys
+
+LAUNCH_MESSAGE = "Launched job"
+
+
+def parsejobid(file: str) -> str:
+    file_path = Path(file)
+    if not file_path.exists():
+        raise FileNotFoundError(file)
+
+    text_content = file_path.read_text().strip()
+    launch_line = next(
+        filter(lambda line: LAUNCH_MESSAGE in line, text_content.splitlines())
+    )
+    return launch_line.split()[-1].strip()
+
+
+if __name__ == "__main__":
+    print(parsejobid(sys.argv[1]))
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index 5894f9dec06953c3eeb909af96db9cb19d202d65..0000000000000000000000000000000000000000
--- a/setup.cfg
+++ /dev/null
@@ -1,11 +0,0 @@
-[metadata]
-name = pyfluids
-description = Python binding for VirtualFluids
-long_description = file: README.md
-long_description_content_type = text/markdown
-platforms = any
-url = https://git.rz.tu-bs.de/irmb/virtualfluids
-version = 0.1.0
-
-[options]
-python_requires = >=3.6
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 530431b3775970b5222bc87d32bfb407363f95d6..0000000000000000000000000000000000000000
--- a/setup.py
+++ /dev/null
@@ -1,72 +0,0 @@
-import sys
-from pathlib import Path
-from typing import List
-
-import skbuild
-
-"""
-Install python wrapper of Virtual Fluids
-install via python:
-    python setup.py install
-    set CMAKE Flags via -DBUILD_VF_GPU:BOOL=ON
-    CMAKE flags have to be separated by -- 
-    example: python setup.py install -- -DBUILD_VF_CPU:BOOL=ON
-or install via pip:
-    pip install .
-    for pip>21:
-        set CMAKE Flags via --config-settings "-DBUILD_VF_GPU=ON"
-        example: pip install . --config-settings="-DBUILD_VF_GPU=ON"
-        each option has to be passed in individually i.e --config-settings="-DOPT1=ON" --config-settings="-DOPT2=OFF"
-    for pip <21:
-        set CMAKE Flags via --global-option ="-DBUILD_VF_GPU=ON"
-        example: pip install . --global-option="-DBUILD_VF_GPU=ON"
-"""
-
-package_name = "pyfluids"
-target = "python_bindings"
-src_dir = "pythonbindings"
-stub_package = package_name+"-stubs"
-
-stub_dir = Path(src_dir)/stub_package
-
-
-def add_subfiles(dir_path: Path, suffix: str, root_dir: Path) -> List[str]:
-    files = []
-    for f in dir_path.iterdir():
-        if f.is_dir():
-            files.extend(add_subfiles(f, suffix, root_dir))
-        if f.is_file():
-            if f.suffix != suffix:
-                continue
-            files.append(str(f.relative_to(root_dir)))
-    return files
-
-def add_directory(dir_path: Path, suffix: str):
-    return add_subfiles(dir_path, suffix, dir_path)
-
-stub_files = add_directory(stub_dir, ".pyi")
-
-# hack to get config-args for installation with pip>21
-cmake_args = []
-if "config_args" in locals():
-    cmake_args.extend([f"{k}={v}" for k, v in locals()["config_args"].items()])
-
-cmake_args += [
-        f"-DPython3_ROOT_DIR={Path(sys.prefix)}",
-        "-DBUILD_VF_PYTHON_BINDINGS=ON",
-        "-DBUILD_SHARED_LIBS=OFF",
-        "-DBUILD_VF_DOUBLE_ACCURACY=OFF",
-        "-DBUILD_VF_UNIT_TESTS:BOOL=OFF",
-        "-DBUILD_WARNINGS_AS_ERRORS=OFF",
-    ]
-
-skbuild.setup(
-    name=package_name,
-    packages=[package_name, "pymuparser", "pyfluids-stubs"],
-    package_dir={"": src_dir},
-    cmake_args=cmake_args,
-    cmake_install_target=target,
-    package_data={  "pyfluids": ["py.typed"],
-                    "pyfluids-stubs": stub_files},
-    include_package_data=True,
-)
diff --git a/src/basics/StringUtilities/StringUtilTest.cpp b/src/basics/StringUtilities/StringUtilTest.cpp
index 52f9511b3774a03f6d6f1e19536839825eff1394..0b229dfd8696490a02f01c0ed3f4fac859c6157c 100644
--- a/src/basics/StringUtilities/StringUtilTest.cpp
+++ b/src/basics/StringUtilities/StringUtilTest.cpp
@@ -6,12 +6,6 @@
 
 #include "StringUtil.h"
 
-int main(int argc, char *argv[])
-{
-    testing::InitGoogleTest(&argc, argv);
-    testing::InitGoogleMock(&argc, argv);
-    return RUN_ALL_TESTS();
-}
 
 TEST(StringUtilTest, endsWith_shouldReturnTrue)
 {
diff --git a/src/basics/config/ConfigurationFile.cpp b/src/basics/config/ConfigurationFile.cpp
index 547468cd2fd6aadccbdc5017230fcf6cdb803733..b714203913b739998cce007d98dccacb1cc99a4e 100644
--- a/src/basics/config/ConfigurationFile.cpp
+++ b/src/basics/config/ConfigurationFile.cpp
@@ -67,27 +67,19 @@ bool ConfigurationFile::load(const std::string& file)
    return true;
 }
 
-//////////////////////////////////////////////////////////////////////////
-template<>
-bool ConfigurationFile::fromString<bool>(const std::string& str) const
-{
-   return str == "true";
-}
-
 //////////////////////////////////////////////////////////////////////////
 bool ConfigurationFile::contains(const std::string& key) const
 {
    return data.find(key) != data.end();
 }
 //////////////////////////////////////////////////////////////////////////
-std::string ConfigurationFile::getString(const std::string& key) const
+std::string ConfigurationFile::getValue(const std::string& key) const
 {
    std::map<std::string, std::string>::const_iterator iter = data.find(key);
 
    if (iter != data.end())
    {
-      std::string value = iter->second;
-      return value;
+      return iter->second;
    }
    else
    {
diff --git a/src/basics/config/ConfigurationFile.h b/src/basics/config/ConfigurationFile.h
index 8ca12306e0ef321832efb19a2a428e6dc753df41..6c651b7039d91c7312c4b98f32e1a97b8b6433de 100644
--- a/src/basics/config/ConfigurationFile.h
+++ b/src/basics/config/ConfigurationFile.h
@@ -1,7 +1,8 @@
 #ifndef BASICS_CONFIGURATIONFILE_H
 #define BASICS_CONFIGURATIONFILE_H
 
-#include "Logger.h"
+#include <logger/Logger.h>
+
 #include <filesystem>
 #include <map>
 #include <vector>
@@ -9,7 +10,7 @@
 #include <string>
 #include <fstream>
 #include <iostream>
-#include <stdlib.h>
+#include <cstdlib>
 
 #include <basics/utilities/UbException.h>
 
@@ -38,7 +39,7 @@
 //!bool           writeLogFile = config.getValue<bool>("writeLogFile");
 //!string         errorMessage = config.getValue<string>("errorMessage");
 //!vector<double> origin       = config.getVector<double>("origin");
-//!            
+//!
 //! \author  Konstantin Kutscher
 
 
@@ -70,36 +71,20 @@ public:
    template<class T>
    T getValue(const std::string& key, T defaultValue) const;
 
-   static ConfigurationFile loadConfig(int argc, char *argv[], std::string configPath = "./config.txt")
-   {
-      // the config file's default path can be replaced by passing a command line argument
-
-      if (argc > 1) 
-      {
-         configPath = argv[1];
-         VF_LOG_INFO("Using command line argument for config path: {}", configPath);
-      } else {
-         VF_LOG_INFO("Using default config path: {}", configPath);
-      }
-
-      vf::basics::ConfigurationFile config;
-      config.load(configPath);
-      return config;
-   }
+   //! the container is public to test this class
+   std::map<std::string, std::string> data;
 
 private:
    //! the container
-   std::map<std::string, std::string> data;
-
    //! get string with key
-   std::string  getString(const std::string& key) const;
+   std::string getValue(const std::string& key) const;
 
    //! remove leading and trailing tabs and spaces
    static std::string trim(const std::string& str);
 
    //! convert string to data type T
    template<class T>
-   T fromString(const std::string& str) const;
+   T convert_to(const std::string& str) const;
 
    void split(std::vector<std::string>& lst, const std::string& input, const std::string& separators, bool remove_empty = true) const;
 };
@@ -109,56 +94,44 @@ private:
 template<class T>
 std::vector<T> ConfigurationFile::getVector(const std::string& key) const
 {
-   std::string str = getString(key);
-   std::vector<T> v;
-   std::vector<std::string> strings;
-   split(strings, str, "\t\n\r;, ");
-   for (std::vector<std::string>::iterator it = strings.begin(); it != strings.end(); ++it)
+   std::string string_value = getValue(key);
+   std::vector<T> values;
+   std::vector<std::string> string_vector;
+   split(string_vector, string_value, "\t\n\r;, ");
+   for (std::vector<std::string>::iterator it = string_vector.begin(); it != string_vector.end(); ++it)
    {
       if (*it != "")
       {
-         v.push_back(fromString<T>(*it));
+         values.push_back(convert_to<T>(*it));
       }
    }
-   return v;
+   return values;
 }
 //////////////////////////////////////////////////////////////////////////
 template<class T>
-T ConfigurationFile::fromString(const std::string& str) const
+T ConfigurationFile::convert_to(const std::string& value) const
 {
-   std::istringstream stream(str);
+   if constexpr (std::is_same_v<T, bool>)
+   {
+      return (value == "true");
+   }
+
+   std::istringstream stream(value);
    T t;
    stream >> t;
+    if (stream.fail())
+      throw UbException(UB_EXARGS, " cannot convert \"" + value + "\" to type <" + static_cast<std::string>(typeid(t).name()) + ">");
+
    return t;
 }
 
-template<>
-bool ConfigurationFile::fromString<bool>(const std::string& str) const;
-
 //////////////////////////////////////////////////////////////////////////
 template<class T>
 T ConfigurationFile::getValue(const std::string& key) const
 {
-   std::string str = getString(key);
-   bool bFlag = false;
-   if ((std::string)typeid(T).name() == (std::string)typeid(bool).name()) 
-   {
-      bFlag = true;
-   }
-
-   std::istringstream iss(str);
-   T x;
-   iss >> x;
-   if (!iss && !bFlag)
-      UB_THROW(UbException(UB_EXARGS, " cannot convert \"" + str + "\" to type <" + static_cast<std::string>(typeid(x).name()) + ">"));
+   std::string value = getValue(key);
 
-   if (bFlag)
-   {
-      bool value = (str == "true");
-      x = value;
-   }
-
-   return x;
+   return convert_to<T>(value);
 }
 
 template<class T>
@@ -174,6 +147,24 @@ T ConfigurationFile::getValue(const std::string& key, T defaultValue) const
    }
 }
 
+static ConfigurationFile loadConfig(int argc, char *argv[], std::string configPath = "./config.txt")
+{
+   // the config file's default path can be replaced by passing a command line argument
+
+   if (argc > 1)
+   {
+      configPath = argv[1];
+      VF_LOG_INFO("Using command line argument for config path: {}", configPath);
+   } else {
+      VF_LOG_INFO("Using default config path: {}", configPath);
+   }
+
+   vf::basics::ConfigurationFile config;
+   config.load(configPath);
+   return config;
+}
+
+
 }
 
 #endif
diff --git a/src/basics/config/ConfigurationFileTest.cpp b/src/basics/config/ConfigurationFileTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f935b4ab95287cc8e2a20c882bd89b74d636cdf6
--- /dev/null
+++ b/src/basics/config/ConfigurationFileTest.cpp
@@ -0,0 +1,124 @@
+#include <gmock/gmock.h>
+
+#include "ConfigurationFile.h"
+
+using namespace vf::basics;
+
+TEST(ConfigurationFileTest, ContainsReturnsTrueForExistingKey)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "value1";
+   config.data["key2"] = "value2";
+
+   EXPECT_TRUE(config.contains("key1"));
+   EXPECT_TRUE(config.contains("key2"));
+}
+
+TEST(ConfigurationFileTest, ContainsReturnsFalseForMissingKey)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "value1";
+
+   EXPECT_FALSE(config.contains("key2"));
+}
+
+TEST(ConfigurationFileTest, GetValueReturnsCorrectValue)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "value1";
+   config.data["key2"] = "1234";
+
+   EXPECT_EQ(config.getValue<std::string>("key1"), "value1");
+   EXPECT_EQ(config.getValue<int>("key2"), 1234);
+}
+
+TEST(ConfigurationFileTest, GetValueThrowsExceptionForMissingKey)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "value1";
+
+   EXPECT_THROW(config.getValue<std::string>("key2"), UbException);
+}
+
+TEST(ConfigurationFileTest, GetVectorReturnsCorrectValues)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "1, 2, 3";
+   config.data["key2"] = "4; 5; 6";
+
+   std::vector<int> v1 = config.getVector<int>("key1");
+   std::vector<int> v2 = config.getVector<int>("key2");
+
+   EXPECT_EQ(v1.size(), 3);
+   EXPECT_EQ(v1[0], 1);
+   EXPECT_EQ(v1[1], 2);
+   EXPECT_EQ(v1[2], 3);
+
+   EXPECT_EQ(v2.size(), 3);
+   EXPECT_EQ(v2[0], 4);
+   EXPECT_EQ(v2[1], 5);
+   EXPECT_EQ(v2[2], 6);
+}
+
+TEST(ConfigurationFileTest, GetVectorThrowsExceptionForMissingKey)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "1, 2, 3";
+
+   EXPECT_THROW(config.getVector<int>("key2"), UbException);
+}
+
+TEST(ConfigurationFileTest, GetValueReturnsDefaultValueForMissingKey)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "value1";
+
+   int defaultValue = 42;
+   int value = config.getValue<int>("key2", defaultValue);
+
+   EXPECT_EQ(value, defaultValue);
+}
+
+TEST(ConfigurationFileTest, GetValueReturnsCorrectValueForExistingKey)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "42";
+
+   int defaultValue = 0;
+   int value = config.getValue<int>("key1", defaultValue);
+
+   EXPECT_EQ(value, 42);
+}
+
+TEST(ConfigurationFileTest, FromStringConvertsValueToBool)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "true";
+   config.data["key2"] = "false";
+
+   bool valueTrue = config.getValue<bool>("key1");
+   bool valueFalse = config.getValue<bool>("key2");
+
+   EXPECT_TRUE(valueTrue);
+   EXPECT_FALSE(valueFalse);
+}
+
+
+TEST(ConfigurationFileTest, GetValueThrowsExceptionForWrongTypeConversion)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "text";
+
+   EXPECT_THROW(config.getVector<int>("key1"), UbException);;
+}
+
+TEST(ConfigurationFileTest, ClearRemovesAllData)
+{
+   ConfigurationFile config;
+   config.data["key1"] = "value1";
+   config.data["key2"] = "value2";
+
+   config.clear();
+
+   EXPECT_TRUE(config.data.empty());
+}
\ No newline at end of file
diff --git a/src/cpu/LiggghtsCoupling/3rdParty/LiggghtsCouplingWrapper.cpp b/src/cpu/LiggghtsCoupling/3rdParty/LiggghtsCouplingWrapper.cpp
index 9be87887a26d654d03dc8a32ed9e456ec352fef2..c745e8a67b5a628321e27ea1132b55fba4bebd95 100644
--- a/src/cpu/LiggghtsCoupling/3rdParty/LiggghtsCouplingWrapper.cpp
+++ b/src/cpu/LiggghtsCoupling/3rdParty/LiggghtsCouplingWrapper.cpp
@@ -70,7 +70,7 @@ void LiggghtsCouplingWrapper::setVariable(char const *name, std::string &value)
 void LiggghtsCouplingWrapper::run(int nSteps)
 {
   std::stringstream cmd;
-  cmd << "run " << nSteps;
+  cmd << "run " << nSteps << " pre no post no";
   execCommand(cmd);
 }
 void LiggghtsCouplingWrapper::runUpto(int nSteps)
diff --git a/src/cpu/LiggghtsCoupling/LBM/IBcumulantK17LBMKernel.cpp b/src/cpu/LiggghtsCoupling/LBM/IBcumulantK17LBMKernel.cpp
index ea39fc17d606498a4b977d77a5151f4fff6e216c..efe93f4c951684e41e6dd1c4d2b81c57c711727f 100644
--- a/src/cpu/LiggghtsCoupling/LBM/IBcumulantK17LBMKernel.cpp
+++ b/src/cpu/LiggghtsCoupling/LBM/IBcumulantK17LBMKernel.cpp
@@ -27,7 +27,7 @@
 //  with VirtualFluids (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
 //! \file IBcumulantK17LBMKernel.cpp
-//! \ingroup LBM
+//! \ingroup LiggghtsCoupling
 //! \author Konstantin Kutscher, Martin Geier
 //=======================================================================================
 #include "IBcumulantK17LBMKernel.h"
@@ -134,9 +134,9 @@ void IBcumulantK17LBMKernel::calculate(int step)
     }
     /////////////////////////////////////
 
-    localDistributions = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
-    nonLocalDistributions = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
-    restDistributions = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
+    localDistributionsF = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
+    nonLocalDistributionsF = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
+    restDistributionsF = dynamic_pointer_cast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
 
     SPtr<BCArray3D> bcArray = this->getBCSet()->getBCArray();
 
@@ -191,35 +191,35 @@ void IBcumulantK17LBMKernel::calculate(int step)
                     // a b c
                     //-1 0 1
 
-                    LBMReal mfcbb = (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3);
-                    LBMReal mfbcb = (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3);
-                    LBMReal mfbbc = (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3);
-                    LBMReal mfccb = (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3);
-                    LBMReal mfacb = (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3);
-                    LBMReal mfcbc = (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3);
-                    LBMReal mfabc = (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3);
-                    LBMReal mfbcc = (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3);
-                    LBMReal mfbac = (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3);
-                    LBMReal mfccc = (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3);
-                    LBMReal mfacc = (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3);
-                    LBMReal mfcac = (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3);
-                    LBMReal mfaac = (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3);
-
-                    LBMReal mfabb = (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3);
-                    LBMReal mfbab = (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3);
-                    LBMReal mfbba = (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p);
-                    LBMReal mfaab = (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3);
-                    LBMReal mfcab = (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3);
-                    LBMReal mfaba = (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p);
-                    LBMReal mfcba = (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p);
-                    LBMReal mfbaa = (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p);
-                    LBMReal mfbca = (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p);
-                    LBMReal mfaaa = (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p);
-                    LBMReal mfcaa = (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p);
-                    LBMReal mfaca = (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p);
-                    LBMReal mfcca = (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p);
-
-                    LBMReal mfbbb = (*this->restDistributions)(x1, x2, x3);
+                    LBMReal mfcbb = (*this->localDistributionsF)(D3Q27System::ET_E, x1, x2, x3);
+                    LBMReal mfbcb = (*this->localDistributionsF)(D3Q27System::ET_N, x1, x2, x3);
+                    LBMReal mfbbc = (*this->localDistributionsF)(D3Q27System::ET_T, x1, x2, x3);
+                    LBMReal mfccb = (*this->localDistributionsF)(D3Q27System::ET_NE, x1, x2, x3);
+                    LBMReal mfacb = (*this->localDistributionsF)(D3Q27System::ET_NW, x1p, x2, x3);
+                    LBMReal mfcbc = (*this->localDistributionsF)(D3Q27System::ET_TE, x1, x2, x3);
+                    LBMReal mfabc = (*this->localDistributionsF)(D3Q27System::ET_TW, x1p, x2, x3);
+                    LBMReal mfbcc = (*this->localDistributionsF)(D3Q27System::ET_TN, x1, x2, x3);
+                    LBMReal mfbac = (*this->localDistributionsF)(D3Q27System::ET_TS, x1, x2p, x3);
+                    LBMReal mfccc = (*this->localDistributionsF)(D3Q27System::ET_TNE, x1, x2, x3);
+                    LBMReal mfacc = (*this->localDistributionsF)(D3Q27System::ET_TNW, x1p, x2, x3);
+                    LBMReal mfcac = (*this->localDistributionsF)(D3Q27System::ET_TSE, x1, x2p, x3);
+                    LBMReal mfaac = (*this->localDistributionsF)(D3Q27System::ET_TSW, x1p, x2p, x3);
+
+                    LBMReal mfabb = (*this->nonLocalDistributionsF)(D3Q27System::ET_W, x1p, x2, x3);
+                    LBMReal mfbab = (*this->nonLocalDistributionsF)(D3Q27System::ET_S, x1, x2p, x3);
+                    LBMReal mfbba = (*this->nonLocalDistributionsF)(D3Q27System::ET_B, x1, x2, x3p);
+                    LBMReal mfaab = (*this->nonLocalDistributionsF)(D3Q27System::ET_SW, x1p, x2p, x3);
+                    LBMReal mfcab = (*this->nonLocalDistributionsF)(D3Q27System::ET_SE, x1, x2p, x3);
+                    LBMReal mfaba = (*this->nonLocalDistributionsF)(D3Q27System::ET_BW, x1p, x2, x3p);
+                    LBMReal mfcba = (*this->nonLocalDistributionsF)(D3Q27System::ET_BE, x1, x2, x3p);
+                    LBMReal mfbaa = (*this->nonLocalDistributionsF)(D3Q27System::ET_BS, x1, x2p, x3p);
+                    LBMReal mfbca = (*this->nonLocalDistributionsF)(D3Q27System::ET_BN, x1, x2, x3p);
+                    LBMReal mfaaa = (*this->nonLocalDistributionsF)(D3Q27System::ET_BSW, x1p, x2p, x3p);
+                    LBMReal mfcaa = (*this->nonLocalDistributionsF)(D3Q27System::ET_BSE, x1, x2p, x3p);
+                    LBMReal mfaca = (*this->nonLocalDistributionsF)(D3Q27System::ET_BNW, x1p, x2, x3p);
+                    LBMReal mfcca = (*this->nonLocalDistributionsF)(D3Q27System::ET_BNE, x1, x2, x3p);
+
+                    LBMReal mfbbb = (*this->restDistributionsF)(x1, x2, x3);
 
                     LBMReal f[D3Q27System::ENDF + 1];
                     LBMReal fEq[D3Q27System::ENDF + 1];
@@ -753,35 +753,35 @@ void IBcumulantK17LBMKernel::calculate(int step)
                     //! href="https://doi.org/10.3390/computation5020019"><b>[ M. Geier et al. (2017),
                     //! DOI:10.3390/computation5020019 ]</b></a>
                     //!
-                    (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3)     = mfabb;
-                    (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3)     = mfbab;
-                    (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3)     = mfbba;
-                    (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3)    = mfaab;
-                    (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3)   = mfcab;
-                    (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3)    = mfaba;
-                    (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3)   = mfcba;
-                    (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3)    = mfbaa;
-                    (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3)   = mfbca;
-                    (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3)   = mfaaa;
-                    (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3)  = mfcaa;
-                    (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3)  = mfaca;
-                    (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3) = mfcca;
-
-                    (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3)     = mfcbb;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3)     = mfbcb;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p)     = mfbbc;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3)   = mfccb;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3)    = mfacb;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p)   = mfcbc;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p)    = mfabc;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p)   = mfbcc;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p)    = mfbac;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p) = mfccc;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p)  = mfacc;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p)  = mfcac;
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p)   = mfaac;
-
-                    (*this->restDistributions)(x1, x2, x3) = mfbbb;
+                    (*this->localDistributionsF)(D3Q27System::ET_E, x1, x2, x3)     = mfabb;
+                    (*this->localDistributionsF)(D3Q27System::ET_N, x1, x2, x3)     = mfbab;
+                    (*this->localDistributionsF)(D3Q27System::ET_T, x1, x2, x3)     = mfbba;
+                    (*this->localDistributionsF)(D3Q27System::ET_NE, x1, x2, x3)    = mfaab;
+                    (*this->localDistributionsF)(D3Q27System::ET_NW, x1p, x2, x3)   = mfcab;
+                    (*this->localDistributionsF)(D3Q27System::ET_TE, x1, x2, x3)    = mfaba;
+                    (*this->localDistributionsF)(D3Q27System::ET_TW, x1p, x2, x3)   = mfcba;
+                    (*this->localDistributionsF)(D3Q27System::ET_TN, x1, x2, x3)    = mfbaa;
+                    (*this->localDistributionsF)(D3Q27System::ET_TS, x1, x2p, x3)   = mfbca;
+                    (*this->localDistributionsF)(D3Q27System::ET_TNE, x1, x2, x3)   = mfaaa;
+                    (*this->localDistributionsF)(D3Q27System::ET_TNW, x1p, x2, x3)  = mfcaa;
+                    (*this->localDistributionsF)(D3Q27System::ET_TSE, x1, x2p, x3)  = mfaca;
+                    (*this->localDistributionsF)(D3Q27System::ET_TSW, x1p, x2p, x3) = mfcca;
+
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_W, x1p, x2, x3)     = mfcbb;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_S, x1, x2p, x3)     = mfbcb;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_B, x1, x2, x3p)     = mfbbc;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_SW, x1p, x2p, x3)   = mfccb;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_SE, x1, x2p, x3)    = mfacb;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BW, x1p, x2, x3p)   = mfcbc;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BE, x1, x2, x3p)    = mfabc;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BS, x1, x2p, x3p)   = mfbcc;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BN, x1, x2, x3p)    = mfbac;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BSW, x1p, x2p, x3p) = mfccc;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BSE, x1, x2p, x3p)  = mfacc;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BNW, x1p, x2, x3p)  = mfcac;
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BNE, x1, x2, x3p)   = mfaac;
+
+                    (*this->restDistributionsF)(x1, x2, x3) = mfbbb;
                     //////////////////////////////////////////////////////////////////////////
                     f[vf::lbm::dir::DIR_000] = mfbbb;
                      
@@ -813,91 +813,93 @@ void IBcumulantK17LBMKernel::calculate(int step)
                     f[vf::lbm::dir::DIR_MPM]  = mfaca;
                     f[vf::lbm::dir::DIR_PPM]  = mfcca;
                 }
-                    if ((*particleData)(x1, x2, x3)->solidFraction < SOLFRAC_MIN)
-                        continue;
-
-                    LBMReal vx1, vx2, vx3, drho;
-                    D3Q27System::calcCompMacroscopicValues(f, drho, vx1, vx2, vx3);
-                    D3Q27System::calcCompFeq(fEq, drho, vx1, vx2, vx3);
-
-                    std::array<double, 3> uPart;
-                    uPart[0] = (*particleData)(x1, x2, x3)->uPart[0] * (1. + drho);
-                    uPart[1] = (*particleData)(x1, x2, x3)->uPart[1] * (1. + drho);
-                    uPart[2] = (*particleData)(x1, x2, x3)->uPart[2] * (1. + drho);
-
-                    D3Q27System::calcCompFeq(fEqSolid, drho, uPart[0], uPart[1], uPart[2]);
-
-                    if ((*particleData)(x1, x2, x3)->solidFraction > SOLFRAC_MAX) {
-                    double const bb0 = fEq[vf::lbm::dir::DIR_000] - fEqSolid[vf::lbm::dir::DIR_000];
-                    f[vf::lbm::dir::DIR_000] = fPre[vf::lbm::dir::DIR_000] + bb0;
-                        for (int iPop = D3Q27System::FSTARTDIR; iPop <= D3Q27System::FENDDIR; iPop++) {
-                            const int iOpp        = D3Q27System::INVDIR[iPop];
-                            double const bb       = ((fPre[iOpp] - fEq[iOpp]) - (fPre[iPop] - fEqSolid[iPop]));
-                            double const bbOpp    = ((fPre[iPop] - fEq[iPop]) - (fPre[iOpp] - fEqSolid[iOpp]));
-
-
-                            f[iPop] = fPre[iPop] + bb;
-                            f[iOpp] = fPre[iOpp] + bbOpp;
-
-                            (*particleData)(x1, x2, x3)->hydrodynamicForce[0] -= D3Q27System::DX1[iPop] * (bb - bbOpp);
-                            (*particleData)(x1, x2, x3)->hydrodynamicForce[1] -= D3Q27System::DX2[iPop] * (bb - bbOpp);
-                            (*particleData)(x1, x2, x3)->hydrodynamicForce[2] -= D3Q27System::DX3[iPop] * (bb - bbOpp);
-                        }
-                    } else { /* particleData.solidFraction < SOLFRAC_MAX */
-//#ifdef LBDEM_USE_WEIGHING
-                        double const ooo = 1. / omega - 0.5;
-                        double const B   = (*particleData)(x1, x2, x3)->solidFraction * ooo / ((1. - (*particleData)(x1, x2, x3)->solidFraction) + ooo);
-//#else
-//                        T const B = particleData.solidFraction;
-//#endif
-                        double const oneMinB = 1. - B;
-
-                        double const bb0 = fEq[vf::lbm::dir::DIR_000] - fEqSolid[vf::lbm::dir::DIR_000];
-                        f[vf::lbm::dir::DIR_000] = fPre[vf::lbm::dir::DIR_000] + oneMinB * (f[vf::lbm::dir::DIR_000] - fPre[vf::lbm::dir::DIR_000]) + B * bb0;
-
-                        for (int iPop = D3Q27System::FSTARTDIR; iPop <= D3Q27System::FENDDIR; iPop++) {
-                            int const iOpp = D3Q27System::INVDIR[iPop];
-                            double const bb       = B * ((fPre[iOpp] - fEq[iOpp]) - (fPre[iPop] - fEqSolid[iPop]));
-                            double const bbOpp    = B * ((fPre[iPop] - fEq[iPop]) - (fPre[iOpp] - fEqSolid[iOpp]));
-
-                            f[iPop] = fPre[iPop] + oneMinB * (f[iPop] - fPre[iPop]) + bb;
-                            f[iOpp] = fPre[iOpp] + oneMinB * (f[iOpp] - fPre[iOpp]) + bbOpp;
-
-                            (*particleData)(x1, x2, x3)->hydrodynamicForce[0] -= D3Q27System::DX1[iPop] * (bb - bbOpp);
-                            (*particleData)(x1, x2, x3)->hydrodynamicForce[1] -= D3Q27System::DX2[iPop] * (bb - bbOpp);
-                            (*particleData)(x1, x2, x3)->hydrodynamicForce[2] -= D3Q27System::DX3[iPop] * (bb - bbOpp);
-                        }
-                    } /* if solidFraction > SOLFRAC_MAX */
-
-                    (*this->restDistributions)(x1, x2, x3)                             = f[vf::lbm::dir::DIR_000];
-                                                                                          
-                    (*this->localDistributions)(D3Q27System::ET_E, x1, x2, x3)         = f[vf::lbm::dir::DIR_M00];
-                    (*this->localDistributions)(D3Q27System::ET_N, x1, x2, x3)         = f[vf::lbm::dir::DIR_0M0];
-                    (*this->localDistributions)(D3Q27System::ET_T, x1, x2, x3)         = f[vf::lbm::dir::DIR_00M];
-                    (*this->localDistributions)(D3Q27System::ET_NE, x1, x2, x3)        = f[vf::lbm::dir::DIR_MM0];
-                    (*this->localDistributions)(D3Q27System::ET_NW, x1p, x2, x3)       = f[vf::lbm::dir::DIR_PM0];
-                    (*this->localDistributions)(D3Q27System::ET_TE, x1, x2, x3)        = f[vf::lbm::dir::DIR_M0M];
-                    (*this->localDistributions)(D3Q27System::ET_TW, x1p, x2, x3)       = f[vf::lbm::dir::DIR_P0M];
-                    (*this->localDistributions)(D3Q27System::ET_TN, x1, x2, x3)        = f[vf::lbm::dir::DIR_0MM];
-                    (*this->localDistributions)(D3Q27System::ET_TS, x1, x2p, x3)       = f[vf::lbm::dir::DIR_0PM];
-                    (*this->localDistributions)(D3Q27System::ET_TNE, x1, x2, x3)       = f[vf::lbm::dir::DIR_MMM];
-                    (*this->localDistributions)(D3Q27System::ET_TNW, x1p, x2, x3)      = f[vf::lbm::dir::DIR_PMM];
-                    (*this->localDistributions)(D3Q27System::ET_TSE, x1, x2p, x3)      = f[vf::lbm::dir::DIR_MPM];
-                    (*this->localDistributions)(D3Q27System::ET_TSW, x1p, x2p, x3)     = f[vf::lbm::dir::DIR_PPM];
-                                                                                              
-                    (*this->nonLocalDistributions)(D3Q27System::ET_W, x1p, x2, x3)     = f[vf::lbm::dir::DIR_P00];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_S, x1, x2p, x3)     = f[vf::lbm::dir::DIR_0P0];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_B, x1, x2, x3p)     = f[vf::lbm::dir::DIR_00P];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_SW, x1p, x2p, x3)   = f[vf::lbm::dir::DIR_PP0];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_SE, x1, x2p, x3)    = f[vf::lbm::dir::DIR_MP0];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BW, x1p, x2, x3p)   = f[vf::lbm::dir::DIR_P0P];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BE, x1, x2, x3p)    = f[vf::lbm::dir::DIR_M0P];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BS, x1, x2p, x3p)   = f[vf::lbm::dir::DIR_0PP];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BN, x1, x2, x3p)    = f[vf::lbm::dir::DIR_0MP];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BSW, x1p, x2p, x3p) = f[vf::lbm::dir::DIR_PPP];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BSE, x1, x2p, x3p)  = f[vf::lbm::dir::DIR_MPP];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BNW, x1p, x2, x3p)  = f[vf::lbm::dir::DIR_PMP];
-                    (*this->nonLocalDistributions)(D3Q27System::ET_BNE, x1, x2, x3p)   = f[vf::lbm::dir::DIR_MMP];
+                    if ((*particleData)(x1, x2, x3)->solidFraction >= SOLFRAC_MIN) {
+                    //                    if ((*particleData)(x1, x2, x3)->solidFraction < SOLFRAC_MIN)
+                    //                        continue;
+                    //
+                                        LBMReal vx1, vx2, vx3, drho;
+                                        D3Q27System::calcCompMacroscopicValues(f, drho, vx1, vx2, vx3);
+                                        D3Q27System::calcCompFeq(fEq, drho, vx1, vx2, vx3);
+                    
+                                        std::array<double, 3> uPart;
+                                        uPart[0] = (*particleData)(x1, x2, x3)->uPart[0] * (1. + drho);
+                                        uPart[1] = (*particleData)(x1, x2, x3)->uPart[1] * (1. + drho);
+                                        uPart[2] = (*particleData)(x1, x2, x3)->uPart[2] * (1. + drho);
+                    
+                                        D3Q27System::calcCompFeq(fEqSolid, drho, uPart[0], uPart[1], uPart[2]);
+                    
+                                        if ((*particleData)(x1, x2, x3)->solidFraction > SOLFRAC_MAX) {
+                                        double const bb0 = fEq[vf::lbm::dir::DIR_000] - fEqSolid[vf::lbm::dir::DIR_000];
+                                        f[vf::lbm::dir::DIR_000] = fPre[vf::lbm::dir::DIR_000] + bb0;
+                                            for (int iPop = D3Q27System::FSTARTDIR; iPop <= D3Q27System::FENDDIR; iPop++) {
+                                                const int iOpp        = D3Q27System::INVDIR[iPop];
+                                                double const bb       = ((fPre[iOpp] - fEq[iOpp]) - (fPre[iPop] - fEqSolid[iPop]));
+                                                double const bbOpp    = ((fPre[iPop] - fEq[iPop]) - (fPre[iOpp] - fEqSolid[iOpp]));
+                    
+                    
+                                                f[iPop] = fPre[iPop] + bb;
+                                                f[iOpp] = fPre[iOpp] + bbOpp;
+                    
+                                                (*particleData)(x1, x2, x3)->hydrodynamicForce[0] -= D3Q27System::DX1[iPop] * (bb - bbOpp);
+                                                (*particleData)(x1, x2, x3)->hydrodynamicForce[1] -= D3Q27System::DX2[iPop] * (bb - bbOpp);
+                                                (*particleData)(x1, x2, x3)->hydrodynamicForce[2] -= D3Q27System::DX3[iPop] * (bb - bbOpp);
+                                            }
+                                        } else { /* particleData.solidFraction < SOLFRAC_MAX */
+                    //#ifdef LBDEM_USE_WEIGHING
+                                            double const ooo = 1. / omega - 0.5;
+                                            double const B   = (*particleData)(x1, x2, x3)->solidFraction * ooo / ((1. - (*particleData)(x1, x2, x3)->solidFraction) + ooo);
+                    //#else
+                    //                        T const B = particleData.solidFraction;
+                    //#endif
+                                            double const oneMinB = 1. - B;
+                    
+                                            double const bb0 = fEq[vf::lbm::dir::DIR_000] - fEqSolid[vf::lbm::dir::DIR_000];
+                                            f[vf::lbm::dir::DIR_000] = fPre[vf::lbm::dir::DIR_000] + oneMinB * (f[vf::lbm::dir::DIR_000] - fPre[vf::lbm::dir::DIR_000]) + B * bb0;
+                    
+                                            for (int iPop = D3Q27System::FSTARTDIR; iPop <= D3Q27System::FENDDIR; iPop++) {
+                                                int const iOpp = D3Q27System::INVDIR[iPop];
+                                                double const bb       = B * ((fPre[iOpp] - fEq[iOpp]) - (fPre[iPop] - fEqSolid[iPop]));
+                                                double const bbOpp    = B * ((fPre[iPop] - fEq[iPop]) - (fPre[iOpp] - fEqSolid[iOpp]));
+                    
+                                                f[iPop] = fPre[iPop] + oneMinB * (f[iPop] - fPre[iPop]) + bb;
+                                                f[iOpp] = fPre[iOpp] + oneMinB * (f[iOpp] - fPre[iOpp]) + bbOpp;
+                    
+                                                (*particleData)(x1, x2, x3)->hydrodynamicForce[0] -= D3Q27System::DX1[iPop] * (bb - bbOpp);
+                                                (*particleData)(x1, x2, x3)->hydrodynamicForce[1] -= D3Q27System::DX2[iPop] * (bb - bbOpp);
+                                                (*particleData)(x1, x2, x3)->hydrodynamicForce[2] -= D3Q27System::DX3[iPop] * (bb - bbOpp);
+                                            }
+                                        } /* if solidFraction > SOLFRAC_MAX */
+
+                    (*this->restDistributionsF)(x1, x2, x3) = f[vf::lbm::dir::DIR_000];
+
+                    (*this->localDistributionsF)(D3Q27System::ET_E, x1, x2, x3) = f[vf::lbm::dir::DIR_M00];
+                    (*this->localDistributionsF)(D3Q27System::ET_N, x1, x2, x3) = f[vf::lbm::dir::DIR_0M0];
+                    (*this->localDistributionsF)(D3Q27System::ET_T, x1, x2, x3) = f[vf::lbm::dir::DIR_00M];
+                    (*this->localDistributionsF)(D3Q27System::ET_NE, x1, x2, x3) = f[vf::lbm::dir::DIR_MM0];
+                    (*this->localDistributionsF)(D3Q27System::ET_NW, x1p, x2, x3) = f[vf::lbm::dir::DIR_PM0];
+                    (*this->localDistributionsF)(D3Q27System::ET_TE, x1, x2, x3) = f[vf::lbm::dir::DIR_M0M];
+                    (*this->localDistributionsF)(D3Q27System::ET_TW, x1p, x2, x3) = f[vf::lbm::dir::DIR_P0M];
+                    (*this->localDistributionsF)(D3Q27System::ET_TN, x1, x2, x3) = f[vf::lbm::dir::DIR_0MM];
+                    (*this->localDistributionsF)(D3Q27System::ET_TS, x1, x2p, x3) = f[vf::lbm::dir::DIR_0PM];
+                    (*this->localDistributionsF)(D3Q27System::ET_TNE, x1, x2, x3) = f[vf::lbm::dir::DIR_MMM];
+                    (*this->localDistributionsF)(D3Q27System::ET_TNW, x1p, x2, x3) = f[vf::lbm::dir::DIR_PMM];
+                    (*this->localDistributionsF)(D3Q27System::ET_TSE, x1, x2p, x3) = f[vf::lbm::dir::DIR_MPM];
+                    (*this->localDistributionsF)(D3Q27System::ET_TSW, x1p, x2p, x3) = f[vf::lbm::dir::DIR_PPM];
+
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_W, x1p, x2, x3) = f[vf::lbm::dir::DIR_P00];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_S, x1, x2p, x3) = f[vf::lbm::dir::DIR_0P0];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_B, x1, x2, x3p) = f[vf::lbm::dir::DIR_00P];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_SW, x1p, x2p, x3) = f[vf::lbm::dir::DIR_PP0];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_SE, x1, x2p, x3) = f[vf::lbm::dir::DIR_MP0];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BW, x1p, x2, x3p) = f[vf::lbm::dir::DIR_P0P];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BE, x1, x2, x3p) = f[vf::lbm::dir::DIR_M0P];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BS, x1, x2p, x3p) = f[vf::lbm::dir::DIR_0PP];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BN, x1, x2, x3p) = f[vf::lbm::dir::DIR_0MP];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BSW, x1p, x2p, x3p) = f[vf::lbm::dir::DIR_PPP];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BSE, x1, x2p, x3p) = f[vf::lbm::dir::DIR_MPP];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BNW, x1p, x2, x3p) = f[vf::lbm::dir::DIR_PMP];
+                    (*this->nonLocalDistributionsF)(D3Q27System::ET_BNE, x1, x2, x3p) = f[vf::lbm::dir::DIR_MMP];
+                    }
                 }
             }
         }
diff --git a/src/cpu/LiggghtsCoupling/LBM/IBcumulantK17LBMKernel.h b/src/cpu/LiggghtsCoupling/LBM/IBcumulantK17LBMKernel.h
index 985ba75df5f0d726868e4ff854c384ad62eeb630..d675e72aabd3122a01e092e99fa22eb491270805 100644
--- a/src/cpu/LiggghtsCoupling/LBM/IBcumulantK17LBMKernel.h
+++ b/src/cpu/LiggghtsCoupling/LBM/IBcumulantK17LBMKernel.h
@@ -34,7 +34,7 @@
 #ifndef IBcumulantK17LBMKernel_h__
 #define IBcumulantK17LBMKernel_h__
 
-#include "LBMKernel.h"
+#include "LiggghtsCouplingLBMKernel.h"
 #include "BCSet.h"
 #include "D3Q27System.h"
 #include "UbTiming.h"
@@ -50,7 +50,7 @@
 //! <a href="http://dx.doi.org/10.1016/j.jcp.2017.05.040"><b>[ Geier et al., (2017), 10.1016/j.jcp.2017.05.040]</b></a>,
 //! <a href="http://dx.doi.org/10.1016/j.jcp.2017.07.004"><b>[ Geier et al., (2017), 10.1016/j.jcp.2017.07.004]</b></a>
 //!
-class IBcumulantK17LBMKernel : public LBMKernel
+class IBcumulantK17LBMKernel : public LiggghtsCouplingLBMKernel
 {
 public:
     IBcumulantK17LBMKernel();
@@ -58,11 +58,6 @@ public:
     void calculate(int step) override;
     SPtr<LBMKernel> clone() override;
     double getCalculationTime() override { return .0; }
-    CbArray3D<SPtr<IBdynamicsParticleData>, IndexerX3X2X1>::CbArray3DPtr getParticleData() { return particleData; };
-    void setParticleData(CbArray3D<SPtr<IBdynamicsParticleData>, IndexerX3X2X1>::CbArray3DPtr particleData)
-    {
-        this->particleData = particleData;
-    };
 
 protected:
     inline void forwardInverseChimeraWithK(LBMReal& mfa, LBMReal& mfb, LBMReal& mfc, LBMReal vv, LBMReal v2, LBMReal Kinverse, LBMReal K);
@@ -72,9 +67,9 @@ protected:
 
     virtual void initDataSet();
 
-    CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributions;
-    CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributions;
-    CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr restDistributions;
+    CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr localDistributionsF;
+    CbArray4D<LBMReal, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributionsF;
+    CbArray3D<LBMReal, IndexerX3X2X1>::CbArray3DPtr restDistributionsF;
 
     mu::value_type muX1, muX2, muX3;
     mu::value_type muDeltaT;
@@ -83,7 +78,6 @@ protected:
     LBMReal forcingX2;
     LBMReal forcingX3;
 
-    CbArray3D<SPtr<IBdynamicsParticleData>, IndexerX3X2X1>::CbArray3DPtr particleData;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/cpu/LiggghtsCoupling/LBM/IBsharpInterfaceLBMKernel.cpp b/src/cpu/LiggghtsCoupling/LBM/IBsharpInterfaceLBMKernel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c502c4b48150e558aa785fa1bdc8c16bbecc1986
--- /dev/null
+++ b/src/cpu/LiggghtsCoupling/LBM/IBsharpInterfaceLBMKernel.cpp
@@ -0,0 +1,1795 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  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 IBsharpInterfaceLBMKernel.cpp
+//! \ingroup LBMKernel
+//! \author M. Geier, K. Kutscher, Hesameddin Safari
+//=======================================================================================
+
+#include "BCArray3D.h"
+#include "Block3D.h"
+#include "D3Q27EsoTwist3DSplittedVector.h"
+#include "D3Q27System.h"
+#include "DataSet3D.h"
+#include "LBMKernel.h"
+#include "IBsharpInterfaceLBMKernel.h"
+#include "NonNewtonianFluids/LBM/Rheology.h"
+#include <cmath>
+#include <iostream>
+#include <string>
+
+#define PROOF_CORRECTNESS
+
+using namespace vf::lbm::dir;
+using namespace vf::basics::constant;
+
+//////////////////////////////////////////////////////////////////////////
+IBsharpInterfaceLBMKernel::IBsharpInterfaceLBMKernel()
+{
+    this->compressible = false;
+}
+//////////////////////////////////////////////////////////////////////////
+void IBsharpInterfaceLBMKernel::initDataSet()
+{
+    SPtr<DistributionArray3D> f(new D3Q27EsoTwist3DSplittedVector(nx[0] + 4, nx[1] + 4, nx[2] + 4, -999.9));
+    SPtr<DistributionArray3D> h(new D3Q27EsoTwist3DSplittedVector(nx[0] + 4, nx[1] + 4, nx[2] + 4, -999.9)); // For phase-field
+    // SPtr<DistributionArray3D> h2(new D3Q27EsoTwist3DSplittedVector(nx[0] + 4, nx[1] + 4, nx[2] + 4, -999.9));
+    // SPtr<PhaseFieldArray3D> divU1(new PhaseFieldArray3D(            nx[0] + 4, nx[1] + 4, nx[2] + 4, 0.0));
+    // CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr pressure(new  CbArray3D<real, IndexerX3X2X1>(    nx[0] + 4, nx[1] + 4, nx[2] + 4, 0.0));
+    // pressureOld = CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr(new  CbArray3D<real, IndexerX3X2X1>(nx[0] + 4, nx[1] + 4, nx[2] + 4, 0.0));
+    // p1Old = CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr(new  CbArray3D<real, IndexerX3X2X1>(nx[0] + 4, nx[1] + 4, nx[2] + 4, 0.0));
+
+    rhoNode = CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<real, IndexerX3X2X1>(nx[0] + 4, nx[1] + 4, nx[2] + 4, 0.0));
+    vxNode = CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<real, IndexerX3X2X1>(nx[0] + 4, nx[1] + 4, nx[2] + 4, 0.0));
+    vyNode = CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<real, IndexerX3X2X1>(nx[0] + 4, nx[1] + 4, nx[2] + 4, 0.0));
+    vzNode = CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<real, IndexerX3X2X1>(nx[0] + 4, nx[1] + 4, nx[2] + 4, 0.0));
+    dataSet->setFdistributions(f);
+    dataSet->setHdistributions(h); // For phase-field
+    // dataSet->setH2distributions(h2);
+    // dataSet->setPhaseField(divU1);
+    // dataSet->setPressureField(pressure);
+
+    phaseField = CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<real, IndexerX3X2X1>(nx[0] + 4, nx[1] + 4, nx[2] + 4, -999.0));
+    phaseFieldOld = CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<real, IndexerX3X2X1>(nx[0] + 4, nx[1] + 4, nx[2] + 4, 999.0));
+
+    particleData = std::make_shared<CbArray3D<SPtr<IBdynamicsParticleData>, IndexerX3X2X1>>(nx[0] + 4, nx[1] + 4, nx[2] + 4);
+
+    // divU = CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr(new CbArray3D<real, IndexerX3X2X1>(nx[0] + 4, nx[1] + 4, nx[2] + 4, 0.0));
+    int minX1 = 0;
+    int minX2 = 0;
+    int minX3 = 0;
+    int maxX1 = nx[0] + 4;
+    int maxX2 = nx[1] + 4;
+    int maxX3 = nx[2] + 4;
+
+        for (int x3 = minX3; x3 < maxX3; x3++) {
+        for (int x2 = minX2; x2 < maxX2; x2++) {
+            for (int x1 = minX1; x1 < maxX1; x1++) {
+                (*particleData)(x1, x2, x3) = std::make_shared<IBdynamicsParticleData>();
+            }
+        }
+    }
+}
+//////////////////////////////////////////////////////////////////////////
+SPtr<LBMKernel> IBsharpInterfaceLBMKernel::clone()
+{
+    SPtr<LBMKernel> kernel(new IBsharpInterfaceLBMKernel());
+    kernel->setNX(nx);
+    dynamicPointerCast<IBsharpInterfaceLBMKernel>(kernel)->initDataSet();
+    kernel->setCollisionFactorMultiphase(this->collFactorL, this->collFactorG);
+    kernel->setDensityRatio(this->densityRatio);
+    // kernel->setMultiphaseModelParameters(this->beta, this->kappa);
+    kernel->setSigma(this->sigma);
+    kernel->setContactAngle(this->contactAngle);
+    kernel->setPhiL(this->phiL);
+    kernel->setPhiH(this->phiH);
+    kernel->setPhaseFieldRelaxation(this->tauH);
+    kernel->setMobility(this->mob);
+    kernel->setInterfaceWidth(this->interfaceWidth);
+
+    kernel->setBCSet(bcSet->clone(kernel));
+    kernel->setWithForcing(withForcing);
+    kernel->setForcingX1(muForcingX1);
+    kernel->setForcingX2(muForcingX2);
+    kernel->setForcingX3(muForcingX3);
+    kernel->setIndex(ix1, ix2, ix3);
+    kernel->setDeltaT(deltaT);
+    kernel->setGhostLayerWidth(2);
+    dynamicPointerCast<IBsharpInterfaceLBMKernel>(kernel)->initForcing();
+
+    return kernel;
+}
+//////////////////////////////////////////////////////////////////////////
+void IBsharpInterfaceLBMKernel::forwardInverseChimeraWithKincompressible(real &mfa, real &mfb, real &mfc, real vv, real v2, real Kinverse, real K, real oneMinusRho)
+{
+    // using namespace UbMath;
+    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;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void IBsharpInterfaceLBMKernel::backwardInverseChimeraWithKincompressible(real &mfa, real &mfb, real &mfc, real vv, real v2, real Kinverse, real K, real oneMinusRho)
+{
+    // using namespace UbMath;
+    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;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void IBsharpInterfaceLBMKernel::forwardChimera(real &mfa, real &mfb, real &mfc, real vv, real v2)
+{
+    // using namespace UbMath;
+    real m1 = (mfa + mfc) + mfb;
+    real m2 = mfc - mfa;
+    mfc = (mfc + mfa) + (v2 * m1 - c2o1 * vv * m2);
+    mfb = m2 - vv * m1;
+    mfa = m1;
+}
+
+void IBsharpInterfaceLBMKernel::backwardChimera(real &mfa, real &mfb, real &mfc, real vv, real v2)
+{
+    // using namespace UbMath;
+    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;
+}
+
+void IBsharpInterfaceLBMKernel::calculate(int step)
+{
+    using namespace D3Q27System;
+    // using namespace UbMath;
+
+    forcingX1 = 0.0;
+    forcingX2 = 0.0;
+    forcingX3 = 0.0;
+
+    real oneOverInterfaceScale = c4o1 / interfaceWidth; // 1.0;//1.5;
+                                                        /////////////////////////////////////
+
+    localDistributionsF = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getLocalDistributions();
+    nonLocalDistributionsF = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getNonLocalDistributions();
+    restDistributionsF = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(dataSet->getFdistributions())->getZeroDistributions();
+
+    localDistributionsH1 = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(dataSet->getHdistributions())->getLocalDistributions();
+    nonLocalDistributionsH1 = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(dataSet->getHdistributions())->getNonLocalDistributions();
+    restDistributionsH1 = dynamicPointerCast<D3Q27EsoTwist3DSplittedVector>(dataSet->getHdistributions())->getZeroDistributions();
+
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr pressure = dataSet->getPressureField();
+
+    SPtr<BCArray3D> bcArray = this->getBCSet()->getBCArray();
+
+    const int bcArrayMaxX1 = (int)bcArray->getNX1();
+    const int bcArrayMaxX2 = (int)bcArray->getNX2();
+    const int bcArrayMaxX3 = (int)bcArray->getNX3();
+
+    int minX1 = ghostLayerWidth;
+    int minX2 = ghostLayerWidth;
+    int minX3 = ghostLayerWidth;
+    int maxX1 = bcArrayMaxX1 - ghostLayerWidth;
+    int maxX2 = bcArrayMaxX2 - ghostLayerWidth;
+    int maxX3 = bcArrayMaxX3 - ghostLayerWidth;
+    // real omegaDRho = 1.0;// 1.25;// 1.3;
+    for (int x3 = minX3 - ghostLayerWidth; x3 < maxX3 + ghostLayerWidth; x3++) {
+        for (int x2 = minX2 - ghostLayerWidth; x2 < maxX2 + ghostLayerWidth; x2++) {
+            for (int x1 = minX1 - ghostLayerWidth; x1 < maxX1 + ghostLayerWidth; x1++) {
+                if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3)) {
+                    int x1p = x1 + 1;
+                    int x2p = x2 + 1;
+                    int x3p = x3 + 1;
+
+                    real mfcbb = (*this->localDistributionsH1)(D3Q27System::ET_E, x1, x2, x3);
+                    real mfbcb = (*this->localDistributionsH1)(D3Q27System::ET_N, x1, x2, x3);
+                    real mfbbc = (*this->localDistributionsH1)(D3Q27System::ET_T, x1, x2, x3);
+                    real mfccb = (*this->localDistributionsH1)(D3Q27System::ET_NE, x1, x2, x3);
+                    real mfacb = (*this->localDistributionsH1)(D3Q27System::ET_NW, x1p, x2, x3);
+                    real mfcbc = (*this->localDistributionsH1)(D3Q27System::ET_TE, x1, x2, x3);
+                    real mfabc = (*this->localDistributionsH1)(D3Q27System::ET_TW, x1p, x2, x3);
+                    real mfbcc = (*this->localDistributionsH1)(D3Q27System::ET_TN, x1, x2, x3);
+                    real mfbac = (*this->localDistributionsH1)(D3Q27System::ET_TS, x1, x2p, x3);
+                    real mfccc = (*this->localDistributionsH1)(D3Q27System::ET_TNE, x1, x2, x3);
+                    real mfacc = (*this->localDistributionsH1)(D3Q27System::ET_TNW, x1p, x2, x3);
+                    real mfcac = (*this->localDistributionsH1)(D3Q27System::ET_TSE, x1, x2p, x3);
+                    real mfaac = (*this->localDistributionsH1)(D3Q27System::ET_TSW, x1p, x2p, x3);
+                    real mfabb = (*this->nonLocalDistributionsH1)(D3Q27System::ET_W, x1p, x2, x3);
+                    real mfbab = (*this->nonLocalDistributionsH1)(D3Q27System::ET_S, x1, x2p, x3);
+                    real mfbba = (*this->nonLocalDistributionsH1)(D3Q27System::ET_B, x1, x2, x3p);
+                    real mfaab = (*this->nonLocalDistributionsH1)(D3Q27System::ET_SW, x1p, x2p, x3);
+                    real mfcab = (*this->nonLocalDistributionsH1)(D3Q27System::ET_SE, x1, x2p, x3);
+                    real mfaba = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BW, x1p, x2, x3p);
+                    real mfcba = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BE, x1, x2, x3p);
+                    real mfbaa = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BS, x1, x2p, x3p);
+                    real mfbca = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BN, x1, x2, x3p);
+                    real mfaaa = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BSW, x1p, x2p, x3p);
+                    real mfcaa = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BSE, x1, x2p, x3p);
+                    real mfaca = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BNW, x1p, x2, x3p);
+                    real mfcca = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BNE, x1, x2, x3p);
+                    real mfbbb = (*this->restDistributionsH1)(x1, x2, x3);
+
+                    // omegaDRho = 2.0;// 1.5;
+                    // real phiOld = (*phaseField)(x1, x2, x3);
+
+                    (*phaseField)(x1, x2, x3) =
+                        (((mfaaa + mfccc) + (mfaca + mfcac)) + ((mfaac + mfcca) + (mfcaa + mfacc))) + (((mfaab + mfacb) + (mfcab + mfccb)) + ((mfaba + mfabc) + (mfcba + mfcbc)) + ((mfbaa + mfbac) + (mfbca + mfbcc))) + ((mfabb + mfcbb) + (mfbab + mfbcb) + (mfbba + mfbbc)) + mfbbb;
+
+                    if ((*phaseField)(x1, x2, x3) > 1) {
+                        (*phaseField)(x1, x2, x3) = c1o1;
+                    }
+
+                    if ((*phaseField)(x1, x2, x3) < 0) {
+                        (*phaseField)(x1, x2, x3) = 0;
+                    }
+                }
+            }
+        }
+    }
+
+    this->swapDistributions();
+    for (int x3 = minX3 - ghostLayerWidth + 1; x3 < maxX3 + ghostLayerWidth - 1; x3++) {
+        for (int x2 = minX2 - ghostLayerWidth + 1; x2 < maxX2 + ghostLayerWidth - 1; x2++) {
+            for (int x1 = minX1 - ghostLayerWidth + 1; x1 < maxX1 + ghostLayerWidth - 1; x1++) {
+                if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3)) {
+                    // int x1p = x1 + 1;
+                    // int x2p = x2 + 1;
+                    // int x3p = x3 + 1;
+
+                    SPtr<DistributionArray3D> distributionH = this->getDataSet()->getHdistributions();
+                    real hh[27];
+                    distributionH->getDistributionInv(hh, x1, x2, x3);
+                    real phiD, vxP, vyP, vzP;
+
+                    D3Q27System::calcIncompMacroscopicValues(hh, phiD, vxP, vyP, vzP);
+                    (*phaseFieldOld)(x1, x2, x3) = phiD;
+
+                    SPtr<DistributionArray3D> distribution = this->getDataSet()->getFdistributions();
+                    real ff[27];
+                    distribution->getDistributionInv(ff, x1, x2, x3);
+                    real rhoG, vx, vy, vz;
+
+                    D3Q27System::calcIncompMacroscopicValues(ff, rhoG, vx, vy, vz);
+
+                    (*rhoNode)(x1, x2, x3) = rhoG; // *((*phaseField)(x1, x2, x3) > c1o2 ? densityRatio : c1o1);
+                    (*vxNode)(x1, x2, x3) = vx;
+                    (*vyNode)(x1, x2, x3) = vy;
+                    (*vzNode)(x1, x2, x3) = vz;
+                }
+            }
+        }
+    }
+
+    SPtr<DistributionArray3D> distribution = this->getDataSet()->getFdistributions();
+    real ff[27];
+    for (int x3 = minX3 - 1; x3 < maxX3 + 1; x3++) {
+        for (int x2 = minX2 - 1; x2 < maxX2 + 1; x2++) {
+            for (int x1 = minX1 - 1; x1 < maxX1 + 1; x1++) {
+                if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3)) {
+                    // int x1p = x1 + 1;
+                    // int x2p = x2 + 1;
+                    // int x3p = x3 + 1;
+                    findNeighbors(phaseFieldOld, x1, x2, x3);
+                    ////////////////////////////////Momentum conservation experiment 06.03.2023
+                    // surfacetension
+
+                    if ((((*phaseField)(x1, x2, x3) <= c1o2) || phi[DIR_000] <= c1o2) &&
+                        ((phi[DIR_P00] > c1o2) || (phi[DIR_M00] > c1o2) || (phi[DIR_00P] > c1o2) || (phi[DIR_00M] > c1o2) || (phi[DIR_0M0] > c1o2) || (phi[DIR_0P0] > c1o2) || (phi[DIR_PP0] > c1o2) || (phi[DIR_PM0] > c1o2) || (phi[DIR_P0P] > c1o2) || (phi[DIR_P0M] > c1o2) || (phi[DIR_MP0] > c1o2) ||
+                         (phi[DIR_MM0] > c1o2) || (phi[DIR_M0P] > c1o2) || (phi[DIR_M0M] > c1o2) || (phi[DIR_0PM] > c1o2) || (phi[DIR_0MM] > c1o2) || (phi[DIR_0PP] > c1o2) || (phi[DIR_0MP] > c1o2) || (phi[DIR_PPP] > c1o2) || (phi[DIR_PMP] > c1o2) || (phi[DIR_MPP] > c1o2) || (phi[DIR_MMP] > c1o2) ||
+                         (phi[DIR_PPM] > c1o2) || (phi[DIR_PMM] > c1o2) || (phi[DIR_MPM] > c1o2) || (phi[DIR_MMM] > c1o2))) {
+                        real vx = (*vxNode)(x1, x2, x3);
+                        real vy = (*vyNode)(x1, x2, x3);
+                        real vz = (*vzNode)(x1, x2, x3);
+                        findNeighbors(phaseField, x1, x2, x3);
+                        real laplacePressure = c12o1 * sigma * computeCurvature_phi();
+                        //                  if (step > 5000)
+                        //                       UBLOG(logINFO, x1 << ","<< x2 << ","<< x3 << " "<< "3*dP=" << laplacePressure << " dP=" << laplacePressure / 3.0<< " phi=" << phi[DIR_000]<< "\n");
+                        findNeighbors(phaseFieldOld, x1, x2, x3);
+
+                        // 16.03.23 c: BB gas side with updated boundary velocity
+
+                        distribution->getDistributionInv(ff, x1, x2, x3);
+                        real rhoG;
+                        if (phi[DIR_000] > c1o2) { // initialization necessary
+                            real sumRho = 0;
+                            real sumWeight = 1.e-100;
+                            for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+                                if ((phi[fdir] <= c1o2)) {
+                                    sumRho += WEIGTH[fdir] * (*rhoNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+                                    sumWeight += WEIGTH[fdir];
+                                }
+                            }
+                            rhoG = sumRho / sumWeight; // uncheck excpetion: what if there is no adequate neighbor?
+                            for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+                                if ((phi[fdir] > c1o2)) {
+                                    real vxBC = ((*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                    real vyBC = ((*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                    real vzBC = ((*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                    real vBC = (D3Q27System::DX1[fdir] * vxBC + D3Q27System::DX2[fdir] * vyBC + D3Q27System::DX3[fdir] * vzBC);
+                                    real vDir = (D3Q27System::DX1[fdir] * vx + D3Q27System::DX2[fdir] * vy + D3Q27System::DX3[fdir] * vz);
+                                    vBC = (vBC + vDir) / (c2o1 + vBC - vDir);
+                                    real fL = distribution->getDistributionInvForDirection(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]);
+
+                                    if ((phi[D3Q27System::INVDIR[fdir]] > c1o2)) {
+                                        /// here we need reconstruction from scrach
+                                        real feqOLD = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], (*rhoNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]),
+                                                                                            (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]),
+                                                                                            (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                        real feqNew = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], rhoG, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]),
+                                                                                            (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                        // real fBC = (fL - feqOLD) * (c1o1 / collFactorG - c1o1) / (c1o1 / collFactorL - c1o1) + feqNew;
+
+                                        // real fG = distribution->getDistributionInvForDirection(x1, x2, x3, fdir);
+                                        // real fGEQOld = D3Q27System::getIncompFeqForDirection(fdir, (*rhoNode)(x1, x2, x3), vx, vy, vz);
+                                        // real fGEQNew = D3Q27System::getIncompFeqForDirection(fdir, rhoG, vx, vy, vz);
+                                        real fBC = (fL - feqOLD) * (c1o1 / collFactorG - c1o1) / (c1o1 / collFactorL - c1o1) + feqNew; // fL -feqOLD + feqNew;
+                                                                                                                                       // real fBC = fGG - c6o1 * WEIGTH[fdir] * (vBC);
+                                        distribution->setDistributionForDirection(fBC, x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]);
+                                        ///// other possibility is tor replace the node itself instead of the neighbor (only c1o1 of them is allowed!)
+                                        // real fG = distribution->getDistributionInvForDirection(x1, x2, x3, fdir);
+                                        // real feqOLD = D3Q27System::getIncompFeqForDirection(fdir, (*rhoNode)(x1 , x2 , x3 ), (*vxNode)(x1 , x2 , x3 ), (*vyNode)(x1 , x2 , x3 ), (*vzNode)(x1 , x2 , x3 ));
+                                        // real feqNew = D3Q27System::getIncompFeqForDirection(fdir, rhoG, (*vxNode)(x1 , x2 , x3 ), (*vyNode)(x1 , x2 , x3 ), (*vzNode)(x1, x2, x3 ));
+                                        // real fBC = fG - feqOLD + feqNew;
+                                        // distribution->setDistributionForDirection(fBC, x1, x2, x3, fdir);
+                                    }
+                                }
+                            }
+                            // distribution->setDistributionForDirection(D3Q27System::getIncompFeqForDirection(DIR_000, rhoG, vx, vy, vz), x1, x2, x3, DIR_000);
+                            {
+                                real fL = distribution->getDistributionInvForDirection(x1, x2, x3, DIR_000);
+                                real feqOLD = D3Q27System::getIncompFeqForDirection(DIR_000, (*rhoNode)(x1, x2, x3), vx, vy, vz);
+                                real feqNew = D3Q27System::getIncompFeqForDirection(DIR_000, rhoG, vx, vy, vz);
+                                distribution->setDistributionForDirection(fL - feqOLD + feqNew, x1, x2, x3, DIR_000);
+                            }
+
+                        } else { // no refill of gas required
+                            rhoG = (*rhoNode)(x1, x2, x3);
+                            if ((*phaseField)(x1, x2, x3) <= c1o2) { // no refill liquid
+                                for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+                                    if ((phi[fdir] > c1o2)) {
+                                        real vxBC = ((*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                        real vyBC = ((*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                        real vzBC = ((*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                        real vBC = (D3Q27System::DX1[fdir] * vxBC + D3Q27System::DX2[fdir] * vyBC + D3Q27System::DX3[fdir] * vzBC);
+                                        real vDir = (D3Q27System::DX1[fdir] * vx + D3Q27System::DX2[fdir] * vy + D3Q27System::DX3[fdir] * vz);
+                                        // real dvDir = vBC - vDir;
+                                        vBC = (vBC + vDir) / (c2o1 + vBC - vDir);
+                                        real fL = distribution->getDistributionInvForDirection(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]);
+                                        real fG = distribution->getDistributionInvForDirection(x1, x2, x3, fdir);
+                                        real fBC = fG - c6o1 * WEIGTH[fdir] * (vBC);
+                                        // real fGEQ = D3Q27System::getIncompFeqForDirection(fdir, rhoG, vx, vy, vz);
+                                        //  real fBC = (-fGInv + fGInvEQ + fGEQ - c6o1 * WEIGTH[fdir] * dvDir * (c1o1 / collFactorG - c1o1)) - c6o1 * WEIGTH[fdir] * (vBC);
+                                        // real fBC = (fGEQ - c3o1 * WEIGTH[fdir] * dvDir * (c1o1 / collFactorG - c1o1)) - c6o1 * WEIGTH[fdir] * (vBC);
+
+                                        // real feqOLD = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], (*rhoNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                        // D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])); real feqNew =
+                                        // D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], rhoG, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                        // D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])); real fG = distribution->getDistributionInvForDirection(x1, x2, x3, fdir); real fBC = (fL - feqOLD) * (c1o1 / collFactorG - c1o1) /
+                                        // (c1o1 / collFactorL - c1o1) + feqNew;
+
+                                        // if ((*phaseField)(x1, x2, x3) <= c1o2)
+                                        distribution->setDistributionForDirection(fBC, x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]);
+                                        if (((*phaseField)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])) > c1o2) {
+                                            // real vxBC = c1o2 * (vx + (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                            // real vyBC = c1o2 * (vy + (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                            // real vzBC = c1o2 * (vz + (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                            // real feqL = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                            // D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])); real feqG = D3Q27System::getIncompFeqForDirection(fdir, 0, vx, vy, vz); real feqL =
+                                            // D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX1[fdir]) * (D3Q27System::DX1[fdir]), (*vyNode)(x1 +
+                                            // D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX2[fdir]) * (D3Q27System::DX2[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) *
+                                            // (D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir])); real feqG = D3Q27System::getIncompFeqForDirection(fdir, 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX1[fdir]) *
+                                            // (D3Q27System::DX1[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX2[fdir]) * (D3Q27System::DX2[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                            // D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir])); real feqG = D3Q27System::getIncompFeqForDirection(fdir, 0, vx * (D3Q27System::DX1[fdir]) * (D3Q27System::DX1[fdir]), vy * (D3Q27System::DX2[fdir]) *
+                                            // (D3Q27System::DX2[fdir]), vz * (D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]));
+
+                                            // distribution->setDistributionForDirection((fBC + fG) / densityRatio*0 - fL  - (feqG - feqL) * (c1o1 / densityRatio*0 - c1o1) * vBC, x1, x2, x3, fdir);// (vxBC * D3Q27System::DX1[fdir] + vyBC * D3Q27System::DX2[fdir] + vzBC * D3Q27System::DX3[fdir]), x1,
+                                            // x2, x3, fdir); distribution->setDistributionForDirection((fBC + fG) / densityRatio * 0 - fL - (feqG - feqL-2*fL+2*feqL) * (c1o1 / densityRatio - c1o1) * vBC, x1, x2, x3, fdir);// (vxBC * D3Q27System::DX1[fdir] + vyBC * D3Q27System::DX2[fdir] + vzBC *
+                                            // D3Q27System::DX3[fdir]), x1, x2, x3, fdir); real flW = (fBC + fG) / densityRatio * 0 - fL - (feqG - feqL) * (c1o1 / densityRatio*0 - c1o1) * vBC; real flWW = (fBC + fG) / densityRatio * 0 - fL - (feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio*0
+                                            // - c1o1) * vBC; real fLi = distribution->getDistributionInvForDirection(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], fdir); real number = 666; distribution->setDistributionForDirection((fBC + fG) / densityRatio *
+                                            // 0 - fL - (feqG - feqL) * (c1o1 / densityRatio * 0 - c1o1) * vBC, x1, x2, x3, fdir);
+                                            ////	real eqBC= D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, vx, vy, vz);
+                                            ////	real eqG = D3Q27System::getIncompFeqForDirection(fdir, 0, vx, vy, vz);
+                                            //	real eqBC = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                            //D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])); 	real eqG = D3Q27System::getIncompFeqForDirection(fdir, 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                            //D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+
+                                            ////real flNew = (fBC + fG-eqBC-eqG) / densityRatio +eqBC+eqG - fL - (feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio  - c1o1) * vBC;
+                                            //	distribution->setDistributionForDirection(c2o1*laplacePressure * WEIGTH[fdir] +(fBC + fG - eqBC - eqG) / densityRatio + (eqBC + eqG) - fL, x1, x2, x3, fdir);// -0* (feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio  - c1o1) * vBC, x1, x2, x3,
+                                            //fdir);// (vxBC * D3Q27System::DX1[fdir] + vyBC * D3Q27System::DX2[fdir] + vzBC * D3Q27System::DX3[fdir]), x1, x2, x3, fdir);
+                                            //	//if (vxBC != 0) {
+                                            //	//	int set = 0;
+                                            //	//}
+
+                                            real feqL = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX1[fdir]) * (D3Q27System::DX1[fdir]),
+                                                                                              (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX2[fdir]) * (D3Q27System::DX2[fdir]),
+                                                                                              (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]));
+                                            real feqG = D3Q27System::getIncompFeqForDirection(fdir, 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX1[fdir]) * (D3Q27System::DX1[fdir]),
+                                                                                              (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX2[fdir]) * (D3Q27System::DX2[fdir]),
+                                                                                              (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]));
+
+                                            real eqBC = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, vx, vy, vz);
+                                            real eqG = D3Q27System::getIncompFeqForDirection(fdir, 0, vx, vy, vz);
+                                            real eqBCN = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]),
+                                                                                               (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                            real eqGN = D3Q27System::getIncompFeqForDirection(fdir, 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]),
+                                                                                              (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+
+                                            // real flNew = (fBC + fG-eqBC-eqG) / densityRatio +eqBC+eqG - fL - (feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio  - c1o1) * vBC;
+                                            real laplacePressureBC;
+                                            if ((x1 + D3Q27System::DX1[fdir] > 0) && (x1 + D3Q27System::DX1[fdir] < maxX1 + 1) && (x2 + D3Q27System::DX2[fdir] > 0) && (x2 + D3Q27System::DX2[fdir] < maxX2 + 1) && (x3 + D3Q27System::DX3[fdir] > 0) && (x3 + D3Q27System::DX3[fdir] < maxX3 + 1)) {
+                                                findNeighbors(phaseField, x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+                                                laplacePressureBC = c6o1 * c2o1 * computeCurvature_phi() * sigma;
+                                                findNeighbors(phaseFieldOld, x1, x2, x3);
+                                            } else
+                                                laplacePressureBC = laplacePressure; // curv; // reset to the above
+                                            laplacePressureBC = laplacePressure * (c1o1 - c2o1 * (*phaseField)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])) /
+                                                                    (c2o1 * (*phaseField)(x1, x2, x3) - c2o1 * (*phaseField)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])) +
+                                                                laplacePressureBC * (-c1o1 + c2o1 * (*phaseField)(x1, x2, x3)) / (c2o1 * (*phaseField)(x1, x2, x3) - c2o1 * (*phaseField)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                            // laplacePressureBC *= sigma;
+                                            distribution->setDistributionForDirection(laplacePressureBC * WEIGTH[fdir] + (fBC + fG - eqBC - eqG) / densityRatio + (eqBCN + eqGN) * (c1o1 - c1o1 / densityRatio * 0) - fL - 0 * (feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio - c1o1) * vBC, x1,
+                                                                                      x2, x3, fdir);
+                                        }
+                                    }
+                                }
+                            } else { // refill liquid
+
+                                for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+                                    if ((phi[fdir] > c1o2)) {
+                                        real vxBC = ((*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                        real vyBC = ((*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                        real vzBC = ((*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                        real vBC = (D3Q27System::DX1[fdir] * vxBC + D3Q27System::DX2[fdir] * vyBC + D3Q27System::DX3[fdir] * vzBC);
+                                        real vDir = (D3Q27System::DX1[fdir] * vx + D3Q27System::DX2[fdir] * vy + D3Q27System::DX3[fdir] * vz);
+                                        // real dvDir = vBC - vDir;
+                                        vBC = (vBC + vDir) / (c2o1 + vBC - vDir);
+                                        real fL = distribution->getDistributionInvForDirection(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]);
+                                        real fG = distribution->getDistributionInvForDirection(x1, x2, x3, fdir);
+                                        real fBC = fG - c6o1 * WEIGTH[fdir] * (vBC);
+
+                                        // real fGEQ = D3Q27System::getIncompFeqForDirection(fdir, rhoG, vx, vy, vz);
+                                        //  real fBC = (-fGInv + fGInvEQ + fGEQ - c6o1 * WEIGTH[fdir] * dvDir * (c1o1 / collFactorG - c1o1)) - c6o1 * WEIGTH[fdir] * (vBC);
+                                        // real fBC = (fGEQ - c3o1 * WEIGTH[fdir] * dvDir * (c1o1 / collFactorG - c1o1)) - c6o1 * WEIGTH[fdir] * (vBC);
+
+                                        // real feqOLD = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], (*rhoNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                        // D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])); real feqNew =
+                                        // D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], rhoG, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                        // D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])); real fG = distribution->getDistributionInvForDirection(x1, x2, x3, fdir); real fBC = (fL - feqOLD) * (c1o1 / collFactorG - c1o1) /
+                                        // (c1o1 / collFactorL - c1o1) + feqNew;
+
+                                        ff[D3Q27System::INVDIR[fdir]] = fBC;
+                                        if (((*phaseField)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])) > c1o2) {
+                                            // real feqL = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                            // D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])); real feqG = D3Q27System::getIncompFeqForDirection(fdir, 0, vx, vy, vz); real feqL =
+                                            // D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX1[fdir]) * (D3Q27System::DX1[fdir]), (*vyNode)(x1 +
+                                            // D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX2[fdir]) * (D3Q27System::DX2[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) *
+                                            // (D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir])); real feqG = D3Q27System::getIncompFeqForDirection(fdir, 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX1[fdir]) *
+                                            // (D3Q27System::DX1[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX2[fdir]) * (D3Q27System::DX2[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                            // D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir])); real feqG = D3Q27System::getIncompFeqForDirection(fdir, 0, vx * (D3Q27System::DX1[fdir]) * (D3Q27System::DX1[fdir]), vy * (D3Q27System::DX2[fdir]) *
+                                            // (D3Q27System::DX2[fdir]), vz * (D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]));
+
+                                            // distribution->setDistributionForDirection((fBC + fG) / densityRatio*0 - fL- (feqG - feqL) * (c1o1 / densityRatio - c1o1) * (vBC), x1, x2, x3, fdir);
+                                            // distribution->setDistributionForDirection((fBC + fG) / densityRatio * 0 - fL - (feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio*0 - c1o1) * vBC, x1, x2, x3, fdir);// (vxBC * D3Q27System::DX1[fdir] + vyBC * D3Q27System::DX2[fdir] + vzBC *
+                                            // D3Q27System::DX3[fdir]), x1, x2, x3, fdir); distribution->setDistributionForDirection(0, x1, x2, x3, fdir); real flW = (fBC + fG) / densityRatio * 0 - fL - (feqG - feqL) * (c1o1 / densityRatio * 0 - c1o1) * vBC; real flWW = (fBC + fG) / densityRatio * 0
+                                            // - fL - (feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio * 0 - c1o1) * vBC; real fLi = distribution->getDistributionInvForDirection(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], fdir);
+                                            //	real eqBC = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                            //D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])); 	real eqG = D3Q27System::getIncompFeqForDirection(fdir, 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 +
+                                            //D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                            //	//real flNew = (fBC + fG - eqBC - eqG) / densityRatio + eqBC + eqG - fL - (feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio - c1o1) * vBC;
+                                            //	distribution->setDistributionForDirection(c2o1*laplacePressure* WEIGTH[fdir] + (fBC + fG - eqBC - eqG) / densityRatio + (eqBC + eqG)  - fL, x1, x2, x3, fdir);// - 0*(feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio - c1o1) * vBC, x1, x2, x3,
+                                            //fdir);// (vxBC * D3Q27System::DX1[fdir] + vyBC * D3Q27System::DX2[fdir] + vzBC * D3Q27System::DX3[fdir]), x1, x2, x3, fdir);
+
+                                            ////	real number = 666;
+
+                                            real feqL = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX1[fdir]) * (D3Q27System::DX1[fdir]),
+                                                                                              (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX2[fdir]) * (D3Q27System::DX2[fdir]),
+                                                                                              (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]));
+                                            real feqG = D3Q27System::getIncompFeqForDirection(fdir, 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX1[fdir]) * (D3Q27System::DX1[fdir]),
+                                                                                              (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX2[fdir]) * (D3Q27System::DX2[fdir]),
+                                                                                              (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]) * (D3Q27System::DX3[fdir]));
+
+                                            real eqBC = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, vx, vy, vz);
+                                            real eqG = D3Q27System::getIncompFeqForDirection(fdir, 0, vx, vy, vz);
+                                            real eqBCN = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]),
+                                                                                               (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                            real eqGN = D3Q27System::getIncompFeqForDirection(fdir, 0, (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]), (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]),
+                                                                                              (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+
+                                            // real flNew = (fBC + fG-eqBC-eqG) / densityRatio +eqBC+eqG - fL - (feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio  - c1o1) * vBC;
+                                            real laplacePressureBC;
+                                            if ((x1 + D3Q27System::DX1[fdir] > 0) && (x1 + D3Q27System::DX1[fdir] < maxX1 + 1) && (x2 + D3Q27System::DX2[fdir] > 0) && (x2 + D3Q27System::DX2[fdir] < maxX2 + 1) && (x3 + D3Q27System::DX3[fdir] > 0) && (x3 + D3Q27System::DX3[fdir] < maxX3 + 1)) {
+                                                findNeighbors(phaseField, x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+                                                laplacePressureBC = c12o1 * computeCurvature_phi() * sigma;
+                                                findNeighbors(phaseFieldOld, x1, x2, x3);
+                                            } else
+                                                laplacePressureBC = laplacePressure; // curv; // reset to the above
+                                            laplacePressureBC = laplacePressure * (c1o1 - c2o1 * (*phaseField)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])) /
+                                                                    (c2o1 * (*phaseField)(x1, x2, x3) - c2o1 * (*phaseField)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])) +
+                                                                laplacePressureBC * (-c1o1 + c2o1 * (*phaseField)(x1, x2, x3)) / (c2o1 * (*phaseField)(x1, x2, x3) - c2o1 * (*phaseField)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]));
+                                            // laplacePressureBC *= sigma;
+                                            distribution->setDistributionForDirection(laplacePressureBC * WEIGTH[fdir] + (fBC + fG - eqBC - eqG) / densityRatio + (eqBCN + eqGN) * (c1o1 - c1o1 / densityRatio * 0) - fL - 0 * (feqG - feqL - 2 * fL + 2 * feqL) * (c1o1 / densityRatio - c1o1) * vBC, x1,
+                                                                                      x2, x3, fdir);
+                                        }
+
+                                    } else {
+                                        ff[D3Q27System::INVDIR[fdir]] = distribution->getDistributionInvForDirection(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]);
+                                        ;
+                                    }
+                                }
+
+                                real sum2 = 1e-100;
+                                real sumRho = 0;
+                                real sumVx = 0;
+                                real sumVy = 0;
+                                real sumVz = 0;
+                                for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+                                    if ((phi[fdir] > c1o2)) {
+
+                                        sumRho += WEIGTH[fdir] * (*rhoNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]); // * tempRho;
+                                        sumVx += WEIGTH[fdir] * (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+                                        sumVy += WEIGTH[fdir] * (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+                                        sumVz += WEIGTH[fdir] * (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+                                        sum2 += WEIGTH[fdir];
+                                    }
+                                }
+                                real rhoL;
+                                D3Q27System::calcIncompMacroscopicValues(ff, rhoG, vx, vy, vz);
+                                rhoL = sumRho / sum2;
+                                // vx = sumVx / sum2;
+                                // vy = sumVy / sum2;
+                                // vz = sumVz / sum2;
+                                // rhoL = (*rhoNode)(x1, x2, x3)/densityRatio;
+
+                                // for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+                                //	ff[D3Q27System::INVDIR[fdir]] = distribution->getDistributionInvForDirection(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]);
+                                // }
+
+                                for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+                                    if (((phi[fdir] <= c1o2))) //&& (((*phaseField)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir])) > c1o2)))
+                                    {
+                                        real feqOLD = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], rhoG, vx, vy, vz);
+                                        real feqNew = D3Q27System::getIncompFeqForDirection(D3Q27System::INVDIR[fdir], rhoL, vx, vy, vz);
+                                        ff[D3Q27System::INVDIR[fdir]] = (ff[D3Q27System::INVDIR[fdir]] - feqOLD) * (c1o1 / collFactorL - c1o1) / (c1o1 / collFactorG - c1o1) + feqNew;
+                                        distribution->setDistributionForDirection(ff[D3Q27System::INVDIR[fdir]], x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]);
+                                    }
+                                }
+
+                                // for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+                                //	if ((phi[D3Q27System::INVDIR[fdir]] <= c1o2) && (phi[fdir] > c1o2)) {
+                                //		//real vxBC = ((*vxNode)(x1 - D3Q27System::DX1[fdir], x2 - D3Q27System::DX2[fdir], x3 - D3Q27System::DX3[fdir]));
+                                //		//real vyBC = ((*vyNode)(x1 - D3Q27System::DX1[fdir], x2 - D3Q27System::DX2[fdir], x3 - D3Q27System::DX3[fdir]));
+                                //		//real vzBC = ((*vzNode)(x1 - D3Q27System::DX1[fdir], x2 - D3Q27System::DX2[fdir], x3 - D3Q27System::DX3[fdir]));
+                                //		//real vBC = -(D3Q27System::DX1[fdir] * vxBC + D3Q27System::DX2[fdir] * vyBC + D3Q27System::DX2[fdir] * vzBC);
+                                //		real vDir = -(D3Q27System::DX1[fdir] * vx + D3Q27System::DX2[fdir] * vy + D3Q27System::DX2[fdir] * vz);
+                                //		//vBC = (vBC + vDir) / (c2o1 -( vBC - vDir));
+                                //		//real fL = distribution->getDistributionInvForDirection(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]) - c6o1 * WEIGTH[fdir] * vDir;
+                                //		//real fL = distribution->getDistributionInvForDirection(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]) + c6o1 * WEIGTH[fdir] * (vx * D3Q27System::DX1[fdir] + vy * D3Q27System::DX2[fdir] + vz *
+                                //D3Q27System::DX3[fdir]); 		real fL= D3Q27System::getIncompFeqForDirection(fdir, rhoL, vx, vy, vz); 		distribution->setDistributionForDirection(fL, x1 - D3Q27System::DX1[fdir], x2 - D3Q27System::DX2[fdir], x3 - D3Q27System::DX3[fdir], fdir); 		ff[fdir] = fL;
+                                //	}
+                                //	if (!(phi[fdir] > c1o2)) {
+                                //		//std::cout << "Eq at dir=" << fdir << "\n";
+                                //		real vxBC = ((*vxNode)(x1 - D3Q27System::DX1[fdir], x2 - D3Q27System::DX2[fdir], x3 - D3Q27System::DX3[fdir]));
+                                //		real vyBC = ((*vyNode)(x1 - D3Q27System::DX1[fdir], x2 - D3Q27System::DX2[fdir], x3 - D3Q27System::DX3[fdir]));
+                                //		real vzBC = ((*vzNode)(x1 - D3Q27System::DX1[fdir], x2 - D3Q27System::DX2[fdir], x3 - D3Q27System::DX3[fdir]));
+                                //		real feqL = D3Q27System::getIncompFeqForDirection(fdir, rhoL, vx, vy, vz);
+                                //		distribution->setDistributionForDirection(feqL, x1 - D3Q27System::DX1[fdir], x2 - D3Q27System::DX2[fdir], x3 - D3Q27System::DX3[fdir], fdir);
+                                //		ff[fdir] = feqL;
+                                //	}
+                                // }
+                                // real sumRho2= 0;
+                                // for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+                                //	sumRho2 += ff[fdir];// -D3Q27System::getIncompFeqForDirection(fdir, 0, sumVx, sumVy, sumVz);
+                                // }
+                                // ff[DIR_000] = rhoL - sumRho2;
+                                // rhoL = 27.0 / 18.0 * sumRho2;
+                                // std::cout << "rhoL=" << rhoL <<" sumRho="<< 27.0 / 18.0 * sumRho2 << " vx=" << vx << " vy=" << vy << "\n";
+                                D3Q27System::calcIncompMacroscopicValues(ff, rhoL, vx, vy, vz);
+                                // std::cout << "RecalCrhoL=" << rhoL << " sumRho=" << 27.0 / 18.0 * sumRho2 << " vx=" << vx << " vy=" << vy << "ffRest="<<ff[DIR_000]<<"\n";
+                                // distribution->setDistributionForDirection(ff[DIR_000], x1, x2, x3, DIR_000);
+                                {
+                                    real fG = distribution->getDistributionInvForDirection(x1, x2, x3, DIR_000);
+                                    real feqOLD = D3Q27System::getIncompFeqForDirection(DIR_000, (*rhoNode)(x1, x2, x3), vx, vy, vz);
+                                    real feqNew = D3Q27System::getIncompFeqForDirection(DIR_000, rhoL, vx, vy, vz);
+                                    distribution->setDistributionForDirection(fG - feqOLD + feqNew, x1, x2, x3, DIR_000);
+                                }
+                                // for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+                                //	ff[D3Q27System::INVDIR[fdir]]=distribution->getDistributionInvForDirection(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir], D3Q27System::INVDIR[fdir]);
+                                // }
+                                // D3Q27System::calcIncompMacroscopicValues(ff, rhoL, vx, vy, vz);
+                                // std::cout << "AfterRead rhoL=" << rhoL << " rhoGToL=" << rhoG/densityRatio << " vx=" << vx << " vy=" << vy << "ffRest=" << ff[DIR_000] <<" x="<<x1<<" y="<<x2<<" z="<<x3<< "\n";
+
+                                // real feqL = D3Q27System::getIncompFeqForDirection(DIR_000, rhoL, vx, vy, vz);
+                                // distribution->setDistributionForDirection(feqL, x1, x2, x3, DIR_000);
+                            }
+                        }
+
+                    } // end Loop
+                }
+            }
+        }
+    }
+
+    this->swapDistributions();
+
+    real collFactorM;
+
+    for (int x3 = minX3; x3 < maxX3; x3++) {
+        for (int x2 = minX2; x2 < maxX2; x2++) {
+            for (int x1 = minX1; x1 < maxX1; x1++) {
+                if (!bcArray->isSolid(x1, x2, x3) && !bcArray->isUndefined(x1, x2, x3)) {
+                    int x1p = x1 + 1;
+                    int x2p = x2 + 1;
+                    int x3p = x3 + 1;
+
+                    findNeighbors(phaseField, x1, x2, x3);
+
+                    real mfcbb = (*this->localDistributionsF)(D3Q27System::ET_E, x1, x2, x3);
+                    real mfbcb = (*this->localDistributionsF)(D3Q27System::ET_N, x1, x2, x3);
+                    real mfbbc = (*this->localDistributionsF)(D3Q27System::ET_T, x1, x2, x3);
+                    real mfccb = (*this->localDistributionsF)(D3Q27System::ET_NE, x1, x2, x3);
+                    real mfacb = (*this->localDistributionsF)(D3Q27System::ET_NW, x1p, x2, x3);
+                    real mfcbc = (*this->localDistributionsF)(D3Q27System::ET_TE, x1, x2, x3);
+                    real mfabc = (*this->localDistributionsF)(D3Q27System::ET_TW, x1p, x2, x3);
+                    real mfbcc = (*this->localDistributionsF)(D3Q27System::ET_TN, x1, x2, x3);
+                    real mfbac = (*this->localDistributionsF)(D3Q27System::ET_TS, x1, x2p, x3);
+                    real mfccc = (*this->localDistributionsF)(D3Q27System::ET_TNE, x1, x2, x3);
+                    real mfacc = (*this->localDistributionsF)(D3Q27System::ET_TNW, x1p, x2, x3);
+                    real mfcac = (*this->localDistributionsF)(D3Q27System::ET_TSE, x1, x2p, x3);
+                    real mfaac = (*this->localDistributionsF)(D3Q27System::ET_TSW, x1p, x2p, x3);
+                    real mfabb = (*this->nonLocalDistributionsF)(D3Q27System::ET_W, x1p, x2, x3);
+                    real mfbab = (*this->nonLocalDistributionsF)(D3Q27System::ET_S, x1, x2p, x3);
+                    real mfbba = (*this->nonLocalDistributionsF)(D3Q27System::ET_B, x1, x2, x3p);
+                    real mfaab = (*this->nonLocalDistributionsF)(D3Q27System::ET_SW, x1p, x2p, x3);
+                    real mfcab = (*this->nonLocalDistributionsF)(D3Q27System::ET_SE, x1, x2p, x3);
+                    real mfaba = (*this->nonLocalDistributionsF)(D3Q27System::ET_BW, x1p, x2, x3p);
+                    real mfcba = (*this->nonLocalDistributionsF)(D3Q27System::ET_BE, x1, x2, x3p);
+                    real mfbaa = (*this->nonLocalDistributionsF)(D3Q27System::ET_BS, x1, x2p, x3p);
+                    real mfbca = (*this->nonLocalDistributionsF)(D3Q27System::ET_BN, x1, x2, x3p);
+                    real mfaaa = (*this->nonLocalDistributionsF)(D3Q27System::ET_BSW, x1p, x2p, x3p);
+                    real mfcaa = (*this->nonLocalDistributionsF)(D3Q27System::ET_BSE, x1, x2p, x3p);
+                    real mfaca = (*this->nonLocalDistributionsF)(D3Q27System::ET_BNW, x1p, x2, x3p);
+                    real mfcca = (*this->nonLocalDistributionsF)(D3Q27System::ET_BNE, x1, x2, x3p);
+                    real mfbbb = (*this->restDistributionsF)(x1, x2, x3);
+
+                    real f[D3Q27System::ENDF + 1];
+                    real fEq[D3Q27System::ENDF + 1];
+                    real fEqSolid[D3Q27System::ENDF + 1];
+                    real fPre[D3Q27System::ENDF + 1];
+
+                    f[vf::lbm::dir::DIR_000] = mfbbb;
+
+                    f[vf::lbm::dir::DIR_P00] = mfcbb;
+                    f[vf::lbm::dir::DIR_0P0] = mfbcb;
+                    f[vf::lbm::dir::DIR_00P] = mfbbc;
+                    f[vf::lbm::dir::DIR_PP0] = mfccb;
+                    f[vf::lbm::dir::DIR_MP0] = mfacb;
+                    f[vf::lbm::dir::DIR_P0P] = mfcbc;
+                    f[vf::lbm::dir::DIR_M0P] = mfabc;
+                    f[vf::lbm::dir::DIR_0PP] = mfbcc;
+                    f[vf::lbm::dir::DIR_0MP] = mfbac;
+                    f[vf::lbm::dir::DIR_PPP] = mfccc;
+                    f[vf::lbm::dir::DIR_MPP] = mfacc;
+                    f[vf::lbm::dir::DIR_PMP] = mfcac;
+                    f[vf::lbm::dir::DIR_MMP] = mfaac;
+
+                    f[vf::lbm::dir::DIR_M00] = mfabb;
+                    f[vf::lbm::dir::DIR_0M0] = mfbab;
+                    f[vf::lbm::dir::DIR_00M] = mfbba;
+                    f[vf::lbm::dir::DIR_MM0] = mfaab;
+                    f[vf::lbm::dir::DIR_PM0] = mfcab;
+                    f[vf::lbm::dir::DIR_M0M] = mfaba;
+                    f[vf::lbm::dir::DIR_P0M] = mfcba;
+                    f[vf::lbm::dir::DIR_0MM] = mfbaa;
+                    f[vf::lbm::dir::DIR_0PM] = mfbca;
+                    f[vf::lbm::dir::DIR_MMM] = mfaaa;
+                    f[vf::lbm::dir::DIR_PMM] = mfcaa;
+                    f[vf::lbm::dir::DIR_MPM] = mfaca;
+                    f[vf::lbm::dir::DIR_PPM] = mfcca;
+
+                    if ((*particleData)(x1, x2, x3)->solidFraction > SOLFRAC_MIN) {
+                        fPre[vf::lbm::dir::DIR_000] = mfbbb;
+
+                        fPre[vf::lbm::dir::DIR_P00] = mfcbb;
+                        fPre[vf::lbm::dir::DIR_0P0] = mfbcb;
+                        fPre[vf::lbm::dir::DIR_00P] = mfbbc;
+                        fPre[vf::lbm::dir::DIR_PP0] = mfccb;
+                        fPre[vf::lbm::dir::DIR_MP0] = mfacb;
+                        fPre[vf::lbm::dir::DIR_P0P] = mfcbc;
+                        fPre[vf::lbm::dir::DIR_M0P] = mfabc;
+                        fPre[vf::lbm::dir::DIR_0PP] = mfbcc;
+                        fPre[vf::lbm::dir::DIR_0MP] = mfbac;
+                        fPre[vf::lbm::dir::DIR_PPP] = mfccc;
+                        fPre[vf::lbm::dir::DIR_MPP] = mfacc;
+                        fPre[vf::lbm::dir::DIR_PMP] = mfcac;
+                        fPre[vf::lbm::dir::DIR_MMP] = mfaac;
+
+                        fPre[vf::lbm::dir::DIR_M00] = mfabb;
+                        fPre[vf::lbm::dir::DIR_0M0] = mfbab;
+                        fPre[vf::lbm::dir::DIR_00M] = mfbba;
+                        fPre[vf::lbm::dir::DIR_MM0] = mfaab;
+                        fPre[vf::lbm::dir::DIR_PM0] = mfcab;
+                        fPre[vf::lbm::dir::DIR_M0M] = mfaba;
+                        fPre[vf::lbm::dir::DIR_P0M] = mfcba;
+                        fPre[vf::lbm::dir::DIR_0MM] = mfbaa;
+                        fPre[vf::lbm::dir::DIR_0PM] = mfbca;
+                        fPre[vf::lbm::dir::DIR_MMM] = mfaaa;
+                        fPre[vf::lbm::dir::DIR_PMM] = mfcaa;
+                        fPre[vf::lbm::dir::DIR_MPM] = mfaca;
+                        fPre[vf::lbm::dir::DIR_PPM] = mfcca;
+                    }
+
+                    (*particleData)(x1, x2, x3)->hydrodynamicForce.fill(0.0);
+
+  
+
+                        real rhoH = 1.0;
+                        real rhoL = 1.0 / densityRatio;
+
+                        // real rhoToPhi = (rhoH - rhoL) / (phiH - phiL);
+
+                        real dX1_phi = gradX1_phi();
+                        real dX2_phi = gradX2_phi();
+                        real dX3_phi = gradX3_phi();
+
+                        real denom = sqrt(dX1_phi * dX1_phi + dX2_phi * dX2_phi + dX3_phi * dX3_phi) + 1.0e-20; //+ 1e-9+1e-3;
+                        // 01.09.2022: unclear what value we have to add to the normal: lager values better cut of in gas phase?
+                        real normX1 = dX1_phi / denom;
+                        real normX2 = dX2_phi / denom;
+                        real normX3 = dX3_phi / denom;
+
+                        collFactorM = phi[DIR_000] > c1o2 ? collFactorL : collFactorG;
+                        // real collFactorMInv = phi[DIR_000] > c1o2 ? collFactorG : collFactorL;
+
+                        // real mu = 2 * beta * phi[DIR_000] * (phi[DIR_000] - 1) * (2 * phi[DIR_000] - 1) - kappa * nabla2_phi();
+
+                        //----------- Calculating Macroscopic Values -------------
+                        real rho = phi[DIR_000] > c1o2 ? rhoH : rhoL;
+
+                        real m0, m1, m2;
+                        real rhoRef = c1o1;
+
+                        real vvx = ((((mfccc - mfaaa) + (mfcac - mfaca)) + ((mfcaa - mfacc) + (mfcca - mfaac))) + (((mfcba - mfabc) + (mfcbc - mfaba)) + ((mfcab - mfacb) + (mfccb - mfaab))) + (mfcbb - mfabb)) / rhoRef;
+                        real vvy = ((((mfccc - mfaaa) + (mfaca - mfcac)) + ((mfacc - mfcaa) + (mfcca - mfaac))) + (((mfbca - mfbac) + (mfbcc - mfbaa)) + ((mfacb - mfcab) + (mfccb - mfaab))) + (mfbcb - mfbab)) / rhoRef;
+                        real vvz = ((((mfccc - mfaaa) + (mfcac - mfaca)) + ((mfacc - mfcaa) + (mfaac - mfcca))) + (((mfbac - mfbca) + (mfbcc - mfbaa)) + ((mfabc - mfcba) + (mfcbc - mfaba))) + (mfbbc - mfbba)) / rhoRef;
+                        /////////////////////
+
+                        forcingX1 = 0.0;
+                        forcingX2 = 0.0;
+                        forcingX3 = 0.0;
+
+                        if (withForcing) {
+                            muRho = rho;
+                            muPhi = phi[DIR_000];
+                            forcingX1 += muForcingX1.Eval();
+                            forcingX2 += muForcingX2.Eval();
+                            forcingX3 += muForcingX3.Eval();
+
+                            vvx += (forcingX1)*deltaT * c1o2;
+                            vvy += (forcingX2)*deltaT * c1o2;
+                            vvz += (forcingX3)*deltaT * c1o2;
+                        }
+                        if ((*particleData)(x1, x2, x3)->solidFraction <= SOLFRAC_MAX) {
+                        real vx2;
+                        real vy2;
+                        real vz2;
+                        vx2 = vvx * vvx;
+                        vy2 = vvy * vvy;
+                        vz2 = vvz * vvz;
+                        ///////////////////////////////////////////////////////////////////////////////////////////
+                        real oMdrho;
+                        ///////////////
+
+                        oMdrho = mfccc + mfaaa;
+                        m0 = mfaca + mfcac;
+                        m1 = mfacc + mfcaa;
+                        m2 = mfaac + mfcca;
+                        oMdrho += m0;
+                        m1 += m2;
+                        oMdrho += m1;
+                        m0 = mfbac + mfbca;
+                        m1 = mfbaa + mfbcc;
+                        m0 += m1;
+                        m1 = mfabc + mfcba;
+                        m2 = mfaba + mfcbc;
+                        m1 += m2;
+                        m0 += m1;
+                        m1 = mfacb + mfcab;
+                        m2 = mfaab + mfccb;
+                        m1 += m2;
+                        m0 += m1;
+                        oMdrho += m0;
+                        m0 = mfabb + mfcbb;
+                        m1 = mfbab + mfbcb;
+                        m2 = mfbba + mfbbc;
+                        m0 += m1 + m2;
+                        m0 += mfbbb;                                // hat gefehlt
+                        oMdrho = (rhoRef - (oMdrho + m0)) / rhoRef; // 12.03.21 check derivation!!!!
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        real wadjust;
+                        //					real qudricLimit = 0.01 / (c1o1 + 1.0e4 * phi[DIR_000] * (c1o1 - phi[DIR_000]));
+                        // real qudricLimit = 0.01 / (c1o1 + (((*phaseField)(x1, x2, x3) > c1o2) ? 1.0e6 * phi[DIR_000] * (c1o1 - phi[DIR_000]):c0o1));
+                        real qudricLimit = 0.01;
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        //! - Chimera transform from well conditioned distributions to central moments as defined in Appendix J 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>
+                        //! see also 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>
+                        //!
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // Z - Dir
+                        forwardInverseChimeraWithKincompressible(mfaaa, mfaab, mfaac, vvz, vz2, c36o1, c1o36, oMdrho);
+                        forwardInverseChimeraWithKincompressible(mfaba, mfabb, mfabc, vvz, vz2, c9o1, c1o9, oMdrho);
+                        forwardInverseChimeraWithKincompressible(mfaca, mfacb, mfacc, vvz, vz2, c36o1, c1o36, oMdrho);
+                        forwardInverseChimeraWithKincompressible(mfbaa, mfbab, mfbac, vvz, vz2, c9o1, c1o9, oMdrho);
+                        forwardInverseChimeraWithKincompressible(mfbba, mfbbb, mfbbc, vvz, vz2, c9o4, c4o9, oMdrho);
+                        forwardInverseChimeraWithKincompressible(mfbca, mfbcb, mfbcc, vvz, vz2, c9o1, c1o9, oMdrho);
+                        forwardInverseChimeraWithKincompressible(mfcaa, mfcab, mfcac, vvz, vz2, c36o1, c1o36, oMdrho);
+                        forwardInverseChimeraWithKincompressible(mfcba, mfcbb, mfcbc, vvz, vz2, c9o1, c1o9, oMdrho);
+                        forwardInverseChimeraWithKincompressible(mfcca, mfccb, mfccc, vvz, vz2, c36o1, c1o36, oMdrho);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // Y - Dir
+                        forwardInverseChimeraWithKincompressible(mfaaa, mfaba, mfaca, vvy, vy2, c6o1, c1o6, oMdrho);
+                        forwardChimera(mfaab, mfabb, mfacb, vvy, vy2);
+                        forwardInverseChimeraWithKincompressible(mfaac, mfabc, mfacc, vvy, vy2, c18o1, c1o18, oMdrho);
+                        forwardInverseChimeraWithKincompressible(mfbaa, mfbba, mfbca, vvy, vy2, c3o2, c2o3, oMdrho);
+                        forwardChimera(mfbab, mfbbb, mfbcb, vvy, vy2);
+                        forwardInverseChimeraWithKincompressible(mfbac, mfbbc, mfbcc, vvy, vy2, c9o2, c2o9, oMdrho);
+                        forwardInverseChimeraWithKincompressible(mfcaa, mfcba, mfcca, vvy, vy2, c6o1, c1o6, oMdrho);
+                        forwardChimera(mfcab, mfcbb, mfccb, vvy, vy2);
+                        forwardInverseChimeraWithKincompressible(mfcac, mfcbc, mfccc, vvy, vy2, c18o1, c1o18, oMdrho);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // X - Dir
+                        forwardInverseChimeraWithKincompressible(mfaaa, mfbaa, mfcaa, vvx, vx2, c1o1, c1o1, oMdrho);
+                        forwardChimera(mfaba, mfbba, mfcba, vvx, vx2);
+                        forwardInverseChimeraWithKincompressible(mfaca, mfbca, mfcca, vvx, vx2, c3o1, c1o3, oMdrho);
+                        forwardChimera(mfaab, mfbab, mfcab, vvx, vx2);
+                        forwardChimera(mfabb, mfbbb, mfcbb, vvx, vx2);
+                        forwardChimera(mfacb, mfbcb, mfccb, vvx, vx2);
+                        forwardInverseChimeraWithKincompressible(mfaac, mfbac, mfcac, vvx, vx2, c3o1, c1o3, oMdrho);
+                        forwardChimera(mfabc, mfbbc, mfcbc, vvx, vx2);
+                        forwardInverseChimeraWithKincompressible(mfacc, mfbcc, mfccc, vvx, vx2, c3o1, c1o9, oMdrho);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // Cumulants
+                        ////////////////////////////////////////////////////////////////////////////////////
+
+                        // mfaaa = 0.0;
+                        real OxxPyyPzz = 1.0; // omega2 or bulk viscosity
+                                              //   real OxyyPxzz = 1.;//-s9;//2+s9;//
+                                              //   real OxyyMxzz  = 1.;//2+s9;//
+                        real O4 = 1.;
+                        real O5 = 1.;
+                        real O6 = 1.;
+                        /////
+
+                        /////fourth order parameters; here only for test. Move out of loop!
+
+                        real OxyyPxzz = 8.0 * (collFactorM - 2.0) * (OxxPyyPzz * (3.0 * collFactorM - 1.0) - 5.0 * collFactorM) / (8.0 * (5.0 - 2.0 * collFactorM) * collFactorM + OxxPyyPzz * (8.0 + collFactorM * (9.0 * collFactorM - 26.0)));
+                        real OxyyMxzz = 8.0 * (collFactorM - 2.0) * (collFactorM + OxxPyyPzz * (3.0 * collFactorM - 7.0)) / (OxxPyyPzz * (56.0 - 42.0 * collFactorM + 9.0 * collFactorM * collFactorM) - 8.0 * collFactorM);
+                        real Oxyz = 24.0 * (collFactorM - 2.0) * (4.0 * collFactorM * collFactorM + collFactorM * OxxPyyPzz * (18.0 - 13.0 * collFactorM) + OxxPyyPzz * OxxPyyPzz * (2.0 + collFactorM * (6.0 * collFactorM - 11.0))) /
+                                    (16.0 * collFactorM * collFactorM * (collFactorM - 6.0) - 2.0 * collFactorM * OxxPyyPzz * (216.0 + 5.0 * collFactorM * (9.0 * collFactorM - 46.0)) + OxxPyyPzz * OxxPyyPzz * (collFactorM * (3.0 * collFactorM - 10.0) * (15.0 * collFactorM - 28.0) - 48.0));
+                        real A = (4.0 * collFactorM * collFactorM + 2.0 * collFactorM * OxxPyyPzz * (collFactorM - 6.0) + OxxPyyPzz * OxxPyyPzz * (collFactorM * (10.0 - 3.0 * collFactorM) - 4.0)) / ((collFactorM - OxxPyyPzz) * (OxxPyyPzz * (2.0 + 3.0 * collFactorM) - 8.0 * collFactorM));
+                        // FIXME:  warning C4459: declaration of 'B' hides global declaration (message : see declaration of 'D3Q27System::B' )
+                        real BB = (4.0 * collFactorM * OxxPyyPzz * (9.0 * collFactorM - 16.0) - 4.0 * collFactorM * collFactorM - 2.0 * OxxPyyPzz * OxxPyyPzz * (2.0 + 9.0 * collFactorM * (collFactorM - 2.0))) /
+                                  (3.0 * (collFactorM - OxxPyyPzz) * (OxxPyyPzz * (2.0 + 3.0 * collFactorM) - 8.0 * collFactorM));
+
+                        // Cum 4.
+                        real CUMcbb = mfcbb - ((mfcaa + c1o3) * mfabb + 2. * mfbba * mfbab);
+                        real CUMbcb = mfbcb - ((mfaca + c1o3) * mfbab + 2. * mfbba * mfabb);
+                        real CUMbbc = mfbbc - ((mfaac + c1o3) * mfbba + 2. * mfbab * mfabb);
+
+                        real CUMcca = mfcca - ((mfcaa * mfaca + 2. * mfbba * mfbba) + c1o3 * (mfcaa + mfaca) * oMdrho + c1o9 * (oMdrho - c1o1) * oMdrho);
+                        real CUMcac = mfcac - ((mfcaa * mfaac + 2. * mfbab * mfbab) + c1o3 * (mfcaa + mfaac) * oMdrho + c1o9 * (oMdrho - c1o1) * oMdrho);
+                        real CUMacc = mfacc - ((mfaac * mfaca + 2. * mfabb * mfabb) + c1o3 * (mfaac + mfaca) * oMdrho + c1o9 * (oMdrho - c1o1) * oMdrho);
+
+                        // Cum 5.
+                        real CUMbcc = mfbcc - (mfaac * mfbca + mfaca * mfbac + 4. * mfabb * mfbbb + 2. * (mfbab * mfacb + mfbba * mfabc)) - c1o3 * (mfbca + mfbac) * oMdrho;
+                        real CUMcbc = mfcbc - (mfaac * mfcba + mfcaa * mfabc + 4. * mfbab * mfbbb + 2. * (mfabb * mfcab + mfbba * mfbac)) - c1o3 * (mfcba + mfabc) * oMdrho;
+                        real CUMccb = mfccb - (mfcaa * mfacb + mfaca * mfcab + 4. * mfbba * mfbbb + 2. * (mfbab * mfbca + mfabb * mfcba)) - c1o3 * (mfacb + mfcab) * oMdrho;
+
+                        // Cum 6.
+                        real CUMccc = mfccc +
+                                      ((-4. * mfbbb * mfbbb - (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca) - 4. * (mfabb * mfcbb + mfbab * mfbcb + mfbba * mfbbc) - 2. * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb)) +
+                                       (4. * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac) + 2. * (mfcaa * mfaca * mfaac) + 16. * mfbba * mfbab * mfabb) - c1o3 * (mfacc + mfcac + mfcca) * oMdrho - c1o9 * oMdrho * oMdrho -
+                                       c1o9 * (mfcaa + mfaca + mfaac) * oMdrho * (1. - 2. * oMdrho) - c1o27 * oMdrho * oMdrho * (-2. * oMdrho) + (2. * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba) + (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa)) * c2o3 * oMdrho) +
+                                      c1o27 * oMdrho;
+
+                        // 2.
+                        //  linear combinations
+                        real mxxPyyPzz = mfcaa + mfaca + mfaac;
+                        mxxPyyPzz -= mfaaa; // 12.03.21 shifted by mfaaa
+                                            // mxxPyyPzz-=(mfaaa+mfaaaS)*c1o2;//12.03.21 shifted by mfaaa
+                        real mxxMyy = mfcaa - mfaca;
+                        real mxxMzz = mfcaa - mfaac;
+
+                        ///
+                        real mmfcaa = c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz);
+                        real mmfaca = c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz);
+                        real mmfaac = c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz);
+                        real mmfabb = mfabb;
+                        real mmfbab = mfbab;
+                        real mmfbba = mfbba;
+                        ///
+
+                        real dxux = -c1o2 * collFactorM * (mxxMyy + mxxMzz) + c1o2 * OxxPyyPzz * (/*mfaaa*/ -mxxPyyPzz) * 0;
+                        // real dxux = -c1o2 * (mxxMyy + mxxMzz) * collFactorM - mfaaa * c1o3* omegaDRho;
+                        real dyuy = dxux + collFactorM * c3o2 * mxxMyy;
+                        real dzuz = dxux + collFactorM * c3o2 * mxxMzz;
+                        real Dxy = -c3o1 * collFactorM * mfbba;
+                        real Dxz = -c3o1 * collFactorM * mfbab;
+                        real Dyz = -c3o1 * collFactorM * mfabb;
+
+                        if (phi[DIR_000] > c1o2) {
+                            /// QR eddyviscosity:
+                            real eddyR = -(Dxy * Dxy + Dxz * Dxz + c1o3 * dxux * dxux) * (dxux) - (Dxy * Dxy + Dyz * Dyz + c1o3 * dyuy * dyuy) * dyuy - (Dxz * Dxz + Dyz * Dyz + c1o3 * dzuz * dzuz) * dzuz - c2o1 * Dxy * Dxz * Dyz;
+                            real eddyQ = Dxy * Dxz + Dxy * Dyz + Dxz * Dyz + c1o2 * (dxux * dxux + dyuy * dyuy + dzuz * dzuz);
+                            real nuEddy = 5.0e1 * (eddyR / (eddyQ + 1e-100)) * (dX1_phi * dX1_phi + dX2_phi * dX2_phi + dX3_phi * dX3_phi);
+                            nuEddy = (nuEddy < c1o1 / collFactorM) ? c1o1 / collFactorM : nuEddy;
+                            collFactorM = c1o1 / nuEddy;
+                            // collFactorM = c1o1 / (c1o1 / collFactorM +1.e2*nuEddy*(dX1_phi*dX1_phi+dX2_phi*dX2_phi+dX3_phi*dX3_phi));
+                            collFactorM = (collFactorM < 1.8) ? 1.8 : collFactorM;
+                            OxyyPxzz = 8.0 * (collFactorM - 2.0) * (OxxPyyPzz * (3.0 * collFactorM - 1.0) - 5.0 * collFactorM) / (8.0 * (5.0 - 2.0 * collFactorM) * collFactorM + OxxPyyPzz * (8.0 + collFactorM * (9.0 * collFactorM - 26.0)));
+                            OxyyMxzz = 8.0 * (collFactorM - 2.0) * (collFactorM + OxxPyyPzz * (3.0 * collFactorM - 7.0)) / (OxxPyyPzz * (56.0 - 42.0 * collFactorM + 9.0 * collFactorM * collFactorM) - 8.0 * collFactorM);
+                            Oxyz = 24.0 * (collFactorM - 2.0) * (4.0 * collFactorM * collFactorM + collFactorM * OxxPyyPzz * (18.0 - 13.0 * collFactorM) + OxxPyyPzz * OxxPyyPzz * (2.0 + collFactorM * (6.0 * collFactorM - 11.0))) /
+                                   (16.0 * collFactorM * collFactorM * (collFactorM - 6.0) - 2.0 * collFactorM * OxxPyyPzz * (216.0 + 5.0 * collFactorM * (9.0 * collFactorM - 46.0)) + OxxPyyPzz * OxxPyyPzz * (collFactorM * (3.0 * collFactorM - 10.0) * (15.0 * collFactorM - 28.0) - 48.0));
+                            A = (4.0 * collFactorM * collFactorM + 2.0 * collFactorM * OxxPyyPzz * (collFactorM - 6.0) + OxxPyyPzz * OxxPyyPzz * (collFactorM * (10.0 - 3.0 * collFactorM) - 4.0)) / ((collFactorM - OxxPyyPzz) * (OxxPyyPzz * (2.0 + 3.0 * collFactorM) - 8.0 * collFactorM));
+                            BB = (4.0 * collFactorM * OxxPyyPzz * (9.0 * collFactorM - 16.0) - 4.0 * collFactorM * collFactorM - 2.0 * OxxPyyPzz * OxxPyyPzz * (2.0 + 9.0 * collFactorM * (collFactorM - 2.0))) /
+                                 (3.0 * (collFactorM - OxxPyyPzz) * (OxxPyyPzz * (2.0 + 3.0 * collFactorM) - 8.0 * collFactorM));
+                        }
+
+                        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+                        // non Newtonian fluid collision factor
+                        if (phi[DIR_000] > c1o2) {
+                            real shearRate = sqrt(c2o1 * (dxux * dxux + dyuy * dyuy + dzuz * dzuz) + Dxy * Dxy + Dxz * Dxz + Dyz * Dyz);
+                            collFactorM = Rheology::getBinghamCollFactor(collFactorM, shearRate, c1o1);
+                            collFactorM = (collFactorM < c1o1) ? c1o1 : collFactorM;
+                        }
+                        // omega = Rheology::getHerschelBulkleyCollFactor(omega, shearRate, drho);
+                        // omega = Rheology::getBinghamCollFactor(omega, shearRate, drho);
+                        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+                        /////////
+                        // real mxxMyyh = -c2o1 * (dxux - dyuy) / collFactorMInv * c1o3;
+                        // real mxxMzzh = -c2o1 * (dxux - dzuz) / collFactorMInv * c1o3;
+
+                        // relax
+                        mxxPyyPzz += OxxPyyPzz * (/*mfaaa*/ -mxxPyyPzz) - 3. * (1. - c1o2 * OxxPyyPzz) * (vx2 * dxux + vy2 * dyuy + vz2 * dzuz);
+                        mxxMyy += collFactorM * (-mxxMyy) - 3. * (1. - c1o2 * collFactorM) * (vx2 * dxux - vy2 * dyuy);
+                        mxxMzz += collFactorM * (-mxxMzz) - 3. * (1. - c1o2 * collFactorM) * (vx2 * dxux - vz2 * dzuz);
+
+                        mfabb += collFactorM * (-mfabb);
+                        mfbab += collFactorM * (-mfbab);
+                        mfbba += collFactorM * (-mfbba);
+
+                        // mxxMyyh += collFactorMInv * (-mxxMyyh) - 3. * (1. - c1o2 * collFactorMInv) * (vx2 * dxux - vy2 * dyuy);
+                        // mxxMzzh += collFactorMInv * (-mxxMzzh) - 3. * (1. - c1o2 * collFactorMInv) * (vx2 * dxux - vz2 * dzuz);
+
+                        mxxPyyPzz += mfaaa; // 12.03.21 shifted by mfaaa
+
+                        // mxxPyyPzz += (mfaaa + mfaaaS) * c1o2;
+                        // mfaaa = mfaaaS;
+                        // linear combinations back
+                        mfcaa = c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz);
+                        mfaca = c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz);
+                        mfaac = c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz);
+
+                        // 3.
+                        //  linear combinations
+                        real mxxyPyzz = mfcba + mfabc;
+                        real mxxyMyzz = mfcba - mfabc;
+
+                        real mxxzPyyz = mfcab + mfacb;
+                        real mxxzMyyz = mfcab - mfacb;
+
+                        real mxyyPxzz = mfbca + mfbac;
+                        real mxyyMxzz = mfbca - mfbac;
+
+                        mmfcaa += c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz - mfaaa);
+                        mmfaca += c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz - mfaaa);
+                        mmfaac += c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz - mfaaa);
+                        mmfabb += mfabb;
+                        mmfbab += mfbab;
+                        mmfbba += mfbba;
+
+                        // relax
+                        wadjust = Oxyz + (1. - Oxyz) * fabs(mfbbb) / (fabs(mfbbb) + qudricLimit);
+                        mfbbb += wadjust * (-mfbbb);
+                        wadjust = OxyyPxzz + (1. - OxyyPxzz) * fabs(mxxyPyzz) / (fabs(mxxyPyzz) + qudricLimit);
+                        mxxyPyzz += wadjust * (-mxxyPyzz);
+                        wadjust = OxyyMxzz + (1. - OxyyMxzz) * fabs(mxxyMyzz) / (fabs(mxxyMyzz) + qudricLimit);
+                        mxxyMyzz += wadjust * (-mxxyMyzz);
+                        wadjust = OxyyPxzz + (1. - OxyyPxzz) * fabs(mxxzPyyz) / (fabs(mxxzPyyz) + qudricLimit);
+                        mxxzPyyz += wadjust * (-mxxzPyyz);
+                        wadjust = OxyyMxzz + (1. - OxyyMxzz) * fabs(mxxzMyyz) / (fabs(mxxzMyyz) + qudricLimit);
+                        mxxzMyyz += wadjust * (-mxxzMyyz);
+                        wadjust = OxyyPxzz + (1. - OxyyPxzz) * fabs(mxyyPxzz) / (fabs(mxyyPxzz) + qudricLimit);
+                        mxyyPxzz += wadjust * (-mxyyPxzz);
+                        wadjust = OxyyMxzz + (1. - OxyyMxzz) * fabs(mxyyMxzz) / (fabs(mxyyMxzz) + qudricLimit);
+                        mxyyMxzz += wadjust * (-mxyyMxzz);
+
+                        // linear combinations back
+                        mfcba = (mxxyMyzz + mxxyPyzz) * c1o2;
+                        mfabc = (-mxxyMyzz + mxxyPyzz) * c1o2;
+                        mfcab = (mxxzMyyz + mxxzPyyz) * c1o2;
+                        mfacb = (-mxxzMyyz + mxxzPyyz) * c1o2;
+                        mfbca = (mxyyMxzz + mxyyPxzz) * c1o2;
+                        mfbac = (-mxyyMxzz + mxyyPxzz) * c1o2;
+
+                        // 4.
+                        CUMacc = -O4 * (c1o1 / collFactorM - c1o2) * (dyuy + dzuz) * c2o3 * A + (c1o1 - O4) * (CUMacc);
+                        CUMcac = -O4 * (c1o1 / collFactorM - c1o2) * (dxux + dzuz) * c2o3 * A + (c1o1 - O4) * (CUMcac);
+                        CUMcca = -O4 * (c1o1 / collFactorM - c1o2) * (dyuy + dxux) * c2o3 * A + (c1o1 - O4) * (CUMcca);
+                        CUMbbc = -O4 * (c1o1 / collFactorM - c1o2) * Dxy * c1o3 * BB + (c1o1 - O4) * (CUMbbc);
+                        CUMbcb = -O4 * (c1o1 / collFactorM - c1o2) * Dxz * c1o3 * BB + (c1o1 - O4) * (CUMbcb);
+                        CUMcbb = -O4 * (c1o1 / collFactorM - c1o2) * Dyz * c1o3 * BB + (c1o1 - O4) * (CUMcbb);
+
+                        // 5.
+                        CUMbcc += O5 * (-CUMbcc);
+                        CUMcbc += O5 * (-CUMcbc);
+                        CUMccb += O5 * (-CUMccb);
+
+                        // 6.
+                        CUMccc += O6 * (-CUMccc);
+
+                        // back cumulants to central moments
+                        // 4.
+                        mfcbb = CUMcbb + ((mfcaa + c1o3) * mfabb + 2. * mfbba * mfbab);
+                        mfbcb = CUMbcb + ((mfaca + c1o3) * mfbab + 2. * mfbba * mfabb);
+                        mfbbc = CUMbbc + ((mfaac + c1o3) * mfbba + 2. * mfbab * mfabb);
+
+                        mfcca = CUMcca + (mfcaa * mfaca + 2. * mfbba * mfbba) + c1o3 * (mfcaa + mfaca) * oMdrho + c1o9 * (oMdrho - c1o1) * oMdrho;
+                        mfcac = CUMcac + (mfcaa * mfaac + 2. * mfbab * mfbab) + c1o3 * (mfcaa + mfaac) * oMdrho + c1o9 * (oMdrho - c1o1) * oMdrho;
+                        mfacc = CUMacc + (mfaac * mfaca + 2. * mfabb * mfabb) + c1o3 * (mfaac + mfaca) * oMdrho + c1o9 * (oMdrho - c1o1) * oMdrho;
+
+                        // 5.
+                        mfbcc = CUMbcc + (mfaac * mfbca + mfaca * mfbac + 4. * mfabb * mfbbb + 2. * (mfbab * mfacb + mfbba * mfabc)) + c1o3 * (mfbca + mfbac) * oMdrho;
+                        mfcbc = CUMcbc + (mfaac * mfcba + mfcaa * mfabc + 4. * mfbab * mfbbb + 2. * (mfabb * mfcab + mfbba * mfbac)) + c1o3 * (mfcba + mfabc) * oMdrho;
+                        mfccb = CUMccb + (mfcaa * mfacb + mfaca * mfcab + 4. * mfbba * mfbbb + 2. * (mfbab * mfbca + mfabb * mfcba)) + c1o3 * (mfacb + mfcab) * oMdrho;
+
+                        // 6.
+                        mfccc = CUMccc -
+                                ((-4. * mfbbb * mfbbb - (mfcaa * mfacc + mfaca * mfcac + mfaac * mfcca) - 4. * (mfabb * mfcbb + mfbac * mfbca + mfbba * mfbbc) - 2. * (mfbca * mfbac + mfcba * mfabc + mfcab * mfacb)) +
+                                 (4. * (mfbab * mfbab * mfaca + mfabb * mfabb * mfcaa + mfbba * mfbba * mfaac) + 2. * (mfcaa * mfaca * mfaac) + 16. * mfbba * mfbab * mfabb) - c1o3 * (mfacc + mfcac + mfcca) * oMdrho - c1o9 * oMdrho * oMdrho -
+                                 c1o9 * (mfcaa + mfaca + mfaac) * oMdrho * (1. - 2. * oMdrho) - c1o27 * oMdrho * oMdrho * (-2. * oMdrho) + (2. * (mfbab * mfbab + mfabb * mfabb + mfbba * mfbba) + (mfaac * mfaca + mfaac * mfcaa + mfaca * mfcaa)) * c2o3 * oMdrho) -
+                                c1o27 * oMdrho;
+
+                        ////////
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // forcing
+                        mfbaa = -mfbaa;
+                        mfaba = -mfaba;
+                        mfaab = -mfaab;
+
+                        backwardInverseChimeraWithKincompressible(mfaaa, mfbaa, mfcaa, vvx, vx2, c1o1, c1o1, oMdrho);
+                        backwardChimera(mfaba, mfbba, mfcba, vvx, vx2);
+                        backwardInverseChimeraWithKincompressible(mfaca, mfbca, mfcca, vvx, vx2, c3o1, c1o3, oMdrho);
+                        backwardChimera(mfaab, mfbab, mfcab, vvx, vx2);
+                        backwardChimera(mfabb, mfbbb, mfcbb, vvx, vx2);
+                        backwardChimera(mfacb, mfbcb, mfccb, vvx, vx2);
+                        backwardInverseChimeraWithKincompressible(mfaac, mfbac, mfcac, vvx, vx2, c3o1, c1o3, oMdrho);
+                        backwardChimera(mfabc, mfbbc, mfcbc, vvx, vx2);
+                        backwardInverseChimeraWithKincompressible(mfacc, mfbcc, mfccc, vvx, vx2, c9o1, c1o9, oMdrho);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // Y - Dir
+                        backwardInverseChimeraWithKincompressible(mfaaa, mfaba, mfaca, vvy, vy2, c6o1, c1o6, oMdrho);
+                        backwardChimera(mfaab, mfabb, mfacb, vvy, vy2);
+                        backwardInverseChimeraWithKincompressible(mfaac, mfabc, mfacc, vvy, vy2, c18o1, c1o18, oMdrho);
+                        backwardInverseChimeraWithKincompressible(mfbaa, mfbba, mfbca, vvy, vy2, c3o2, c2o3, oMdrho);
+                        backwardChimera(mfbab, mfbbb, mfbcb, vvy, vy2);
+                        backwardInverseChimeraWithKincompressible(mfbac, mfbbc, mfbcc, vvy, vy2, c9o2, c2o9, oMdrho);
+                        backwardInverseChimeraWithKincompressible(mfcaa, mfcba, mfcca, vvy, vy2, c6o1, c1o6, oMdrho);
+                        backwardChimera(mfcab, mfcbb, mfccb, vvy, vy2);
+                        backwardInverseChimeraWithKincompressible(mfcac, mfcbc, mfccc, vvy, vy2, c18o1, c1o18, oMdrho);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // Z - Dir
+                        backwardInverseChimeraWithKincompressible(mfaaa, mfaab, mfaac, vvz, vz2, c36o1, c1o36, oMdrho);
+                        backwardInverseChimeraWithKincompressible(mfaba, mfabb, mfabc, vvz, vz2, c9o1, c1o9, oMdrho);
+                        backwardInverseChimeraWithKincompressible(mfaca, mfacb, mfacc, vvz, vz2, c36o1, c1o36, oMdrho);
+                        backwardInverseChimeraWithKincompressible(mfbaa, mfbab, mfbac, vvz, vz2, c9o1, c1o9, oMdrho);
+                        backwardInverseChimeraWithKincompressible(mfbba, mfbbb, mfbbc, vvz, vz2, c9o4, c4o9, oMdrho);
+                        backwardInverseChimeraWithKincompressible(mfbca, mfbcb, mfbcc, vvz, vz2, c9o1, c1o9, oMdrho);
+                        backwardInverseChimeraWithKincompressible(mfcaa, mfcab, mfcac, vvz, vz2, c36o1, c1o36, oMdrho);
+                        backwardInverseChimeraWithKincompressible(mfcba, mfcbb, mfcbc, vvz, vz2, c9o1, c1o9, oMdrho);
+                        backwardInverseChimeraWithKincompressible(mfcca, mfccb, mfccc, vvz, vz2, c36o1, c1o36, oMdrho);
+                        //////////////////////////////////////////////////////////////////////////
+                        // proof correctness
+                        //////////////////////////////////////////////////////////////////////////
+                        // #ifdef  PROOF_CORRECTNESS
+                        real rho_post = (mfaaa + mfaac + mfaca + mfcaa + mfacc + mfcac + mfccc + mfcca) + (mfaab + mfacb + mfcab + mfccb) + (mfaba + mfabc + mfcba + mfcbc) + (mfbaa + mfbac + mfbca + mfbcc) + (mfabb + mfcbb) + (mfbab + mfbcb) + (mfbba + mfbbc) + mfbbb;
+
+                        if (UbMath::isNaN(rho_post) || UbMath::isInfinity(rho_post)) UB_THROW(UbException(UB_EXARGS, "rho_post is not a number (nan or -1.#IND) or infinity number -1.#INF, node=" + UbSystem::toString(x1) + "," + UbSystem::toString(x2) + "," + UbSystem::toString(x3)));
+
+                        //////////////////////////////////////////////////////////////////////////
+                        // write distribution
+                        //////////////////////////////////////////////////////////////////////////
+                        //	if (phi[DIR_000] < c1o2) {
+                        (*this->localDistributionsF)(D3Q27System::ET_E, x1, x2, x3) = mfabb;         //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_N, x1, x2, x3) = mfbab;         //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_T, x1, x2, x3) = mfbba;         //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_NE, x1, x2, x3) = mfaab;        //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_NW, x1p, x2, x3) = mfcab;       //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_TE, x1, x2, x3) = mfaba;        //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_TW, x1p, x2, x3) = mfcba;       //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_TN, x1, x2, x3) = mfbaa;        //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_TS, x1, x2p, x3) = mfbca;       //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_TNE, x1, x2, x3) = mfaaa;       //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_TNW, x1p, x2, x3) = mfcaa;      //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_TSE, x1, x2p, x3) = mfaca;      //* rho * c1o3;
+                        (*this->localDistributionsF)(D3Q27System::ET_TSW, x1p, x2p, x3) = mfcca;     //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_W, x1p, x2, x3) = mfcbb;     //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_S, x1, x2p, x3) = mfbcb;     //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_B, x1, x2, x3p) = mfbbc;     //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_SW, x1p, x2p, x3) = mfccb;   //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_SE, x1, x2p, x3) = mfacb;    //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BW, x1p, x2, x3p) = mfcbc;   //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BE, x1, x2, x3p) = mfabc;    //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BS, x1, x2p, x3p) = mfbcc;   //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BN, x1, x2, x3p) = mfbac;    //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BSW, x1p, x2p, x3p) = mfccc; //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BSE, x1, x2p, x3p) = mfacc;  //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BNW, x1p, x2, x3p) = mfcac;  //* rho * c1o3;
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BNE, x1, x2, x3p) = mfaac;   //* rho * c1o3;
+
+                        (*this->restDistributionsF)(x1, x2, x3) = mfbbb; // *rho* c1o3;
+
+                        f[vf::lbm::dir::DIR_000] = mfbbb;
+
+                        f[vf::lbm::dir::DIR_P00] = mfcbb;
+                        f[vf::lbm::dir::DIR_0P0] = mfbcb;
+                        f[vf::lbm::dir::DIR_00P] = mfbbc;
+                        f[vf::lbm::dir::DIR_PP0] = mfccb;
+                        f[vf::lbm::dir::DIR_MP0] = mfacb;
+                        f[vf::lbm::dir::DIR_P0P] = mfcbc;
+                        f[vf::lbm::dir::DIR_M0P] = mfabc;
+                        f[vf::lbm::dir::DIR_0PP] = mfbcc;
+                        f[vf::lbm::dir::DIR_0MP] = mfbac;
+                        f[vf::lbm::dir::DIR_PPP] = mfccc;
+                        f[vf::lbm::dir::DIR_MPP] = mfacc;
+                        f[vf::lbm::dir::DIR_PMP] = mfcac;
+                        f[vf::lbm::dir::DIR_MMP] = mfaac;
+
+                        f[vf::lbm::dir::DIR_M00] = mfabb;
+                        f[vf::lbm::dir::DIR_0M0] = mfbab;
+                        f[vf::lbm::dir::DIR_00M] = mfbba;
+                        f[vf::lbm::dir::DIR_MM0] = mfaab;
+                        f[vf::lbm::dir::DIR_PM0] = mfcab;
+                        f[vf::lbm::dir::DIR_M0M] = mfaba;
+                        f[vf::lbm::dir::DIR_P0M] = mfcba;
+                        f[vf::lbm::dir::DIR_0MM] = mfbaa;
+                        f[vf::lbm::dir::DIR_0PM] = mfbca;
+                        f[vf::lbm::dir::DIR_MMM] = mfaaa;
+                        f[vf::lbm::dir::DIR_PMM] = mfcaa;
+                        f[vf::lbm::dir::DIR_MPM] = mfaca;
+                        f[vf::lbm::dir::DIR_PPM] = mfcca;
+                    }
+                    if ((*particleData)(x1, x2, x3)->solidFraction >= SOLFRAC_MIN) {
+                        real vx1, vx2, vx3, drho;
+                        D3Q27System::calcIncompMacroscopicValues(f, drho, vx1, vx2, vx3);
+                        D3Q27System::calcIncompFeq(fEq, drho, vx1, vx2, vx3);
+
+                        std::array<double, 3> uPart;
+                        uPart[0] = (*particleData)(x1, x2, x3)->uPart[0];
+                        uPart[1] = (*particleData)(x1, x2, x3)->uPart[1];
+                        uPart[2] = (*particleData)(x1, x2, x3)->uPart[2];
+
+                        D3Q27System::calcIncompFeq(fEqSolid, drho, uPart[0], uPart[1], uPart[2]);
+                        real rhoPhaseField = (phi[DIR_000] > c1o2) ? c1o1 : c1o1 / densityRatio;
+                        if ((*particleData)(x1, x2, x3)->solidFraction > SOLFRAC_MAX) {
+                            double const bb0 = fEq[vf::lbm::dir::DIR_000] - fEqSolid[vf::lbm::dir::DIR_000];
+                            f[vf::lbm::dir::DIR_000] = fPre[vf::lbm::dir::DIR_000] + bb0;
+                            for (int iPop = D3Q27System::FSTARTDIR; iPop <= D3Q27System::FENDDIR; iPop++) {
+                                const int iOpp = D3Q27System::INVDIR[iPop];
+                                double const bb = ((fPre[iOpp] - fEq[iOpp]) - (fPre[iPop] - fEqSolid[iPop]));
+                                double const bbOpp = ((fPre[iPop] - fEq[iPop]) - (fPre[iOpp] - fEqSolid[iOpp]));
+
+                                f[iPop] = fPre[iPop] + bb;
+                                f[iOpp] = fPre[iOpp] + bbOpp;
+
+                                (*particleData)(x1, x2, x3)->hydrodynamicForce[0] -= D3Q27System::DX1[iPop] * (bb - bbOpp) * rhoPhaseField;
+                                (*particleData)(x1, x2, x3)->hydrodynamicForce[1] -= D3Q27System::DX2[iPop] * (bb - bbOpp) * rhoPhaseField;
+                                (*particleData)(x1, x2, x3)->hydrodynamicForce[2] -= D3Q27System::DX3[iPop] * (bb - bbOpp) * rhoPhaseField;
+                            }
+                        } else { /* particleData.solidFraction < SOLFRAC_MAX */
+                                 // #ifdef LBDEM_USE_WEIGHING
+                            double const ooo = 1. / collFactorM - 0.5;
+                            double const B = (*particleData)(x1, x2, x3)->solidFraction * ooo / ((1. - (*particleData)(x1, x2, x3)->solidFraction) + ooo);
+                            // #else
+                            //                         T const B = particleData.solidFraction;
+                            // #endif
+                            double const oneMinB = 1. - B;
+
+                            double const bb0 = fEq[vf::lbm::dir::DIR_000] - fEqSolid[vf::lbm::dir::DIR_000];
+                            f[vf::lbm::dir::DIR_000] = fPre[vf::lbm::dir::DIR_000] + oneMinB * (f[vf::lbm::dir::DIR_000] - fPre[vf::lbm::dir::DIR_000]) + B * bb0;
+
+                            for (int iPop = D3Q27System::FSTARTDIR; iPop <= D3Q27System::FENDDIR; iPop++) {
+                                int const iOpp = D3Q27System::INVDIR[iPop];
+                                double const bb = B * ((fPre[iOpp] - fEq[iOpp]) - (fPre[iPop] - fEqSolid[iPop]));
+                                double const bbOpp = B * ((fPre[iPop] - fEq[iPop]) - (fPre[iOpp] - fEqSolid[iOpp]));
+
+                                f[iPop] = fPre[iPop] + oneMinB * (f[iPop] - fPre[iPop]) + bb;
+                                f[iOpp] = fPre[iOpp] + oneMinB * (f[iOpp] - fPre[iOpp]) + bbOpp;
+
+                                (*particleData)(x1, x2, x3)->hydrodynamicForce[0] -= D3Q27System::DX1[iPop] * (bb - bbOpp) * rhoPhaseField;
+                                (*particleData)(x1, x2, x3)->hydrodynamicForce[1] -= D3Q27System::DX2[iPop] * (bb - bbOpp) * rhoPhaseField;
+                                (*particleData)(x1, x2, x3)->hydrodynamicForce[2] -= D3Q27System::DX3[iPop] * (bb - bbOpp) * rhoPhaseField;
+                            }
+                        } /* if solidFraction > SOLFRAC_MAX */
+
+                        (*this->restDistributionsF)(x1, x2, x3) = f[vf::lbm::dir::DIR_000];
+
+                        (*this->localDistributionsF)(D3Q27System::ET_E, x1, x2, x3) = f[vf::lbm::dir::DIR_M00];
+                        (*this->localDistributionsF)(D3Q27System::ET_N, x1, x2, x3) = f[vf::lbm::dir::DIR_0M0];
+                        (*this->localDistributionsF)(D3Q27System::ET_T, x1, x2, x3) = f[vf::lbm::dir::DIR_00M];
+                        (*this->localDistributionsF)(D3Q27System::ET_NE, x1, x2, x3) = f[vf::lbm::dir::DIR_MM0];
+                        (*this->localDistributionsF)(D3Q27System::ET_NW, x1p, x2, x3) = f[vf::lbm::dir::DIR_PM0];
+                        (*this->localDistributionsF)(D3Q27System::ET_TE, x1, x2, x3) = f[vf::lbm::dir::DIR_M0M];
+                        (*this->localDistributionsF)(D3Q27System::ET_TW, x1p, x2, x3) = f[vf::lbm::dir::DIR_P0M];
+                        (*this->localDistributionsF)(D3Q27System::ET_TN, x1, x2, x3) = f[vf::lbm::dir::DIR_0MM];
+                        (*this->localDistributionsF)(D3Q27System::ET_TS, x1, x2p, x3) = f[vf::lbm::dir::DIR_0PM];
+                        (*this->localDistributionsF)(D3Q27System::ET_TNE, x1, x2, x3) = f[vf::lbm::dir::DIR_MMM];
+                        (*this->localDistributionsF)(D3Q27System::ET_TNW, x1p, x2, x3) = f[vf::lbm::dir::DIR_PMM];
+                        (*this->localDistributionsF)(D3Q27System::ET_TSE, x1, x2p, x3) = f[vf::lbm::dir::DIR_MPM];
+                        (*this->localDistributionsF)(D3Q27System::ET_TSW, x1p, x2p, x3) = f[vf::lbm::dir::DIR_PPM];
+
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_W, x1p, x2, x3) = f[vf::lbm::dir::DIR_P00];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_S, x1, x2p, x3) = f[vf::lbm::dir::DIR_0P0];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_B, x1, x2, x3p) = f[vf::lbm::dir::DIR_00P];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_SW, x1p, x2p, x3) = f[vf::lbm::dir::DIR_PP0];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_SE, x1, x2p, x3) = f[vf::lbm::dir::DIR_MP0];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BW, x1p, x2, x3p) = f[vf::lbm::dir::DIR_P0P];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BE, x1, x2, x3p) = f[vf::lbm::dir::DIR_M0P];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BS, x1, x2p, x3p) = f[vf::lbm::dir::DIR_0PP];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BN, x1, x2, x3p) = f[vf::lbm::dir::DIR_0MP];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BSW, x1p, x2p, x3p) = f[vf::lbm::dir::DIR_PPP];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BSE, x1, x2p, x3p) = f[vf::lbm::dir::DIR_MPP];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BNW, x1p, x2, x3p) = f[vf::lbm::dir::DIR_PMP];
+                        (*this->nonLocalDistributionsF)(D3Q27System::ET_BNE, x1, x2, x3p) = f[vf::lbm::dir::DIR_MMP];                   
+                    }
+
+
+
+                        /////////////////////  P H A S E - F I E L D   S O L V E R
+                     ////////////////////////////////////////////
+                                                                     /////CUMULANT PHASE-FIELD
+                    real omegaD = 1.0 / (3.0 * mob + 0.5);
+                    {
+                        mfcbb = (*this->localDistributionsH1)(D3Q27System::ET_E, x1, x2, x3);
+                        mfbcb = (*this->localDistributionsH1)(D3Q27System::ET_N, x1, x2, x3);
+                        mfbbc = (*this->localDistributionsH1)(D3Q27System::ET_T, x1, x2, x3);
+                        mfccb = (*this->localDistributionsH1)(D3Q27System::ET_NE, x1, x2, x3);
+                        mfacb = (*this->localDistributionsH1)(D3Q27System::ET_NW, x1p, x2, x3);
+                        mfcbc = (*this->localDistributionsH1)(D3Q27System::ET_TE, x1, x2, x3);
+                        mfabc = (*this->localDistributionsH1)(D3Q27System::ET_TW, x1p, x2, x3);
+                        mfbcc = (*this->localDistributionsH1)(D3Q27System::ET_TN, x1, x2, x3);
+                        mfbac = (*this->localDistributionsH1)(D3Q27System::ET_TS, x1, x2p, x3);
+                        mfccc = (*this->localDistributionsH1)(D3Q27System::ET_TNE, x1, x2, x3);
+                        mfacc = (*this->localDistributionsH1)(D3Q27System::ET_TNW, x1p, x2, x3);
+                        mfcac = (*this->localDistributionsH1)(D3Q27System::ET_TSE, x1, x2p, x3);
+                        mfaac = (*this->localDistributionsH1)(D3Q27System::ET_TSW, x1p, x2p, x3);
+                        mfabb = (*this->nonLocalDistributionsH1)(D3Q27System::ET_W, x1p, x2, x3);
+                        mfbab = (*this->nonLocalDistributionsH1)(D3Q27System::ET_S, x1, x2p, x3);
+                        mfbba = (*this->nonLocalDistributionsH1)(D3Q27System::ET_B, x1, x2, x3p);
+                        mfaab = (*this->nonLocalDistributionsH1)(D3Q27System::ET_SW, x1p, x2p, x3);
+                        mfcab = (*this->nonLocalDistributionsH1)(D3Q27System::ET_SE, x1, x2p, x3);
+                        mfaba = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BW, x1p, x2, x3p);
+                        mfcba = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BE, x1, x2, x3p);
+                        mfbaa = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BS, x1, x2p, x3p);
+                        mfbca = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BN, x1, x2, x3p);
+                        mfaaa = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BSW, x1p, x2p, x3p);
+                        mfcaa = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BSE, x1, x2p, x3p);
+                        mfaca = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BNW, x1p, x2, x3p);
+                        mfcca = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BNE, x1, x2, x3p);
+                        mfbbb = (*this->restDistributionsH1)(x1, x2, x3);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        //! - 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>
+                        //!
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // second component
+                        real concentration =
+                            ((((mfccc + mfaaa) + (mfaca + mfcac)) + ((mfacc + mfcaa) + (mfaac + mfcca))) + (((mfbac + mfbca) + (mfbaa + mfbcc)) + ((mfabc + mfcba) + (mfaba + mfcbc)) + ((mfacb + mfcab) + (mfaab + mfccb))) + ((mfabb + mfcbb) + (mfbab + mfbcb) + (mfbba + mfbbc))) + mfbbb;
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        real oneMinusRho = c1o1 - concentration;
+
+                        real cx = ((((mfccc - mfaaa) + (mfcac - mfaca)) + ((mfcaa - mfacc) + (mfcca - mfaac))) + (((mfcba - mfabc) + (mfcbc - mfaba)) + ((mfcab - mfacb) + (mfccb - mfaab))) + (mfcbb - mfabb));
+                        real cy = ((((mfccc - mfaaa) + (mfaca - mfcac)) + ((mfacc - mfcaa) + (mfcca - mfaac))) + (((mfbca - mfbac) + (mfbcc - mfbaa)) + ((mfacb - mfcab) + (mfccb - mfaab))) + (mfbcb - mfbab));
+                        real cz = ((((mfccc - mfaaa) + (mfcac - mfaca)) + ((mfacc - mfcaa) + (mfaac - mfcca))) + (((mfbac - mfbca) + (mfbcc - mfbaa)) + ((mfabc - mfcba) + (mfcbc - mfaba))) + (mfbbc - mfbba));
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // calculate the square of velocities for this lattice node
+                        real cx2 = cx * cx;
+                        real cy2 = cy * cy;
+                        real cz2 = cz * cz;
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        //! - Chimera transform from well conditioned distributions to central moments as defined in Appendix J 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>
+                        //! see also 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>
+                        //!
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // Z - Dir
+                        forwardInverseChimeraWithKincompressible(mfaaa, mfaab, mfaac, cz, cz2, c36o1, c1o36, oneMinusRho);
+                        forwardInverseChimeraWithKincompressible(mfaba, mfabb, mfabc, cz, cz2, c9o1, c1o9, oneMinusRho);
+                        forwardInverseChimeraWithKincompressible(mfaca, mfacb, mfacc, cz, cz2, c36o1, c1o36, oneMinusRho);
+                        forwardInverseChimeraWithKincompressible(mfbaa, mfbab, mfbac, cz, cz2, c9o1, c1o9, oneMinusRho);
+                        forwardInverseChimeraWithKincompressible(mfbba, mfbbb, mfbbc, cz, cz2, c9o4, c4o9, oneMinusRho);
+                        forwardInverseChimeraWithKincompressible(mfbca, mfbcb, mfbcc, cz, cz2, c9o1, c1o9, oneMinusRho);
+                        forwardInverseChimeraWithKincompressible(mfcaa, mfcab, mfcac, cz, cz2, c36o1, c1o36, oneMinusRho);
+                        forwardInverseChimeraWithKincompressible(mfcba, mfcbb, mfcbc, cz, cz2, c9o1, c1o9, oneMinusRho);
+                        forwardInverseChimeraWithKincompressible(mfcca, mfccb, mfccc, cz, cz2, c36o1, c1o36, oneMinusRho);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // Y - Dir
+                        forwardInverseChimeraWithKincompressible(mfaaa, mfaba, mfaca, cy, cy2, c6o1, c1o6, oneMinusRho);
+                        forwardChimera(mfaab, mfabb, mfacb, cy, cy2);
+                        forwardInverseChimeraWithKincompressible(mfaac, mfabc, mfacc, cy, cy2, c18o1, c1o18, oneMinusRho);
+                        forwardInverseChimeraWithKincompressible(mfbaa, mfbba, mfbca, cy, cy2, c3o2, c2o3, oneMinusRho);
+                        forwardChimera(mfbab, mfbbb, mfbcb, cy, cy2);
+                        forwardInverseChimeraWithKincompressible(mfbac, mfbbc, mfbcc, cy, cy2, c9o2, c2o9, oneMinusRho);
+                        forwardInverseChimeraWithKincompressible(mfcaa, mfcba, mfcca, cy, cy2, c6o1, c1o6, oneMinusRho);
+                        forwardChimera(mfcab, mfcbb, mfccb, cy, cy2);
+                        forwardInverseChimeraWithKincompressible(mfcac, mfcbc, mfccc, cy, cy2, c18o1, c1o18, oneMinusRho);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // X - Dir
+                        forwardInverseChimeraWithKincompressible(mfaaa, mfbaa, mfcaa, cx, cx2, c1o1, c1o1, oneMinusRho);
+                        forwardChimera(mfaba, mfbba, mfcba, cx, cx2);
+                        forwardInverseChimeraWithKincompressible(mfaca, mfbca, mfcca, cx, cx2, c3o1, c1o3, oneMinusRho);
+                        forwardChimera(mfaab, mfbab, mfcab, cx, cx2);
+                        forwardChimera(mfabb, mfbbb, mfcbb, cx, cx2);
+                        forwardChimera(mfacb, mfbcb, mfccb, cx, cx2);
+                        forwardInverseChimeraWithKincompressible(mfaac, mfbac, mfcac, cx, cx2, c3o1, c1o3, oneMinusRho);
+                        forwardChimera(mfabc, mfbbc, mfcbc, cx, cx2);
+                        forwardInverseChimeraWithKincompressible(mfacc, mfbcc, mfccc, cx, cx2, c3o1, c1o9, oneMinusRho);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        //! - experimental Cumulant ... to be published ... hopefully
+                        //!
+
+                        // linearized orthogonalization of 3rd order central moments
+                        real Mabc = mfabc - mfaba * c1o3;
+                        real Mbca = mfbca - mfbaa * c1o3;
+                        real Macb = mfacb - mfaab * c1o3;
+                        real Mcba = mfcba - mfaba * c1o3;
+                        real Mcab = mfcab - mfaab * c1o3;
+                        real Mbac = mfbac - mfbaa * c1o3;
+                        // linearized orthogonalization of 5th order central moments
+                        real Mcbc = mfcbc - mfaba * c1o9;
+                        real Mbcc = mfbcc - mfbaa * c1o9;
+                        real Mccb = mfccb - mfaab * c1o9;
+
+                        // 31.05.2022 addaptive mobility
+                        // omegaD = c1o1 + (sqrt((cx - vvx * concentration) * (cx - vvx * concentration) + (cy - vvy * concentration) * (cy - vvy * concentration) + (cz - vvz * concentration) * (cz - vvz * concentration))) / (sqrt((cx - vvx * concentration) * (cx - vvx * concentration) + (cy - vvy *
+                        // concentration) * (cy - vvy * concentration) + (cz - vvz * concentration) * (cz - vvz * concentration)) + fabs((1.0 - concentration) * (concentration)) * c1o6 * oneOverInterfaceScale+1.0e-200); omegaD = c2o1 * (concentration * (concentration - c1o1)) / (-c6o1 * (sqrt((cx -
+                        // vvx * concentration) * (cx - vvx * concentration) + (cy - vvy * concentration) * (cy - vvy * concentration) + (cz - vvz * concentration) * (cz - vvz * concentration))) + (concentration * (concentration - c1o1))+1.0e-200);
+                        //  collision of 1st order moments
+                        cx = cx * (c1o1 - omegaD) + omegaD * vvx * concentration + normX1 * (c1o1 - 0.5 * omegaD) * (1.0 - concentration) * (concentration)*c1o3 * oneOverInterfaceScale;
+                        cy = cy * (c1o1 - omegaD) + omegaD * vvy * concentration + normX2 * (c1o1 - 0.5 * omegaD) * (1.0 - concentration) * (concentration)*c1o3 * oneOverInterfaceScale;
+                        cz = cz * (c1o1 - omegaD) + omegaD * vvz * concentration + normX3 * (c1o1 - 0.5 * omegaD) * (1.0 - concentration) * (concentration)*c1o3 * oneOverInterfaceScale;
+
+                        cx2 = cx * cx;
+                        cy2 = cy * cy;
+                        cz2 = cz * cz;
+
+                        // equilibration of 2nd order moments
+                        mfbba = c0o1;
+                        mfbab = c0o1;
+                        mfabb = c0o1;
+
+                        mfcaa = c1o3 * concentration;
+                        mfaca = c1o3 * concentration;
+                        mfaac = c1o3 * concentration;
+
+                        // equilibration of 3rd order moments
+                        Mabc = c0o1;
+                        Mbca = c0o1;
+                        Macb = c0o1;
+                        Mcba = c0o1;
+                        Mcab = c0o1;
+                        Mbac = c0o1;
+                        mfbbb = c0o1;
+
+                        // from linearized orthogonalization 3rd order central moments to central moments
+                        mfabc = Mabc + mfaba * c1o3;
+                        mfbca = Mbca + mfbaa * c1o3;
+                        mfacb = Macb + mfaab * c1o3;
+                        mfcba = Mcba + mfaba * c1o3;
+                        mfcab = Mcab + mfaab * c1o3;
+                        mfbac = Mbac + mfbaa * c1o3;
+
+                        // equilibration of 4th order moments
+                        mfacc = c1o9 * concentration;
+                        mfcac = c1o9 * concentration;
+                        mfcca = c1o9 * concentration;
+
+                        mfcbb = c0o1;
+                        mfbcb = c0o1;
+                        mfbbc = c0o1;
+
+                        // equilibration of 5th order moments
+                        Mcbc = c0o1;
+                        Mbcc = c0o1;
+                        Mccb = c0o1;
+
+                        // from linearized orthogonalization 5th order central moments to central moments
+                        mfcbc = Mcbc + mfaba * c1o9;
+                        mfbcc = Mbcc + mfbaa * c1o9;
+                        mfccb = Mccb + mfaab * c1o9;
+
+                        // equilibration of 6th order moment
+                        mfccc = c1o27 * concentration;
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        //! - Chimera transform from central moments to well conditioned distributions as defined in Appendix J in
+                        //! <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>
+                        //! see also Eq. (88)-(96) in
+                        //! <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>
+                        //!
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // X - Dir
+                        backwardInverseChimeraWithKincompressible(mfaaa, mfbaa, mfcaa, cx, cx2, c1o1, c1o1, oneMinusRho);
+                        backwardChimera(mfaba, mfbba, mfcba, cx, cx2);
+                        backwardInverseChimeraWithKincompressible(mfaca, mfbca, mfcca, cx, cx2, c3o1, c1o3, oneMinusRho);
+                        backwardChimera(mfaab, mfbab, mfcab, cx, cx2);
+                        backwardChimera(mfabb, mfbbb, mfcbb, cx, cx2);
+                        backwardChimera(mfacb, mfbcb, mfccb, cx, cx2);
+                        backwardInverseChimeraWithKincompressible(mfaac, mfbac, mfcac, cx, cx2, c3o1, c1o3, oneMinusRho);
+                        backwardChimera(mfabc, mfbbc, mfcbc, cx, cx2);
+                        backwardInverseChimeraWithKincompressible(mfacc, mfbcc, mfccc, cx, cx2, c9o1, c1o9, oneMinusRho);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // Y - Dir
+                        backwardInverseChimeraWithKincompressible(mfaaa, mfaba, mfaca, cy, cy2, c6o1, c1o6, oneMinusRho);
+                        backwardChimera(mfaab, mfabb, mfacb, cy, cy2);
+                        backwardInverseChimeraWithKincompressible(mfaac, mfabc, mfacc, cy, cy2, c18o1, c1o18, oneMinusRho);
+                        backwardInverseChimeraWithKincompressible(mfbaa, mfbba, mfbca, cy, cy2, c3o2, c2o3, oneMinusRho);
+                        backwardChimera(mfbab, mfbbb, mfbcb, cy, cy2);
+                        backwardInverseChimeraWithKincompressible(mfbac, mfbbc, mfbcc, cy, cy2, c9o2, c2o9, oneMinusRho);
+                        backwardInverseChimeraWithKincompressible(mfcaa, mfcba, mfcca, cy, cy2, c6o1, c1o6, oneMinusRho);
+                        backwardChimera(mfcab, mfcbb, mfccb, cy, cy2);
+                        backwardInverseChimeraWithKincompressible(mfcac, mfcbc, mfccc, cy, cy2, c18o1, c1o18, oneMinusRho);
+
+                        ////////////////////////////////////////////////////////////////////////////////////
+                        // Z - Dir
+                        backwardInverseChimeraWithKincompressible(mfaaa, mfaab, mfaac, cz, cz2, c36o1, c1o36, oneMinusRho);
+                        backwardInverseChimeraWithKincompressible(mfaba, mfabb, mfabc, cz, cz2, c9o1, c1o9, oneMinusRho);
+                        backwardInverseChimeraWithKincompressible(mfaca, mfacb, mfacc, cz, cz2, c36o1, c1o36, oneMinusRho);
+                        backwardInverseChimeraWithKincompressible(mfbaa, mfbab, mfbac, cz, cz2, c9o1, c1o9, oneMinusRho);
+                        backwardInverseChimeraWithKincompressible(mfbba, mfbbb, mfbbc, cz, cz2, c9o4, c4o9, oneMinusRho);
+                        backwardInverseChimeraWithKincompressible(mfbca, mfbcb, mfbcc, cz, cz2, c9o1, c1o9, oneMinusRho);
+                        backwardInverseChimeraWithKincompressible(mfcaa, mfcab, mfcac, cz, cz2, c36o1, c1o36, oneMinusRho);
+                        backwardInverseChimeraWithKincompressible(mfcba, mfcbb, mfcbc, cz, cz2, c9o1, c1o9, oneMinusRho);
+                        backwardInverseChimeraWithKincompressible(mfcca, mfccb, mfccc, cz, cz2, c36o1, c1o36, oneMinusRho);
+
+                        (*this->localDistributionsH1)(D3Q27System::ET_E, x1, x2, x3) = mfabb;
+                        (*this->localDistributionsH1)(D3Q27System::ET_N, x1, x2, x3) = mfbab;
+                        (*this->localDistributionsH1)(D3Q27System::ET_T, x1, x2, x3) = mfbba;
+                        (*this->localDistributionsH1)(D3Q27System::ET_NE, x1, x2, x3) = mfaab;
+                        (*this->localDistributionsH1)(D3Q27System::ET_NW, x1p, x2, x3) = mfcab;
+                        (*this->localDistributionsH1)(D3Q27System::ET_TE, x1, x2, x3) = mfaba;
+                        (*this->localDistributionsH1)(D3Q27System::ET_TW, x1p, x2, x3) = mfcba;
+                        (*this->localDistributionsH1)(D3Q27System::ET_TN, x1, x2, x3) = mfbaa;
+                        (*this->localDistributionsH1)(D3Q27System::ET_TS, x1, x2p, x3) = mfbca;
+                        (*this->localDistributionsH1)(D3Q27System::ET_TNE, x1, x2, x3) = mfaaa;
+                        (*this->localDistributionsH1)(D3Q27System::ET_TNW, x1p, x2, x3) = mfcaa;
+                        (*this->localDistributionsH1)(D3Q27System::ET_TSE, x1, x2p, x3) = mfaca;
+                        (*this->localDistributionsH1)(D3Q27System::ET_TSW, x1p, x2p, x3) = mfcca;
+
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_W, x1p, x2, x3) = mfcbb;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_S, x1, x2p, x3) = mfbcb;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_B, x1, x2, x3p) = mfbbc;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_SW, x1p, x2p, x3) = mfccb;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_SE, x1, x2p, x3) = mfacb;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_BW, x1p, x2, x3p) = mfcbc;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_BE, x1, x2, x3p) = mfabc;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_BS, x1, x2p, x3p) = mfbcc;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_BN, x1, x2, x3p) = mfbac;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_BSW, x1p, x2p, x3p) = mfccc;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_BSE, x1, x2p, x3p) = mfacc;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_BNW, x1p, x2, x3p) = mfcac;
+                        (*this->nonLocalDistributionsH1)(D3Q27System::ET_BNE, x1, x2, x3p) = mfaac;
+
+                        (*this->restDistributionsH1)(x1, x2, x3) = mfbbb;
+
+                    }
+                }
+            }
+        }
+    }
+}
+//////////////////////////////////////////////////////////////////////////
+
+real IBsharpInterfaceLBMKernel::gradX1_phi()
+{
+    using namespace D3Q27System;
+    return 3.0 * ((WEIGTH[DIR_PPP] * (((phi[DIR_PPP] - phi[DIR_MMM]) + (phi[DIR_PMM] - phi[DIR_MPP])) + ((phi[DIR_PMP] - phi[DIR_MPM]) + (phi[DIR_PPM] - phi[DIR_MMP]))) +
+                   WEIGTH[DIR_PP0] * (((phi[DIR_P0P] - phi[DIR_M0M]) + (phi[DIR_P0M] - phi[DIR_M0P])) + ((phi[DIR_PM0] - phi[DIR_MP0]) + (phi[DIR_PP0] - phi[DIR_MM0])))) +
+                  +WEIGTH[DIR_0P0] * (phi[DIR_P00] - phi[DIR_M00]));
+}
+
+real IBsharpInterfaceLBMKernel::gradX2_phi()
+{
+    using namespace D3Q27System;
+    return 3.0 * ((WEIGTH[DIR_PPP] * (((phi[DIR_PPP] - phi[DIR_MMM]) - (phi[DIR_PMM] - phi[DIR_MPP])) + ((phi[DIR_PPM] - phi[DIR_MMP]) - (phi[DIR_PMP] - phi[DIR_MPM]))) +
+                   WEIGTH[DIR_PP0] * (((phi[DIR_0PP] - phi[DIR_0MM]) + (phi[DIR_0PM] - phi[DIR_0MP])) + ((phi[DIR_PP0] - phi[DIR_MM0]) - (phi[DIR_PM0] - phi[DIR_MP0])))) +
+                  +WEIGTH[DIR_0P0] * (phi[DIR_0P0] - phi[DIR_0M0]));
+}
+
+real IBsharpInterfaceLBMKernel::gradX3_phi()
+{
+    using namespace D3Q27System;
+    return 3.0 * ((WEIGTH[DIR_PPP] * (((phi[DIR_PPP] - phi[DIR_MMM]) - (phi[DIR_PMM] - phi[DIR_MPP])) + ((phi[DIR_PMP] - phi[DIR_MPM]) - (phi[DIR_PPM] - phi[DIR_MMP]))) +
+                   WEIGTH[DIR_PP0] * (((phi[DIR_P0P] - phi[DIR_M0M]) - (phi[DIR_P0M] - phi[DIR_M0P])) + ((phi[DIR_0MP] - phi[DIR_0PM]) + (phi[DIR_0PP] - phi[DIR_0MM])))) +
+                  +WEIGTH[DIR_0P0] * (phi[DIR_00P] - phi[DIR_00M]));
+}
+
+real IBsharpInterfaceLBMKernel::gradX1_rhoInv(real rhoL, real rhoDIV)
+{
+    using namespace D3Q27System;
+    return 3.0 * ((WEIGTH[DIR_PPP] * (((1.0 / (rhoL + rhoDIV * phi[DIR_PPP]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MMM])) + (1.0 / (rhoL + rhoDIV * phi[DIR_PMM]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MPP]))) +
+                                      ((1.0 / (rhoL + rhoDIV * phi[DIR_PMP]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MPM])) + (1.0 / (rhoL + rhoDIV * phi[DIR_PPM]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MMP])))) +
+                   WEIGTH[DIR_PP0] * (((1.0 / (rhoL + rhoDIV * phi[DIR_P0P]) - 1.0 / (rhoL + rhoDIV * phi[DIR_M0M])) + (1.0 / (rhoL + rhoDIV * phi[DIR_P0M]) - 1.0 / (rhoL + rhoDIV * phi[DIR_M0P]))) +
+                                      ((1.0 / (rhoL + rhoDIV * phi[DIR_PM0]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MP0])) + (1.0 / (rhoL + rhoDIV * phi[DIR_PP0]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MM0]))))) +
+                  +WEIGTH[DIR_0P0] * (1.0 / (rhoL + rhoDIV * phi[DIR_P00]) - 1.0 / (rhoL + rhoDIV * phi[DIR_M00])));
+}
+
+real IBsharpInterfaceLBMKernel::gradX2_rhoInv(real rhoL, real rhoDIV)
+{
+    using namespace D3Q27System;
+    return 3.0 * ((WEIGTH[DIR_PPP] * (((1.0 / (rhoL + rhoDIV * phi[DIR_PPP]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MMM])) - (1.0 / (rhoL + rhoDIV * phi[DIR_PMM]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MPP]))) +
+                                      ((1.0 / (rhoL + rhoDIV * phi[DIR_PPM]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MMP])) - (1.0 / (rhoL + rhoDIV * phi[DIR_PMP]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MPM])))) +
+                   WEIGTH[DIR_PP0] * (((1.0 / (rhoL + rhoDIV * phi[DIR_0PP]) - 1.0 / (rhoL + rhoDIV * phi[DIR_0MM])) + (1.0 / (rhoL + rhoDIV * phi[DIR_0PM]) - 1.0 / (rhoL + rhoDIV * phi[DIR_0MP]))) +
+                                      ((1.0 / (rhoL + rhoDIV * phi[DIR_PP0]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MM0])) - (1.0 / (rhoL + rhoDIV * phi[DIR_PM0]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MP0]))))) +
+                  +WEIGTH[DIR_0P0] * (1.0 / (rhoL + rhoDIV * phi[DIR_0P0]) - 1.0 / (rhoL + rhoDIV * phi[DIR_0M0])));
+}
+
+real IBsharpInterfaceLBMKernel::gradX3_rhoInv(real rhoL, real rhoDIV)
+{
+    using namespace D3Q27System;
+    return 3.0 * ((WEIGTH[DIR_PPP] * (((1.0 / (rhoL + rhoDIV * phi[DIR_PPP]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MMM])) - (1.0 / (rhoL + rhoDIV * phi[DIR_PMM]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MPP]))) +
+                                      ((1.0 / (rhoL + rhoDIV * phi[DIR_PMP]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MPM])) - (1.0 / (rhoL + rhoDIV * phi[DIR_PPM]) - 1.0 / (rhoL + rhoDIV * phi[DIR_MMP])))) +
+                   WEIGTH[DIR_PP0] * (((1.0 / (rhoL + rhoDIV * phi[DIR_P0P]) - 1.0 / (rhoL + rhoDIV * phi[DIR_M0M])) - (1.0 / (rhoL + rhoDIV * phi[DIR_P0M]) - 1.0 / (rhoL + rhoDIV * phi[DIR_M0P]))) +
+                                      ((1.0 / (rhoL + rhoDIV * phi[DIR_0MP]) - 1.0 / (rhoL + rhoDIV * phi[DIR_0PM])) + (1.0 / (rhoL + rhoDIV * phi[DIR_0PP]) - 1.0 / (rhoL + rhoDIV * phi[DIR_0MM]))))) +
+                  +WEIGTH[DIR_0P0] * (1.0 / (rhoL + rhoDIV * phi[DIR_00P]) - 1.0 / (rhoL + rhoDIV * phi[DIR_00M])));
+}
+
+real IBsharpInterfaceLBMKernel::gradX1_phi2()
+{
+    using namespace D3Q27System;
+    return 3.0 * ((WEIGTH[DIR_PPP] * (((phi2[DIR_PPP] - phi2[DIR_MMM]) + (phi2[DIR_PMM] - phi2[DIR_MPP])) + ((phi2[DIR_PMP] - phi2[DIR_MPM]) + (phi2[DIR_PPM] - phi2[DIR_MMP]))) +
+                   WEIGTH[DIR_PP0] * (((phi2[DIR_P0P] - phi2[DIR_M0M]) + (phi2[DIR_P0M] - phi2[DIR_M0P])) + ((phi2[DIR_PM0] - phi2[DIR_MP0]) + (phi2[DIR_PP0] - phi2[DIR_MM0])))) +
+                  +WEIGTH[DIR_0P0] * (phi2[DIR_P00] - phi2[DIR_M00]));
+}
+
+real IBsharpInterfaceLBMKernel::gradX2_phi2()
+{
+    using namespace D3Q27System;
+    return 3.0 * ((WEIGTH[DIR_PPP] * (((phi2[DIR_PPP] - phi2[DIR_MMM]) - (phi2[DIR_PMM] - phi2[DIR_MPP])) + ((phi2[DIR_PPM] - phi2[DIR_MMP]) - (phi2[DIR_PMP] - phi2[DIR_MPM]))) +
+                   WEIGTH[DIR_PP0] * (((phi2[DIR_0PP] - phi2[DIR_0MM]) + (phi2[DIR_0PM] - phi2[DIR_0MP])) + ((phi2[DIR_PP0] - phi2[DIR_MM0]) - (phi2[DIR_PM0] - phi2[DIR_MP0])))) +
+                  +WEIGTH[DIR_0P0] * (phi2[DIR_0P0] - phi2[DIR_0M0]));
+}
+
+real IBsharpInterfaceLBMKernel::gradX3_phi2()
+{
+    using namespace D3Q27System;
+    return 3.0 * ((WEIGTH[DIR_PPP] * (((phi2[DIR_PPP] - phi2[DIR_MMM]) - (phi2[DIR_PMM] - phi2[DIR_MPP])) + ((phi2[DIR_PMP] - phi2[DIR_MPM]) - (phi2[DIR_PPM] - phi2[DIR_MMP]))) +
+                   WEIGTH[DIR_PP0] * (((phi2[DIR_P0P] - phi2[DIR_M0M]) - (phi2[DIR_P0M] - phi2[DIR_M0P])) + ((phi2[DIR_0MP] - phi2[DIR_0PM]) + (phi2[DIR_0PP] - phi2[DIR_0MM])))) +
+                  +WEIGTH[DIR_0P0] * (phi2[DIR_00P] - phi2[DIR_00M]));
+}
+
+real IBsharpInterfaceLBMKernel::nabla2_phi()
+{
+    using namespace D3Q27System;
+    real sum = 0.0;
+    sum += WEIGTH[DIR_PPP] * ((((phi[DIR_PPP] - phi[DIR_000]) + (phi[DIR_MMM] - phi[DIR_000])) + ((phi[DIR_MMP] - phi[DIR_000]) + (phi[DIR_PPM] - phi[DIR_000]))) + (((phi[DIR_MPP] - phi[DIR_000]) + (phi[DIR_PMM] - phi[DIR_000])) + ((phi[DIR_PMP] - phi[DIR_000]) + (phi[DIR_MPM] - phi[DIR_000]))));
+    sum += WEIGTH[DIR_0PP] * ((((phi[DIR_0PP] - phi[DIR_000]) + (phi[DIR_0MM] - phi[DIR_000])) + ((phi[DIR_0MP] - phi[DIR_000]) + (phi[DIR_0PM] - phi[DIR_000]))) + (((phi[DIR_P0P] - phi[DIR_000]) + (phi[DIR_M0M] - phi[DIR_000])) + ((phi[DIR_M0P] - phi[DIR_000]) + (phi[DIR_P0M] - phi[DIR_000]))) +
+                              (((phi[DIR_PP0] - phi[DIR_000]) + (phi[DIR_MM0] - phi[DIR_000])) + ((phi[DIR_MP0] - phi[DIR_000]) + (phi[DIR_PM0] - phi[DIR_000]))));
+    sum += WEIGTH[DIR_00P] * (((phi[DIR_00P] - phi[DIR_000]) + (phi[DIR_00M] - phi[DIR_000])) + ((phi[DIR_0P0] - phi[DIR_000]) + (phi[DIR_0M0] - phi[DIR_000])) + ((phi[DIR_P00] - phi[DIR_000]) + (phi[DIR_M00] - phi[DIR_000])));
+
+    return 6.0 * sum;
+}
+
+real IBsharpInterfaceLBMKernel::computeCurvature_phi()
+{
+    using namespace D3Q27System;
+    using namespace UbMath;
+
+    real phiX = gradX1_phi();
+    real phiY = gradX2_phi();
+    real phiZ = gradX3_phi();
+    real phiXX =
+        c4o9 * (phi[DIR_P00] - c2o1 * phi[DIR_000] + phi[DIR_M00]) + (c1o9 * (((phi[DIR_PP0] - c2o1 * phi[DIR_0P0] + phi[DIR_MP0]) + (phi[DIR_PM0] - c2o1 * phi[DIR_0M0] + phi[DIR_MM0])) + ((phi[DIR_P0P] - c2o1 * phi[DIR_00P] + phi[DIR_M0P]) + (phi[DIR_P0M] - c2o1 * phi[DIR_00M] + phi[DIR_M0M]))) +
+                                                                      c1o36 * (((phi[DIR_PPP] - c2o1 * phi[DIR_0PP] + phi[DIR_MPP]) + (phi[DIR_PMP] - c2o1 * phi[DIR_0MP] + phi[DIR_MMP])) + ((phi[DIR_PPM] - c2o1 * phi[DIR_0PM] + phi[DIR_MPM]) + (phi[DIR_PMM] - c2o1 * phi[DIR_0MM] + phi[DIR_MMM]))));
+    real phiYY =
+        c4o9 * (phi[DIR_0P0] - c2o1 * phi[DIR_000] + phi[DIR_0M0]) + (c1o9 * (((phi[DIR_PP0] - c2o1 * phi[DIR_P00] + phi[DIR_PM0]) + (phi[DIR_MP0] - c2o1 * phi[DIR_M00] + phi[DIR_MM0])) + ((phi[DIR_0PP] - c2o1 * phi[DIR_00P] + phi[DIR_0MP]) + (phi[DIR_0PM] - c2o1 * phi[DIR_00M] + phi[DIR_0MM]))) +
+                                                                      c1o36 * (((phi[DIR_PPP] - c2o1 * phi[DIR_P0P] + phi[DIR_PMP]) + (phi[DIR_MPM] - c2o1 * phi[DIR_M0M] + phi[DIR_MMM])) + ((phi[DIR_MPP] - c2o1 * phi[DIR_M0P] + phi[DIR_MMP]) + (phi[DIR_PPM] - c2o1 * phi[DIR_P0M] + phi[DIR_PMM]))));
+    real phiZZ =
+        c4o9 * (phi[DIR_00P] - c2o1 * phi[DIR_000] + phi[DIR_00M]) + (c1o9 * (((phi[DIR_M0P] - c2o1 * phi[DIR_M00] + phi[DIR_M0M]) + (phi[DIR_P0P] - c2o1 * phi[DIR_P00] + phi[DIR_P0M])) + ((phi[DIR_0MP] - c2o1 * phi[DIR_0M0] + phi[DIR_0MM]) + (phi[DIR_0PP] - c2o1 * phi[DIR_0P0] + phi[DIR_0PM]))) +
+                                                                      c1o36 * (((phi[DIR_MPP] - c2o1 * phi[DIR_MP0] + phi[DIR_MPM]) + (phi[DIR_PMP] - c2o1 * phi[DIR_PM0] + phi[DIR_PMM])) + ((phi[DIR_MMP] - c2o1 * phi[DIR_MM0] + phi[DIR_MMM]) + (phi[DIR_PPP] - c2o1 * phi[DIR_PP0] + phi[DIR_PPM]))));
+    real phiXY = c1o4 * (c2o3 * (phi[DIR_MM0] - phi[DIR_PM0] + phi[DIR_PP0] - phi[DIR_MP0]) + c1o6 * ((phi[DIR_MMP] - phi[DIR_PMP] + phi[DIR_PPP] - phi[DIR_MPP]) + (phi[DIR_MMM] - phi[DIR_PMM] + phi[DIR_PPM] - phi[DIR_MPM])));
+    real phiXZ = c1o4 * (c2o3 * (phi[DIR_M0M] - phi[DIR_P0M] + phi[DIR_P0P] - phi[DIR_M0P]) + c1o6 * ((phi[DIR_MPM] - phi[DIR_PPM] + phi[DIR_PPP] - phi[DIR_MPP]) + (phi[DIR_MMM] - phi[DIR_PMM] + phi[DIR_PMP] - phi[DIR_MMP])));
+    real phiYZ = c1o4 * (c2o3 * (phi[DIR_0MM] - phi[DIR_0MP] + phi[DIR_0PP] - phi[DIR_0PM]) + c1o6 * ((phi[DIR_MMM] - phi[DIR_MMP] + phi[DIR_MPP] - phi[DIR_MPM]) + (phi[DIR_PMM] - phi[DIR_PMP] + phi[DIR_PPP] - phi[DIR_PPM])));
+
+    // non isotropic FD (to be improved):
+    // real phiX = (phi[DIR_P00] - phi[DIR_M00]) * c1o2; //gradX1_phi();
+    // real phiY = (phi[DIR_0P0] - phi[DIR_0M0]) * c1o2; //gradX2_phi();
+    // real phiZ = (phi[DIR_00P] - phi[DIR_00M]) * c1o2; //gradX3_phi();
+
+    // real phiXX = phi[DIR_P00] - c2o1 * phi[DIR_000] + phi[DIR_M00];
+    // real phiYY = phi[DIR_0P0] - c2o1 * phi[DIR_000] + phi[DIR_0M0];
+    // real phiZZ =( phi[DIR_00P] - c2o1 * phi[DIR_000] + phi[DIR_00M]);
+    // real phiXY = c1o4 * (phi[DIR_MM0] - phi[DIR_PM0] + phi[DIR_PP0] - phi[DIR_MP0]);
+    // real phiXZ = c1o4 * (phi[DIR_M0M] - phi[DIR_P0M] + phi[DIR_P0P] - phi[DIR_M0P]);
+    // real phiYZ = c1o4 * (phi[DIR_0MM] - phi[DIR_0MP] + phi[DIR_0PP] - phi[DIR_0PM]);
+    // real back= (c2o1 * (phiX * phiY * phiXY + phiX * phiZ * phiXZ + phiY * phiZ * phiYZ) - phiXX * (phiY * phiY + phiZ * phiZ) - phiYY * (phiX * phiX + phiZ * phiZ) - phiZZ * (phiX * phiX + phiY * phiY)) / (c2o1 * pow(phiX * phiX + phiY * phiY + phiZ * phiZ, c3o2));
+    return (c2o1 * (phiX * phiY * phiXY + phiX * phiZ * phiXZ + phiY * phiZ * phiYZ) - phiXX * (phiY * phiY + phiZ * phiZ) - phiYY * (phiX * phiX + phiZ * phiZ) - phiZZ * (phiX * phiX + phiY * phiY)) / (c2o1 * pow(phiX * phiX + phiY * phiY + phiZ * phiZ, c3o2));
+}
+
+void IBsharpInterfaceLBMKernel::computePhasefield()
+{
+    using namespace D3Q27System;
+    SPtr<DistributionArray3D> distributionsH = dataSet->getHdistributions();
+
+    int minX1 = ghostLayerWidth;
+    int minX2 = ghostLayerWidth;
+    int minX3 = ghostLayerWidth;
+    int maxX1 = (int)distributionsH->getNX1() - ghostLayerWidth;
+    int maxX2 = (int)distributionsH->getNX2() - ghostLayerWidth;
+    int maxX3 = (int)distributionsH->getNX3() - ghostLayerWidth;
+
+    //------------- Computing the phase-field ------------------
+    for (int x3 = minX3; x3 < maxX3; x3++) {
+        for (int x2 = minX2; x2 < maxX2; x2++) {
+            for (int x1 = minX1; x1 < maxX1; x1++) {
+                // if(!bcArray->isSolid(x1,x2,x3) && !bcArray->isUndefined(x1,x2,x3))
+                {
+                    int x1p = x1 + 1;
+                    int x2p = x2 + 1;
+                    int x3p = x3 + 1;
+
+                    h[DIR_P00] = (*this->localDistributionsH1)(D3Q27System::ET_E, x1, x2, x3);
+                    h[DIR_0P0] = (*this->localDistributionsH1)(D3Q27System::ET_N, x1, x2, x3);
+                    h[DIR_00P] = (*this->localDistributionsH1)(D3Q27System::ET_T, x1, x2, x3);
+                    h[DIR_PP0] = (*this->localDistributionsH1)(D3Q27System::ET_NE, x1, x2, x3);
+                    h[DIR_MP0] = (*this->localDistributionsH1)(D3Q27System::ET_NW, x1p, x2, x3);
+                    h[DIR_P0P] = (*this->localDistributionsH1)(D3Q27System::ET_TE, x1, x2, x3);
+                    h[DIR_M0P] = (*this->localDistributionsH1)(D3Q27System::ET_TW, x1p, x2, x3);
+                    h[DIR_0PP] = (*this->localDistributionsH1)(D3Q27System::ET_TN, x1, x2, x3);
+                    h[DIR_0MP] = (*this->localDistributionsH1)(D3Q27System::ET_TS, x1, x2p, x3);
+                    h[DIR_PPP] = (*this->localDistributionsH1)(D3Q27System::ET_TNE, x1, x2, x3);
+                    h[DIR_MPP] = (*this->localDistributionsH1)(D3Q27System::ET_TNW, x1p, x2, x3);
+                    h[DIR_PMP] = (*this->localDistributionsH1)(D3Q27System::ET_TSE, x1, x2p, x3);
+                    h[DIR_MMP] = (*this->localDistributionsH1)(D3Q27System::ET_TSW, x1p, x2p, x3);
+
+                    h[DIR_M00] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_W, x1p, x2, x3);
+                    h[DIR_0M0] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_S, x1, x2p, x3);
+                    h[DIR_00M] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_B, x1, x2, x3p);
+                    h[DIR_MM0] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_SW, x1p, x2p, x3);
+                    h[DIR_PM0] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_SE, x1, x2p, x3);
+                    h[DIR_M0M] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BW, x1p, x2, x3p);
+                    h[DIR_P0M] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BE, x1, x2, x3p);
+                    h[DIR_0MM] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BS, x1, x2p, x3p);
+                    h[DIR_0PM] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BN, x1, x2, x3p);
+                    h[DIR_MMM] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BSW, x1p, x2p, x3p);
+                    h[DIR_PMM] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BSE, x1, x2p, x3p);
+                    h[DIR_MPM] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BNW, x1p, x2, x3p);
+                    h[DIR_PPM] = (*this->nonLocalDistributionsH1)(D3Q27System::ET_BNE, x1, x2, x3p);
+
+                    h[DIR_000] = (*this->restDistributionsH1)(x1, x2, x3);
+                }
+            }
+        }
+    }
+}
+
+void IBsharpInterfaceLBMKernel::findNeighbors(CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr ph, int x1, int x2, int x3)
+{
+    using namespace D3Q27System;
+
+    SPtr<BCArray3D> bcArray = this->getBCSet()->getBCArray();
+
+    phi[DIR_000] = (*ph)(x1, x2, x3);
+
+    for (int k = FSTARTDIR; k <= FENDDIR; k++) {
+
+        if (!bcArray->isSolid(x1 + DX1[k], x2 + DX2[k], x3 + DX3[k])) {
+            phi[k] = (*ph)(x1 + DX1[k], x2 + DX2[k], x3 + DX3[k]);
+        } else {
+            phi[k] = (*ph)(x1, x2, x3); // neutral wetting
+                                        // phi[k] = 0.0;//unwetting
+        }
+    }
+}
+
+void IBsharpInterfaceLBMKernel::findNeighbors2(CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr ph, int x1, int x2, int x3)
+{
+    using namespace D3Q27System;
+
+    SPtr<BCArray3D> bcArray = this->getBCSet()->getBCArray();
+
+    phi2[DIR_000] = (*ph)(x1, x2, x3);
+
+    for (int k = FSTARTDIR; k <= FENDDIR; k++) {
+
+        if (!bcArray->isSolid(x1 + DX1[k], x2 + DX2[k], x3 + DX3[k])) {
+            phi2[k] = (*ph)(x1 + DX1[k], x2 + DX2[k], x3 + DX3[k]);
+        } else {
+            phi2[k] = 0.05;
+        }
+    }
+}
+
+void IBsharpInterfaceLBMKernel::swapDistributions()
+{
+    LBMKernel::swapDistributions();
+    dataSet->getHdistributions()->swap();
+}
+
+void IBsharpInterfaceLBMKernel::initForcing()
+{
+    muForcingX1.DefineVar("x1", &muX1);
+    muForcingX1.DefineVar("x2", &muX2);
+    muForcingX1.DefineVar("x3", &muX3);
+    muForcingX2.DefineVar("x1", &muX1);
+    muForcingX2.DefineVar("x2", &muX2);
+    muForcingX2.DefineVar("x3", &muX3);
+    muForcingX3.DefineVar("x1", &muX1);
+    muForcingX3.DefineVar("x2", &muX2);
+    muForcingX3.DefineVar("x3", &muX3);
+
+    muDeltaT = deltaT;
+
+    muForcingX1.DefineVar("dt", &muDeltaT);
+    muForcingX2.DefineVar("dt", &muDeltaT);
+    muForcingX3.DefineVar("dt", &muDeltaT);
+
+    muNu = (1.0 / 3.0) * (1.0 / collFactor - 1.0 / 2.0);
+
+    muForcingX1.DefineVar("nu", &muNu);
+    muForcingX2.DefineVar("nu", &muNu);
+    muForcingX3.DefineVar("nu", &muNu);
+
+    muForcingX1.DefineVar("rho", &muRho);
+    muForcingX2.DefineVar("rho", &muRho);
+    muForcingX3.DefineVar("rho", &muRho);
+}
diff --git a/src/cpu/LiggghtsCoupling/LBM/IBsharpInterfaceLBMKernel.h b/src/cpu/LiggghtsCoupling/LBM/IBsharpInterfaceLBMKernel.h
new file mode 100644
index 0000000000000000000000000000000000000000..a24131488a642a0a44712dd73fe4188cfeafaab2
--- /dev/null
+++ b/src/cpu/LiggghtsCoupling/LBM/IBsharpInterfaceLBMKernel.h
@@ -0,0 +1,133 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  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 IBsharpInterfaceLBMKernel.h
+//! \ingroup LBMKernel
+//! \author M. Geier, K. Kutscher, Hesameddin Safari
+//=======================================================================================
+
+#ifndef IBsharpInterfaceLBMKernel_H
+#define IBsharpInterfaceLBMKernel_H
+
+#include "BCSet.h"
+#include "D3Q27System.h"
+#include "LiggghtsCouplingLBMKernel.h"
+#include "basics/container/CbArray3D.h"
+#include "basics/container/CbArray4D.h"
+#include "basics/utilities/UbTiming.h"
+#include "IBdynamicsParticleData.h"
+
+//! \brief  Multiphase Cascaded Cumulant LBM kernel.
+//! \details CFD solver that use Cascaded Cumulant Lattice Boltzmann method for D3Q27 model
+//! \author  M. Geier, K. Kutscher, Hesameddin Safari
+class IBsharpInterfaceLBMKernel : public LiggghtsCouplingLBMKernel
+{
+public:
+    IBsharpInterfaceLBMKernel();
+    virtual ~IBsharpInterfaceLBMKernel(void) = default;
+    void calculate(int step) override;
+    SPtr<LBMKernel> clone() override;
+
+    /// refactor
+    // CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr pressure;
+
+    double getCalculationTime() override
+    {
+        return .0;
+    }
+
+protected:
+    virtual void initDataSet();
+    void swapDistributions() override;
+
+    void initForcing();
+
+    void forwardInverseChimeraWithKincompressible(real &mfa, real &mfb, real &mfc, real vv, real v2, real Kinverse, real K, real oneMinusRho);
+    void backwardInverseChimeraWithKincompressible(real &mfa, real &mfb, real &mfc, real vv, real v2, real Kinverse, real K, real oneMinusRho);
+    void forwardChimera(real &mfa, real &mfb, real &mfc, real vv, real v2);
+    void backwardChimera(real &mfa, real &mfb, real &mfc, real vv, real v2);
+
+    real f1[D3Q27System::ENDF + 1];
+
+    CbArray4D<real, IndexerX4X3X2X1>::CbArray4DPtr localDistributionsF;
+    CbArray4D<real, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributionsF;
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr restDistributionsF;
+
+    CbArray4D<real, IndexerX4X3X2X1>::CbArray4DPtr localDistributionsH1;
+    CbArray4D<real, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributionsH1;
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr restDistributionsH1;
+
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr pressureOld;
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr p1Old;
+
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr phaseField;
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr phaseFieldOld;
+    // CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr divU;
+
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr rhoNode;
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr vxNode;
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr vyNode;
+    CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr vzNode;
+
+    real h[D3Q27System::ENDF + 1];
+    // real h2[D3Q27System::ENDF + 1];
+    // real g  [D3Q27System::ENDF+1];
+    real phi[D3Q27System::ENDF + 1];
+    real phi2[D3Q27System::ENDF + 1];
+    // real pr1[D3Q27System::ENDF+1];
+    real phi_cutoff[D3Q27System::ENDF + 1];
+
+    real gradX1_phi();
+    real gradX2_phi();
+    real gradX3_phi();
+    real gradX1_rhoInv(real rhoL, real rhoDIV);
+    real gradX2_rhoInv(real rhoL, real rhoDIV);
+    real gradX3_rhoInv(real rhoL, real rhoDIV);
+    real gradX1_phi2();
+    real gradX2_phi2();
+    real gradX3_phi2();
+    void computePhasefield();
+    void findNeighbors(CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr ph /*Phase-Field*/, int x1, int x2, int x3);
+    void findNeighbors2(CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr ph, int x1, int x2, int x3);
+
+    real nabla2_phi();
+
+    real computeCurvature_phi();
+
+    mu::value_type muX1, muX2, muX3;
+    mu::value_type muDeltaT;
+    mu::value_type muNu;
+    mu::value_type muRho;
+    mu::value_type muPhi;
+    real forcingX1;
+    real forcingX2;
+    real forcingX3;
+
+};
+
+#endif
diff --git a/src/cpu/LiggghtsCoupling/LBM/LiggghtsCouplingLBMKernel.cpp b/src/cpu/LiggghtsCoupling/LBM/LiggghtsCouplingLBMKernel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ff7a3bf1b19d5efd626f638d47dc05727fc2bc89
--- /dev/null
+++ b/src/cpu/LiggghtsCoupling/LBM/LiggghtsCouplingLBMKernel.cpp
@@ -0,0 +1,92 @@
+#include "LiggghtsCouplingLBMKernel.h"
+#include "D3Q27System.h"
+
+//void LiggghtsCouplingLBMKernel::collisionOperator(int x1, int x2, int x3, real collFactorM, real fPre[])
+//{
+//    //if ((*particleData)(x1, x2, x3)->solidFraction >= SOLFRAC_MIN) {
+//        LBMReal f[D3Q27System::ENDF + 1];
+//        LBMReal fEq[D3Q27System::ENDF + 1];
+//        LBMReal fEqSolid[D3Q27System::ENDF + 1];
+//        LBMReal vx1, vx2, vx3, drho;
+//        D3Q27System::calcIncompMacroscopicValues(f, drho, vx1, vx2, vx3);
+//        D3Q27System::calcIncompFeq(fEq, drho, vx1, vx2, vx3);
+//
+//        std::array<double, 3> uPart;
+//        uPart[0] = (*particleData)(x1, x2, x3)->uPart[0];
+//        uPart[1] = (*particleData)(x1, x2, x3)->uPart[1];
+//        uPart[2] = (*particleData)(x1, x2, x3)->uPart[2];
+//
+//        D3Q27System::calcIncompFeq(fEqSolid, drho, uPart[0], uPart[1], uPart[2]);
+//        real rhoPhaseField = (phi[DIR_000] > c1o2) ? c1o1 : c1o1 / densityRatio;
+//        if ((*particleData)(x1, x2, x3)->solidFraction > SOLFRAC_MAX) {
+//            double const bb0 = fEq[vf::lbm::dir::DIR_000] - fEqSolid[vf::lbm::dir::DIR_000];
+//            f[vf::lbm::dir::DIR_000] = fPre[vf::lbm::dir::DIR_000] + bb0;
+//            for (int iPop = D3Q27System::FSTARTDIR; iPop <= D3Q27System::FENDDIR; iPop++) {
+//                const int iOpp = D3Q27System::INVDIR[iPop];
+//                double const bb = ((fPre[iOpp] - fEq[iOpp]) - (fPre[iPop] - fEqSolid[iPop]));
+//                double const bbOpp = ((fPre[iPop] - fEq[iPop]) - (fPre[iOpp] - fEqSolid[iOpp]));
+//
+//                f[iPop] = fPre[iPop] + bb;
+//                f[iOpp] = fPre[iOpp] + bbOpp;
+//
+//                (*particleData)(x1, x2, x3)->hydrodynamicForce[0] -= D3Q27System::DX1[iPop] * (bb - bbOpp) * rhoPhaseField;
+//                (*particleData)(x1, x2, x3)->hydrodynamicForce[1] -= D3Q27System::DX2[iPop] * (bb - bbOpp) * rhoPhaseField;
+//                (*particleData)(x1, x2, x3)->hydrodynamicForce[2] -= D3Q27System::DX3[iPop] * (bb - bbOpp) * rhoPhaseField;
+//            }
+//        } else { /* particleData.solidFraction < SOLFRAC_MAX */
+//                 // #ifdef LBDEM_USE_WEIGHING
+//            double const ooo = 1. / collFactorM - 0.5;
+//            double const B = (*particleData)(x1, x2, x3)->solidFraction * ooo / ((1. - (*particleData)(x1, x2, x3)->solidFraction) + ooo);
+//            // #else
+//            //                         T const B = particleData.solidFraction;
+//            // #endif
+//            double const oneMinB = 1. - B;
+//
+//            double const bb0 = fEq[vf::lbm::dir::DIR_000] - fEqSolid[vf::lbm::dir::DIR_000];
+//            f[vf::lbm::dir::DIR_000] = fPre[vf::lbm::dir::DIR_000] + oneMinB * (f[vf::lbm::dir::DIR_000] - fPre[vf::lbm::dir::DIR_000]) + B * bb0;
+//
+//            for (int iPop = D3Q27System::FSTARTDIR; iPop <= D3Q27System::FENDDIR; iPop++) {
+//                int const iOpp = D3Q27System::INVDIR[iPop];
+//                double const bb = B * ((fPre[iOpp] - fEq[iOpp]) - (fPre[iPop] - fEqSolid[iPop]));
+//                double const bbOpp = B * ((fPre[iPop] - fEq[iPop]) - (fPre[iOpp] - fEqSolid[iOpp]));
+//
+//                f[iPop] = fPre[iPop] + oneMinB * (f[iPop] - fPre[iPop]) + bb;
+//                f[iOpp] = fPre[iOpp] + oneMinB * (f[iOpp] - fPre[iOpp]) + bbOpp;
+//
+//                (*particleData)(x1, x2, x3)->hydrodynamicForce[0] -= D3Q27System::DX1[iPop] * (bb - bbOpp) * rhoPhaseField;
+//                (*particleData)(x1, x2, x3)->hydrodynamicForce[1] -= D3Q27System::DX2[iPop] * (bb - bbOpp) * rhoPhaseField;
+//                (*particleData)(x1, x2, x3)->hydrodynamicForce[2] -= D3Q27System::DX3[iPop] * (bb - bbOpp) * rhoPhaseField;
+//            }
+//        } /* if solidFraction > SOLFRAC_MAX */
+//
+//    //    (*this->restDistributionsF)(x1, x2, x3) = f[vf::lbm::dir::DIR_000];
+//
+//    //    (*this->localDistributionsF)(D3Q27System::ET_E, x1, x2, x3) = f[vf::lbm::dir::DIR_M00];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_N, x1, x2, x3) = f[vf::lbm::dir::DIR_0M0];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_T, x1, x2, x3) = f[vf::lbm::dir::DIR_00M];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_NE, x1, x2, x3) = f[vf::lbm::dir::DIR_MM0];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_NW, x1p, x2, x3) = f[vf::lbm::dir::DIR_PM0];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_TE, x1, x2, x3) = f[vf::lbm::dir::DIR_M0M];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_TW, x1p, x2, x3) = f[vf::lbm::dir::DIR_P0M];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_TN, x1, x2, x3) = f[vf::lbm::dir::DIR_0MM];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_TS, x1, x2p, x3) = f[vf::lbm::dir::DIR_0PM];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_TNE, x1, x2, x3) = f[vf::lbm::dir::DIR_MMM];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_TNW, x1p, x2, x3) = f[vf::lbm::dir::DIR_PMM];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_TSE, x1, x2p, x3) = f[vf::lbm::dir::DIR_MPM];
+//    //    (*this->localDistributionsF)(D3Q27System::ET_TSW, x1p, x2p, x3) = f[vf::lbm::dir::DIR_PPM];
+//
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_W, x1p, x2, x3) = f[vf::lbm::dir::DIR_P00];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_S, x1, x2p, x3) = f[vf::lbm::dir::DIR_0P0];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_B, x1, x2, x3p) = f[vf::lbm::dir::DIR_00P];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_SW, x1p, x2p, x3) = f[vf::lbm::dir::DIR_PP0];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_SE, x1, x2p, x3) = f[vf::lbm::dir::DIR_MP0];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_BW, x1p, x2, x3p) = f[vf::lbm::dir::DIR_P0P];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_BE, x1, x2, x3p) = f[vf::lbm::dir::DIR_M0P];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_BS, x1, x2p, x3p) = f[vf::lbm::dir::DIR_0PP];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_BN, x1, x2, x3p) = f[vf::lbm::dir::DIR_0MP];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_BSW, x1p, x2p, x3p) = f[vf::lbm::dir::DIR_PPP];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_BSE, x1, x2p, x3p) = f[vf::lbm::dir::DIR_MPP];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_BNW, x1p, x2, x3p) = f[vf::lbm::dir::DIR_PMP];
+//    //    (*this->nonLocalDistributionsF)(D3Q27System::ET_BNE, x1, x2, x3p) = f[vf::lbm::dir::DIR_MMP];
+//    //}
+//}
\ No newline at end of file
diff --git a/src/cpu/LiggghtsCoupling/LBM/LiggghtsCouplingLBMKernel.h b/src/cpu/LiggghtsCoupling/LBM/LiggghtsCouplingLBMKernel.h
new file mode 100644
index 0000000000000000000000000000000000000000..86ac895486d357e9facc30c210b325af527dfbf2
--- /dev/null
+++ b/src/cpu/LiggghtsCoupling/LBM/LiggghtsCouplingLBMKernel.h
@@ -0,0 +1,66 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  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 LiggghtsCouplingLBMKernel.h
+//! \ingroup LBM
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef LiggghtsCouplingLBMKernel_h
+#define LiggghtsCouplingLBMKernel_h
+
+#include "LBMKernel.h"
+#include "IBdynamicsParticleData.h"
+#include "basics/container/CbArray3D.h"
+#include "basics/container/CbArray4D.h"
+
+class LiggghtsCouplingLBMKernel : public LBMKernel
+{
+public:
+    virtual ~LiggghtsCouplingLBMKernel() = default;
+
+    CbArray3D<SPtr<IBdynamicsParticleData>, IndexerX3X2X1>::CbArray3DPtr getParticleData()
+    {
+        return particleData;
+    };
+    void setParticleData(CbArray3D<SPtr<IBdynamicsParticleData>, IndexerX3X2X1>::CbArray3DPtr particleData)
+    {
+        this->particleData = particleData;
+    };
+
+    
+ protected:
+    //void collisionOperator();
+    CbArray3D<SPtr<IBdynamicsParticleData>, IndexerX3X2X1>::CbArray3DPtr particleData;
+
+    //CbArray4D<real, IndexerX4X3X2X1>::CbArray4DPtr localDistributionsF;
+    //CbArray4D<real, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributionsF;
+    //CbArray3D<real, IndexerX3X2X1>::CbArray3DPtr restDistributionsF;
+};
+
+#endif
\ No newline at end of file
diff --git a/src/cpu/LiggghtsCoupling/LiggghtsCoupling.h b/src/cpu/LiggghtsCoupling/LiggghtsCoupling.h
index 88e5be001b5f71f97b4369ab3795ee5e3e972210..42b127f730e1c6ba58d9da93fe7653e5f9f7407c 100644
--- a/src/cpu/LiggghtsCoupling/LiggghtsCoupling.h
+++ b/src/cpu/LiggghtsCoupling/LiggghtsCoupling.h
@@ -26,13 +26,18 @@
 //  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 MultiphasePressureBCStrategy.h
-//! \ingroup BoundarConditions
-//! \author Hesameddin Safari
+//! \file LiggghtsCoupling.h
+//! \ingroup LiggghtsCoupling
+//! \author Konstantin Kutscher
 //=======================================================================================
 
-#pragma once
+#ifndef LiggghtsCoupling_h
+#define LiggghtsCoupling_h
 
 #include "LiggghtsCoupling/3rdParty/LiggghtsCouplingWrapper.h"
 #include "LiggghtsCoupling/LBM/IBcumulantK17LBMKernel.h"
-#include "LiggghtsCoupling/SimulationObserver/LiggghtsCouplingSimulationObserver.h"
\ No newline at end of file
+#include "LiggghtsCoupling/LBM/IBsharpInterfaceLBMKernel.h"
+#include "LiggghtsCoupling/SimulationObserver/LiggghtsCouplingSimulationObserver.h"
+#include "LiggghtsCoupling/Parallel/LiggghtsPartitioningGridVisitor.h"
+
+#endif
\ No newline at end of file
diff --git a/src/cpu/LiggghtsCoupling/Parallel/LiggghtsPartitioningGridVisitor.cpp b/src/cpu/LiggghtsCoupling/Parallel/LiggghtsPartitioningGridVisitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..487077f080205cb33ca11748d1f611ca1f1a423d
--- /dev/null
+++ b/src/cpu/LiggghtsCoupling/Parallel/LiggghtsPartitioningGridVisitor.cpp
@@ -0,0 +1,82 @@
+#include "LiggghtsPartitioningGridVisitor.h"
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  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 LiggghtsPartitioningGridVisitor.cpp
+//! \ingroup LiggghtsCoupling
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#include <comm.h>
+#include "LiggghtsPartitioningGridVisitor.h"
+#include "VirtualFluidsCore/Simulation/Grid3D.h"
+#include "VirtualFluidsCore/Simulation/Block3D.h"
+
+LiggghtsPartitioningGridVisitor::LiggghtsPartitioningGridVisitor(int nx, int ny, int nz, LAMMPS_NS::LAMMPS *lmp) : nx(nx), ny(ny), nz(nz), lmp(*lmp)
+{
+ 
+}
+
+LiggghtsPartitioningGridVisitor::~LiggghtsPartitioningGridVisitor()
+{
+
+}
+
+void LiggghtsPartitioningGridVisitor::visit(SPtr<Grid3D> grid)
+{
+    npx = lmp.comm->procgrid[0];
+    npy = lmp.comm->procgrid[1];
+    npz = lmp.comm->procgrid[2];
+
+    for (int i = 0; i <= npx; i++)
+        xVal.push_back(round(lmp.comm->xsplit[i] * (double)nx));
+    for (int i = 0; i <= npy; i++)
+        yVal.push_back(round(lmp.comm->ysplit[i] * (double)ny));
+    for (int i = 0; i <= npz; i++)
+        zVal.push_back(round(lmp.comm->zsplit[i] * (double)nz));
+
+    UbTupleInt3 blockNX = grid->getBlockNX();
+
+    for (int iX = 0; iX < xVal.size() - 1; ++iX) {
+        for (int iY = 0; iY < yVal.size() - 1; ++iY) {
+            for (int iZ = 0; iZ < zVal.size() - 1; ++iZ) {
+
+                int rank = (int)lmp.comm->grid2proc[iX][iY][iZ];
+                int blockX1 = xVal[iX] / val<1>(blockNX);
+                int blockX2 = yVal[iY] / val<2>(blockNX);
+                int blockX3 = zVal[iZ] / val<3>(blockNX);
+                SPtr<Block3D> block = grid->getBlock(blockX1, blockX2, blockX3, 0);
+                block->setRank(rank);
+            }
+        }
+    }
+
+    xVal.clear();
+    yVal.clear();
+    zVal.clear();
+}
diff --git a/src/cpu/LiggghtsCoupling/Parallel/LiggghtsPartitioningGridVisitor.h b/src/cpu/LiggghtsCoupling/Parallel/LiggghtsPartitioningGridVisitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..6fb5560ad7a93ca13005a24fcf976d4019576dd1
--- /dev/null
+++ b/src/cpu/LiggghtsCoupling/Parallel/LiggghtsPartitioningGridVisitor.h
@@ -0,0 +1,59 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  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 LiggghtsPartitioningGridVisitor.h
+//! \ingroup LiggghtsCoupling
+//! \author Konstantin Kutscher
+//=======================================================================================
+#ifndef LiggghtsPartitioningGridVisitor_h
+#define LiggghtsPartitioningGridVisitor_h
+
+#include <lammps.h>
+#include <vector>
+#include "basics/PointerDefinitions.h"
+#include "VirtualFluidsCore/Visitors/Grid3DVisitor.h"
+
+class LiggghtsCouplingWrapper;
+class Grid3D;
+
+class LiggghtsPartitioningGridVisitor : public Grid3DVisitor
+{
+public:
+    LiggghtsPartitioningGridVisitor(int nx, int ny, int nz, LAMMPS_NS::LAMMPS *lmp);
+
+    ~LiggghtsPartitioningGridVisitor() override;
+
+    void visit(SPtr<Grid3D> grid) override;
+
+private:
+    int nx, ny, nz;
+    LAMMPS_NS::LAMMPS &lmp;
+    int npx{ 0 }, npy{ 0 }, npz{ 0 };
+    std::vector<int> xVal, yVal, zVal;
+};
+#endif
\ No newline at end of file
diff --git a/src/cpu/LiggghtsCoupling/SimulationObserver/LiggghtsCouplingSimulationObserver.cpp b/src/cpu/LiggghtsCoupling/SimulationObserver/LiggghtsCouplingSimulationObserver.cpp
index 7b7fafd8a653f9a33559d9f569c6add4fba929f9..651421bd11312fcfa99cd002c5ce2a4a4a44a63f 100644
--- a/src/cpu/LiggghtsCoupling/SimulationObserver/LiggghtsCouplingSimulationObserver.cpp
+++ b/src/cpu/LiggghtsCoupling/SimulationObserver/LiggghtsCouplingSimulationObserver.cpp
@@ -9,6 +9,7 @@
 #include "DistributionArray3D.h"
 #include "DataSet3D.h"
 #include "LiggghtsCoupling/LBM/IBcumulantK17LBMKernel.h"
+#include "LiggghtsCoupling/LBM/IBsharpInterfaceLBMKernel.h"
 #include "LBMUnitConverter.h"
 #include "fix_lb_coupling_onetoone.h"
 
@@ -27,8 +28,8 @@ LiggghtsCouplingSimulationObserver::~LiggghtsCouplingSimulationObserver()
 
 void LiggghtsCouplingSimulationObserver::update(double actualTimeStep)
 { 
-    if (comm->getProcessID() == 0)
-        std::cout << "LiggghtsCouplingSimulationObserver step: " << actualTimeStep << "\n";
+    //if (comm->getProcessID() == 0)
+    //    std::cout << "LiggghtsCouplingSimulationObserver step: " << actualTimeStep << "\n";
     
     //comm->barrier();
 
@@ -104,22 +105,44 @@ void LiggghtsCouplingSimulationObserver::setSingleSphere3D(double *x, double *v,
             SPtr<DistributionArray3D> distributions = kernel->getDataSet()->getFdistributions();
 
             CbArray3D<SPtr<IBdynamicsParticleData>, IndexerX3X2X1>::CbArray3DPtr particleData =
-                dynamicPointerCast<IBcumulantK17LBMKernel>(kernel)->getParticleData();
+                dynamicPointerCast<LiggghtsCouplingLBMKernel>(kernel)->getParticleData();
 
             if (!particleData)
                 continue;
 
-            int minX1 = 1;
-            int minX2 = 1;
-            int minX3 = 1;
+            int minX1b = 1;
+            int minX2b = 1;
+            int minX3b = 1;
 
-            int maxX1 = (int)(distributions->getNX1()) - 1;
-            int maxX2 = (int)(distributions->getNX2()) - 1;
-            int maxX3 = (int)(distributions->getNX3()) - 1;
+            int maxX1b = (int)(distributions->getNX1()) - 2;
+            int maxX2b = (int)(distributions->getNX2()) - 2;
+            int maxX3b = (int)(distributions->getNX3()) - 2;
 
-            for (int ix3 = minX3; ix3 < maxX3; ix3++) {
-                for (int ix2 = minX2; ix2 < maxX2; ix2++) {
-                    for (int ix1 = minX1; ix1 < maxX1; ix1++) {
+            real deltax = grid->getDeltaX(block);
+
+            UbTupleInt3 nodesMin = grid->getNodeIndexes(block, x[0] - r - deltax, x[1] - r - deltax, x[2] - r - deltax);
+            UbTupleInt3 nodesMax = grid->getNodeIndexes(block, x[0] + r + deltax, x[1] + r + deltax, x[2] + r + deltax);
+
+            int minX1 = (val<1>(nodesMin) < minX1b) ? minX1b : val<1>(nodesMin);
+            int minX2 = (val<2>(nodesMin) < minX2b) ? minX2b : val<2>(nodesMin);
+            int minX3 = (val<3>(nodesMin) < minX3b) ? minX3b : val<3>(nodesMin);
+
+            int maxX1 = (val<1>(nodesMax) > maxX1b) ? maxX1b : val<1>(nodesMax);
+            int maxX2 = (val<2>(nodesMax) > maxX2b) ? maxX2b : val<2>(nodesMax);
+            int maxX3 = (val<3>(nodesMax) > maxX3b) ? maxX3b : val<3>(nodesMax);
+
+            //int minX1 =  minX1b;
+            //int minX2 =  minX2b;
+            //int minX3 =  minX3b;
+
+            //int maxX1 =  maxX1b;
+            //int maxX2 =  maxX2b;
+            //int maxX3 =  maxX3b;
+
+
+            for (int ix3 = minX3; ix3 <= maxX3; ix3++) {
+                for (int ix2 = minX2; ix2 <= maxX2; ix2++) {
+                    for (int ix1 = minX1; ix1 <= maxX1; ix1++) {
 
                         //UbTupleInt3 blockNX = grid->getBlockNX();
 
@@ -334,7 +357,7 @@ void LiggghtsCouplingSimulationObserver::SumForceTorque3D(ParticleData::Particle
             SPtr<DistributionArray3D> distributions = kernel->getDataSet()->getFdistributions();
 
             CbArray3D<SPtr<IBdynamicsParticleData>, IndexerX3X2X1>::CbArray3DPtr particleData =
-                dynamicPointerCast<IBcumulantK17LBMKernel>(kernel)->getParticleData();
+                dynamicPointerCast<LiggghtsCouplingLBMKernel>(kernel)->getParticleData();
 
             if (!particleData)
                 continue;
@@ -358,6 +381,8 @@ void LiggghtsCouplingSimulationObserver::SumForceTorque3D(ParticleData::Particle
 
                         int const ind = wrapper.lmp->atom->map(id);
 
+                        if (ind < 0) continue; // no particle here
+
                         Vector3D worldCoordinates = grid->getNodeCoordinates(block, ix1, ix2, ix3);
 
                         double dx = (worldCoordinates[0] - x[ind][0]) * units->getFactorLentghWToLb();
diff --git a/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphasePressureBCStrategy.cpp b/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphasePressureBCStrategy.cpp
index d2bb9f083fd433d60e0d1f5054b2238e963d9efc..f85d3c6503fbe645ecef115351c6e8fd11c287d1 100644
--- a/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphasePressureBCStrategy.cpp
+++ b/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphasePressureBCStrategy.cpp
@@ -88,19 +88,6 @@ void MultiphasePressureBCStrategy::applyBC()
    calcMacrosFct(f, p1, vx1, vx2, vx3);
    p1 = 0.0;
 
-   int nx1 = x1;
-   int nx2 = x2;
-   int nx3 = x3;
-
-   //flag points in direction of fluid
-   if      (bcPtr->hasVelocityBoundaryFlag(DIR_P00)) { nx1 -= 1; }
-   else if (bcPtr->hasVelocityBoundaryFlag(DIR_M00)) { nx1 += 1; }
-   else if (bcPtr->hasVelocityBoundaryFlag(DIR_0P0)) { nx2 -= 1; }
-   else if (bcPtr->hasVelocityBoundaryFlag(DIR_0M0)) { nx2 += 1; }
-   else if (bcPtr->hasVelocityBoundaryFlag(DIR_00P)) { nx3 -= 1; }
-   else if (bcPtr->hasVelocityBoundaryFlag(DIR_00M)) { nx3 += 1; }
-   //else UB_THROW(UbException(UB_EXARGS, "Danger...no orthogonal BC-Flag on velocity boundary..."));
-   
    phiBC = bcPtr->getBoundaryPhaseField();
    LBMReal rhoBC = bcPtr->getBoundaryDensity();
    D3Q27System::calcIncompFeq(feq, rhoBC, vx1, vx2, vx3);
diff --git a/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphaseVelocityBC.h b/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphaseVelocityBC.h
index e01237cf96e14bffbbfeac43469d32c907d56dd7..8618d797245a641b8c6ce7fc30fee46a3bfeed22 100644
--- a/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphaseVelocityBC.h
+++ b/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphaseVelocityBC.h
@@ -79,8 +79,8 @@ class UbFileInput;
 //! \code{.cpp}
 //!    mu::Parser fct;
 //!    fct.SetExpr("max(vmax*(1.0-4.0*((x2-x2_vmax)^2+(x3-x3_vmax)^2)/H^2),0.0)"); //paraboloid (with vmax for
-//!    (0/x2_vmax/x3_vmax) fct.DefineConst("x2Vmax", 0.0            ); //x2-Pos für vmax fct.DefineConst("x3Vmax", 0.0
-//!    ); //x3-Pos für vmax fct.DefineConst("H"     , diameterOfPipe); fct.DefineConst("vmax"  , vmax           );
+//!    (0/x2_vmax/x3_vmax) fct.DefineConst("x2Vmax", 0.0            ); //x2-Pos for vmax fct.DefineConst("x3Vmax", 0.0
+//!    ); //x3-Pos for vmax fct.DefineConst("H"     , diameterOfPipe); fct.DefineConst("vmax"  , vmax           );
 //!    VelocityBC velBC(true, false ,false ,fct, 0, BCFunction::INFCONST);
 //! \endcode 
 
diff --git a/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphaseVelocityBCStrategy.cpp b/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphaseVelocityBCStrategy.cpp
index a9b8391a8296fbbaf2709bb36863880985790a45..a0b334d8ee7a88471ca3e5c640e04a914f4171bd 100644
--- a/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphaseVelocityBCStrategy.cpp
+++ b/src/cpu/MultiphaseFlow/BoundaryConditions/MultiphaseVelocityBCStrategy.cpp
@@ -95,19 +95,6 @@ void MultiphaseVelocityBCStrategy::applyBC()
 
    ///// added for phase field //////
 
-   int nx1 = x1;
-   int nx2 = x2;
-   int nx3 = x3;
-
-   //flag points in direction of fluid
-   if      (bcPtr->hasVelocityBoundaryFlag(DIR_P00)) { nx1 -= 1; }
-   else if (bcPtr->hasVelocityBoundaryFlag(DIR_M00)) { nx1 += 1; }
-   else if (bcPtr->hasVelocityBoundaryFlag(DIR_0P0)) { nx2 -= 1; }
-   else if (bcPtr->hasVelocityBoundaryFlag(DIR_0M0)) { nx2 += 1; }
-   else if (bcPtr->hasVelocityBoundaryFlag(DIR_00P)) { nx3 -= 1; }
-   else if (bcPtr->hasVelocityBoundaryFlag(DIR_00M)) { nx3 += 1; }
-   //else UB_THROW(UbException(UB_EXARGS, "Danger...no orthogonal BC-Flag on velocity boundary..."));
-   
    phiBC = bcPtr->getBoundaryPhaseField();
    
    D3Q27System::calcMultiphaseHeq(htemp, phiBC, vx1, vx2, vx3);
diff --git a/src/cpu/MultiphaseFlow/LBM/MultiphaseScaleDistributionLBMKernel.cpp b/src/cpu/MultiphaseFlow/LBM/MultiphaseScaleDistributionLBMKernel.cpp
index 169ea1593e9d966511f548671cec82c55d9e4da2..4a207ee2d370a3585b6e876f42872a4636fde376 100644
--- a/src/cpu/MultiphaseFlow/LBM/MultiphaseScaleDistributionLBMKernel.cpp
+++ b/src/cpu/MultiphaseFlow/LBM/MultiphaseScaleDistributionLBMKernel.cpp
@@ -905,16 +905,16 @@ void MultiphaseScaleDistributionLBMKernel::calculate(int step)
 
 								real sum2 = 1e-100;
 								real sumRho = 0;
-								real sumVx = 0;
-								real sumVy = 0;
-								real sumVz = 0;
+								// real sumVx = 0;
+								// real sumVy = 0;
+								// real sumVz = 0;
 								for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
 									if ((phi[fdir] > c1o2)) {
 
 										sumRho += WEIGTH[fdir] * (*rhoNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);// * tempRho;
-										sumVx += WEIGTH[fdir] * (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
-										sumVy += WEIGTH[fdir] * (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
-										sumVz += WEIGTH[fdir] * (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+										// sumVx += WEIGTH[fdir] * (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+										// sumVy += WEIGTH[fdir] * (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+										// sumVz += WEIGTH[fdir] * (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
 										sum2 += WEIGTH[fdir];
 									}
 								}
@@ -3813,12 +3813,12 @@ void MultiphaseScaleDistributionLBMKernel::calculate(int step)
 					real mxxMzz = mfcaa - mfaac;
 
 					///
-					real mmfcaa = c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz);
-					real mmfaca = c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz);
-					real mmfaac = c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz);
-					real mmfabb = mfabb;
-					real mmfbab = mfbab;
-					real mmfbba = mfbba;
+					// real mmfcaa = c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz);
+					// real mmfaca = c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz);
+					// real mmfaac = c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz);
+					// real mmfabb = mfabb;
+					// real mmfbab = mfbab;
+					// real mmfbba = mfbba;
 					///
 
 					real dxux = -c1o2 * collFactorM * (mxxMyy + mxxMzz) + c1o2 * OxxPyyPzz * (/*mfaaa*/ -mxxPyyPzz);// *0;
@@ -3950,12 +3950,12 @@ void MultiphaseScaleDistributionLBMKernel::calculate(int step)
 					real mxyyPxzz = mfbca + mfbac;
 					real mxyyMxzz = mfbca - mfbac;
 
-					 mmfcaa += c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz- mfaaa);
-					 mmfaca += c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz- mfaaa);
-					 mmfaac += c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz- mfaaa);
-					 mmfabb += mfabb;
-					 mmfbab += mfbab;
-					 mmfbba += mfbba;
+					//  mmfcaa += c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz- mfaaa);
+					//  mmfaca += c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz- mfaaa);
+					//  mmfaac += c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz- mfaaa);
+					//  mmfabb += mfabb;
+					//  mmfbab += mfbab;
+					//  mmfbba += mfbba;
 
 					//relax
 					wadjust = Oxyz + (1. - Oxyz) * fabs(mfbbb) / (fabs(mfbbb) + qudricLimit);
diff --git a/src/cpu/MultiphaseFlow/LBM/MultiphaseSharpInterfaceLBMKernel.cpp b/src/cpu/MultiphaseFlow/LBM/MultiphaseSharpInterfaceLBMKernel.cpp
index e77ee20435c901136121ced7490f0d2334513a6f..ed5b0c8d418db3a93b79aaae7ddc67ad11da3219 100644
--- a/src/cpu/MultiphaseFlow/LBM/MultiphaseSharpInterfaceLBMKernel.cpp
+++ b/src/cpu/MultiphaseFlow/LBM/MultiphaseSharpInterfaceLBMKernel.cpp
@@ -573,16 +573,16 @@ void MultiphaseSharpInterfaceLBMKernel::calculate(int step)
 
 								real sum2 = 1e-100;
 								real sumRho = 0;
-								real sumVx = 0;
-								real sumVy = 0;
-								real sumVz = 0;
+								// real sumVx = 0;
+								// real sumVy = 0;
+								// real sumVz = 0;
 								for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
 									if ((phi[fdir] > c1o2)) {
 
 										sumRho += WEIGTH[fdir] * (*rhoNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);// * tempRho;
-										sumVx += WEIGTH[fdir] * (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
-										sumVy += WEIGTH[fdir] * (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
-										sumVz += WEIGTH[fdir] * (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+										// sumVx += WEIGTH[fdir] * (*vxNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+										// sumVy += WEIGTH[fdir] * (*vyNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
+										// sumVz += WEIGTH[fdir] * (*vzNode)(x1 + D3Q27System::DX1[fdir], x2 + D3Q27System::DX2[fdir], x3 + D3Q27System::DX3[fdir]);
 										sum2 += WEIGTH[fdir];
 									}
 								}
@@ -944,12 +944,12 @@ void MultiphaseSharpInterfaceLBMKernel::calculate(int step)
 					real mxxMzz = mfcaa - mfaac;
 
 					///
-					real mmfcaa = c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz);
-					real mmfaca = c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz);
-					real mmfaac = c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz);
-					real mmfabb = mfabb;
-					real mmfbab = mfbab;
-					real mmfbba = mfbba;
+					// real mmfcaa = c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz);
+					// real mmfaca = c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz);
+					// real mmfaac = c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz);
+					// real mmfabb = mfabb;
+					// real mmfbab = mfbab;
+					// real mmfbba = mfbba;
 					///
 
 					real dxux =  -c1o2 * collFactorM * (mxxMyy + mxxMzz) + c1o2 * OxxPyyPzz * (/*mfaaa*/ -mxxPyyPzz)*0;
@@ -1024,12 +1024,12 @@ void MultiphaseSharpInterfaceLBMKernel::calculate(int step)
 					real mxyyPxzz = mfbca + mfbac;
 					real mxyyMxzz = mfbca - mfbac;
 
-					 mmfcaa += c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz- mfaaa);
-					 mmfaca += c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz- mfaaa);
-					 mmfaac += c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz- mfaaa);
-					 mmfabb += mfabb;
-					 mmfbab += mfbab;
-					 mmfbba += mfbba;
+					//  mmfcaa += c1o3 * (mxxMyy + mxxMzz + mxxPyyPzz- mfaaa);
+					//  mmfaca += c1o3 * (-2. * mxxMyy + mxxMzz + mxxPyyPzz- mfaaa);
+					//  mmfaac += c1o3 * (mxxMyy - 2. * mxxMzz + mxxPyyPzz- mfaaa);
+					//  mmfabb += mfabb;
+					//  mmfbab += mfbab;
+					//  mmfbba += mfbba;
 
 					//relax
 					wadjust = Oxyz + (1. - Oxyz) * fabs(mfbbb) / (fabs(mfbbb) + qudricLimit);
diff --git a/src/cpu/MultiphaseFlow/MultiphaseFlow.h b/src/cpu/MultiphaseFlow/MultiphaseFlow.h
index 469a819060f7a06ce6e914ace68cb44f6b83dca1..79c2ce8066414bc3a96457e143c9552d6907b663 100644
--- a/src/cpu/MultiphaseFlow/MultiphaseFlow.h
+++ b/src/cpu/MultiphaseFlow/MultiphaseFlow.h
@@ -1,4 +1,38 @@
-#pragma once
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  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 MultiphaseFlow.h
+//! \ingroup MultiphaseFlow
+//! \author Konstantin Kutscher
+//=======================================================================================
+
+#ifndef MultiphaseFlow_h
+#define MultiphaseFlow_h
 
 #include "MultiphaseFlow/BoundaryConditions/MultiphaseNoSlipBCStrategy.h"
 #include "MultiphaseFlow/BoundaryConditions/MultiphaseNonReflectingOutflowBCStrategy.h"
@@ -26,3 +60,4 @@
 #include "MultiphaseFlow/Visitors/MultiphaseInitDistributionsBlockVisitor.h"
 #include "MultiphaseFlow/Visitors/MultiphaseVelocityFormInitDistributionsBlockVisitor.h"
 
+#endif
\ No newline at end of file
diff --git a/src/cpu/NonNewtonianFluids/LBM/RheologyInterpolationProcessor.cpp b/src/cpu/NonNewtonianFluids/LBM/RheologyInterpolator.cpp
similarity index 94%
rename from src/cpu/NonNewtonianFluids/LBM/RheologyInterpolationProcessor.cpp
rename to src/cpu/NonNewtonianFluids/LBM/RheologyInterpolator.cpp
index 0a9c380dece3ba90f7d2d3d5d2a84ceadfcf4850..8da8886a42b0a9f9c784eca708618217f06c883a 100644
--- a/src/cpu/NonNewtonianFluids/LBM/RheologyInterpolationProcessor.cpp
+++ b/src/cpu/NonNewtonianFluids/LBM/RheologyInterpolator.cpp
@@ -26,51 +26,46 @@
 //  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 RheologyInterpolationProcessor.cpp
+//! \file RheologyInterpolator.cpp
 //! \ingroup LBM
 //! \author Konstantin Kutscher
 //=======================================================================================
 
-#include "RheologyInterpolationProcessor.h"
+#include "RheologyInterpolator.h"
 #include "D3Q27System.h"
 #include "Rheology.h"
 
 
-RheologyInterpolationProcessor::RheologyInterpolationProcessor()
+RheologyInterpolator::RheologyInterpolator()
    : omegaC(0.0), omegaF(0.0), omegaMin(0.0)
 {
 
 }
 //////////////////////////////////////////////////////////////////////////
-RheologyInterpolationProcessor::RheologyInterpolationProcessor(real omegaC, real omegaF, real omegaMin)
+RheologyInterpolator::RheologyInterpolator(real omegaC, real omegaF, real omegaMin)
    : omegaC(omegaC), omegaF(omegaF), omegaMin(omegaMin)
 {
 
 }
 //////////////////////////////////////////////////////////////////////////
-RheologyInterpolationProcessor::~RheologyInterpolationProcessor()
+InterpolationProcessorPtr RheologyInterpolator::clone()
 {
-
-}
-//////////////////////////////////////////////////////////////////////////
-InterpolationProcessorPtr RheologyInterpolationProcessor::clone()
-{
-   InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new RheologyInterpolationProcessor(this->omegaC, this->omegaF, this->omegaMin));
+   InterpolationProcessorPtr iproc = std::make_shared<RheologyInterpolator>(this->omegaC, this->omegaF, this->omegaMin);
    return iproc;
 }
 //////////////////////////////////////////////////////////////////////////
-void RheologyInterpolationProcessor::setOmegas( real omegaC, real omegaF )
+void RheologyInterpolator::setOmegas( real omegaC, real omegaF )
 {
    this->omegaC = omegaC;
    this->omegaF = omegaF;
 }
 //////////////////////////////////////////////////////////////////////////
-void RheologyInterpolationProcessor::setOmegaMin( real omegaMin )
+void RheologyInterpolator::setOmegaMin( real omegaMin )
 {
    this->omegaMin = omegaMin;
 }
 //////////////////////////////////////////////////////////////////////////
-void RheologyInterpolationProcessor::setOffsets(real xoff, real yoff, real zoff)
+void RheologyInterpolator::setOffsets(real xoff, real yoff, real zoff)
 {
    this->xoff = xoff;
    this->yoff = yoff;
@@ -80,7 +75,7 @@ void RheologyInterpolationProcessor::setOffsets(real xoff, real yoff, real zoff)
    this->zoff_sq = zoff * zoff;
 }
 //////////////////////////////////////////////////////////////////////////
-void RheologyInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff)
+void RheologyInterpolator::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff)
 {
     setOffsets(xoff, yoff, zoff);
     calcInterpolatedCoefficiets_intern(icellC, omegaC, 0.5, 0.25, -0.25, -0.25, -1, -1, -1);
@@ -101,14 +96,14 @@ void RheologyInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC,
     calcInterpolatedNode(icellF.TNE, /*omegaF,*/  0.25,  0.25,  0.25, calcPressTNE(),  1,  1,  1);
 }
 //////////////////////////////////////////////////////////////////////////
-void RheologyInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff)
+void RheologyInterpolator::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff)
 {
    setOffsets(xoff, yoff, zoff);
     calcInterpolatedCoefficiets_intern(icellF, omegaF, 2.0, 0, 0, 0, 0, 0, 0);
    calcInterpolatedNodeFC(icellC, omegaC);
 }
 //////////////////////////////////////////////////////////////////////////
-void RheologyInterpolationProcessor::calcMoments(const real* const f, real omegaInf, real& press, real& vx1, real& vx2, real& vx3, real& kxy, real& kyz, real& kxz, real& kxxMyy, real& kxxMzz)
+void RheologyInterpolator::calcMoments(const real* const f, real omegaInf, real& press, real& vx1, real& vx2, real& vx3, real& kxy, real& kyz, real& kxz, real& kxxMyy, real& kxxMzz)
 {
    using namespace D3Q27System;
    using namespace vf::lbm::dir;
@@ -129,7 +124,7 @@ void RheologyInterpolationProcessor::calcMoments(const real* const f, real omega
    kxxMzz = -3./2.*omega*((((f[DIR_MP0]+f[DIR_PM0])-(f[DIR_0MM]+f[DIR_0PP]))+((f[DIR_MM0]+f[DIR_PP0])-(f[DIR_0MP]+f[DIR_0PM])))+((f[DIR_M00]+f[DIR_P00])-(f[DIR_00M]+f[DIR_00P]))-(vx1*vx1-vx3*vx3));
 }
 //////////////////////////////////////////////////////////////////////////
-void RheologyInterpolationProcessor::calcInterpolatedCoefficiets_intern(const D3Q27ICell& icell,
+void RheologyInterpolator::calcInterpolatedCoefficiets_intern(const D3Q27ICell& icell,
                                                                           real omega,
                                                                           real eps_new,
                                                                           real x,
@@ -432,7 +427,7 @@ void RheologyInterpolationProcessor::calcInterpolatedCoefficiets_intern(const D3
    yz_TNW =   0.0625*eps_new *((                bxyz +     cxyz)/(72.*o));
 }
 //////////////////////////////////////////////////////////////////////////
-void RheologyInterpolationProcessor::calcInterpolatedNode(real* f, /*real omega,*/ real x, real y, real z, real press, real xs, real ys, real zs)
+void RheologyInterpolator::calcInterpolatedNode(real* f, /*real omega,*/ real x, real y, real z, real press, real xs, real ys, real zs)
 {
    using namespace D3Q27System;
    using namespace vf::lbm::dir;
@@ -475,7 +470,7 @@ void RheologyInterpolationProcessor::calcInterpolatedNode(real* f, /*real omega,
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SWB -0.25, -0.25, -0.25
-real RheologyInterpolationProcessor::calcPressBSW()
+real RheologyInterpolator::calcPressBSW()
 {
    return   press_SWT * (0.140625 + 0.1875 * xoff + 0.1875 * yoff - 0.5625 * zoff) +
       press_NWT * (0.046875 + 0.0625 * xoff - 0.1875 * yoff - 0.1875 * zoff) +
@@ -488,7 +483,7 @@ real RheologyInterpolationProcessor::calcPressBSW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SWT -0.25, -0.25, 0.25
-real RheologyInterpolationProcessor::calcPressTSW()
+real RheologyInterpolator::calcPressTSW()
 {
    return   press_SWT * (0.421875 + 0.5625 * xoff + 0.5625 * yoff - 0.5625 * zoff) +
       press_NWT * (0.140625 + 0.1875 * xoff - 0.5625 * yoff - 0.1875 * zoff) +
@@ -501,7 +496,7 @@ real RheologyInterpolationProcessor::calcPressTSW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SET 0.25, -0.25, 0.25
-real RheologyInterpolationProcessor::calcPressTSE()
+real RheologyInterpolator::calcPressTSE()
 {
    return   press_SET * (0.421875 - 0.5625 * xoff + 0.5625 * yoff - 0.5625 * zoff) +
       press_NET * (0.140625 - 0.1875 * xoff - 0.5625 * yoff - 0.1875 * zoff) +
@@ -514,7 +509,7 @@ real RheologyInterpolationProcessor::calcPressTSE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SEB 0.25, -0.25, -0.25
-real RheologyInterpolationProcessor::calcPressBSE()
+real RheologyInterpolator::calcPressBSE()
 {
    return   press_SET * (0.140625 - 0.1875 * xoff + 0.1875 * yoff - 0.5625 * zoff) +
       press_NET * (0.046875 - 0.0625 * xoff - 0.1875 * yoff - 0.1875 * zoff) +
@@ -527,7 +522,7 @@ real RheologyInterpolationProcessor::calcPressBSE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NWB -0.25, 0.25, -0.25
-real RheologyInterpolationProcessor::calcPressBNW()
+real RheologyInterpolator::calcPressBNW()
 {
    return   press_NWT * (0.140625 + 0.1875 * xoff - 0.1875 * yoff - 0.5625 * zoff) +
       press_NET * (0.046875 - 0.1875 * xoff - 0.0625 * yoff - 0.1875 * zoff) +
@@ -540,7 +535,7 @@ real RheologyInterpolationProcessor::calcPressBNW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NWT -0.25, 0.25, 0.25
-real RheologyInterpolationProcessor::calcPressTNW()
+real RheologyInterpolator::calcPressTNW()
 {
    return   press_NWT * (0.421875 + 0.5625 * xoff - 0.5625 * yoff - 0.5625 * zoff) +
       press_NET * (0.140625 - 0.5625 * xoff - 0.1875 * yoff - 0.1875 * zoff) +
@@ -553,7 +548,7 @@ real RheologyInterpolationProcessor::calcPressTNW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NET 0.25, 0.25, 0.25
-real RheologyInterpolationProcessor::calcPressTNE()
+real RheologyInterpolator::calcPressTNE()
 {
    return   press_NET * (0.421875 - 0.5625 * xoff - 0.5625 * yoff - 0.5625 * zoff) +
       press_NWT * (0.140625 + 0.5625 * xoff - 0.1875 * yoff - 0.1875 * zoff) +
@@ -566,7 +561,7 @@ real RheologyInterpolationProcessor::calcPressTNE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NEB 0.25, 0.25, -0.25
-real RheologyInterpolationProcessor::calcPressBNE()
+real RheologyInterpolator::calcPressBNE()
 {
    return   press_NET * (0.140625 - 0.1875 * xoff - 0.1875 * yoff - 0.5625 * zoff) +
       press_NWT * (0.046875 + 0.1875 * xoff - 0.0625 * yoff - 0.1875 * zoff) +
@@ -579,7 +574,7 @@ real RheologyInterpolationProcessor::calcPressBNE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position C 0.0, 0.0, 0.0
-void RheologyInterpolationProcessor::calcInterpolatedNodeFC(real* f, real omega)
+void RheologyInterpolator::calcInterpolatedNodeFC(real* f, real omega)
 {
    using namespace D3Q27System;
    using namespace vf::lbm::dir;
@@ -664,14 +659,14 @@ void RheologyInterpolationProcessor::calcInterpolatedNodeFC(real* f, real omega)
    f[DIR_000] = f_ZERO + feq[DIR_000];
 }
 //////////////////////////////////////////////////////////////////////////
-void RheologyInterpolationProcessor::calcInterpolatedVelocity(real x, real y, real z, real& vx1, real& vx2, real& vx3)
+void RheologyInterpolator::calcInterpolatedVelocity(real x, real y, real z, real& vx1, real& vx2, real& vx3)
 {
 	vx1  = a0 + ax*x + ay*y + az*z + axx*x*x + ayy*y*y + azz*z*z + axy*x*y + axz*x*z + ayz*y*z+axyz*x*y*z;
 	vx2  = b0 + bx*x + by*y + bz*z + bxx*x*x + byy*y*y + bzz*z*z + bxy*x*y + bxz*x*z + byz*y*z+bxyz*x*y*z;
 	vx3  = c0 + cx*x + cy*y + cz*z + cxx*x*x + cyy*y*y + czz*z*z + cxy*x*y + cxz*x*z + cyz*y*z+cxyz*x*y*z;
 }
 //////////////////////////////////////////////////////////////////////////
-void RheologyInterpolationProcessor::calcInterpolatedShearStress(real x, real y, real z,real& tauxx, real& tauyy, real& tauzz,real& tauxy, real& tauxz, real& tauyz)
+void RheologyInterpolator::calcInterpolatedShearStress(real x, real y, real z,real& tauxx, real& tauyy, real& tauzz,real& tauxy, real& tauxz, real& tauyz)
 {
 	tauxx=ax+2*axx*x+axy*y+axz*z+axyz*y*z;
 	tauyy=by+2*byy*y+bxy*x+byz*z+bxyz*x*z;
diff --git a/src/cpu/NonNewtonianFluids/LBM/RheologyInterpolationProcessor.h b/src/cpu/NonNewtonianFluids/LBM/RheologyInterpolator.h
similarity index 89%
rename from src/cpu/NonNewtonianFluids/LBM/RheologyInterpolationProcessor.h
rename to src/cpu/NonNewtonianFluids/LBM/RheologyInterpolator.h
index 178932204307606b9fc48d2745ebf1353547e3e8..4b9391df278dc3e69a08df8a1400e3871ca7f067 100644
--- a/src/cpu/NonNewtonianFluids/LBM/RheologyInterpolationProcessor.h
+++ b/src/cpu/NonNewtonianFluids/LBM/RheologyInterpolator.h
@@ -26,24 +26,23 @@
 //  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 RheologyInterpolationProcessor.h
+//! \file RheologyInterpolator.h
 //! \ingroup LBM
 //! \author Konstantin Kutscher
 //=======================================================================================
-#ifndef RheologyInterpolationProcessor_H_
-#define RheologyInterpolationProcessor_H_
+#ifndef RheologyInterpolator_H_
+#define RheologyInterpolator_H_
 
-#include "InterpolationProcessor.h"
+#include "Interpolation/Interpolator.h"
 #include "D3Q27System.h"
 
 //! \brief A class implements an interpolation function of grid refinement for thixotropic fluid.
 
-class RheologyInterpolationProcessor : public InterpolationProcessor
+class RheologyInterpolator : public Interpolator
 {
 public:
-   RheologyInterpolationProcessor();
-   RheologyInterpolationProcessor(real omegaC, real omegaF, real omegaMin);
-   virtual ~RheologyInterpolationProcessor();
+   RheologyInterpolator();
+   RheologyInterpolator(real omegaC, real omegaF, real omegaMin);
    InterpolationProcessorPtr clone();
    void setOmegas(real omegaC, real omegaF);
    void setOmegaMin(real omegaMin);
@@ -94,12 +93,12 @@ private:
 };
 
 //////////////////////////////////////////////////////////////////////////
-inline void RheologyInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF)
+inline void RheologyInterpolator::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF)
 {
    this->interpolateCoarseToFine(icellC, icellF, 0.0, 0.0, 0.0);
 }
 //////////////////////////////////////////////////////////////////////////
-inline void RheologyInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC)
+inline void RheologyInterpolator::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC)
 {
    this->interpolateFineToCoarse(icellF, icellC, 0.0, 0.0, 0.0);
 }
diff --git a/src/cpu/NonNewtonianFluids/LBM/RheologyK17LBMKernel.cpp b/src/cpu/NonNewtonianFluids/LBM/RheologyK17LBMKernel.cpp
index a9c7a05da6eefb4f44834d1c91f5e5b43d4f5eb4..2981156c4a5f6acc0df336d9d66cc9a9e97d8c1a 100644
--- a/src/cpu/NonNewtonianFluids/LBM/RheologyK17LBMKernel.cpp
+++ b/src/cpu/NonNewtonianFluids/LBM/RheologyK17LBMKernel.cpp
@@ -33,7 +33,7 @@
 
 #include "RheologyK17LBMKernel.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <math.h>
 #include "DataSet3D.h"
diff --git a/src/cpu/NonNewtonianFluids/LBM/ThixotropyExpLBMKernel.cpp b/src/cpu/NonNewtonianFluids/LBM/ThixotropyExpLBMKernel.cpp
index cbfa924405109fa03dfef6532c538fb2917d2d43..a55ee9a28740843a4bf3c8587b3afb5f348c2759 100644
--- a/src/cpu/NonNewtonianFluids/LBM/ThixotropyExpLBMKernel.cpp
+++ b/src/cpu/NonNewtonianFluids/LBM/ThixotropyExpLBMKernel.cpp
@@ -1,6 +1,6 @@
 #include "ThixotropyExpLBMKernel.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <math.h>
 #include "DataSet3D.h"
diff --git a/src/cpu/NonNewtonianFluids/LBM/ThixotropyLBMKernel.cpp b/src/cpu/NonNewtonianFluids/LBM/ThixotropyLBMKernel.cpp
index 368436088dc72bb10677f046aa9e954f9120be42..f764af6f5cd75b67ce51f8644d9f1839894fcdc3 100644
--- a/src/cpu/NonNewtonianFluids/LBM/ThixotropyLBMKernel.cpp
+++ b/src/cpu/NonNewtonianFluids/LBM/ThixotropyLBMKernel.cpp
@@ -1,6 +1,6 @@
 #include "ThixotropyLBMKernel.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <math.h>
 #include "DataSet3D.h"
diff --git a/src/cpu/NonNewtonianFluids/NonNewtonianFluids.h b/src/cpu/NonNewtonianFluids/NonNewtonianFluids.h
index 169082259b203b195b7fc636d84cdd4029ce6ccf..705a07af12b8ad8d32632d28dde5f4cd4b127173 100644
--- a/src/cpu/NonNewtonianFluids/NonNewtonianFluids.h
+++ b/src/cpu/NonNewtonianFluids/NonNewtonianFluids.h
@@ -1,4 +1,37 @@
-#pragma once
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
+//
+//  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 NonNewtonianFluids.h
+//! \ingroup NonNewtonianFluids
+//! \author Konstantin Kutscher
+//=======================================================================================
+#ifndef NonNewtonianFluids_h
+#define NonNewtonianFluids_h
 
 #include "NonNewtonianFluids/BoundaryConditions/ThixotropyDensityBCStrategy.h"
 #include "NonNewtonianFluids/BoundaryConditions/ThixotropyNoSlipBCStrategy.h"
@@ -18,7 +51,9 @@
 #include "NonNewtonianFluids/LBM/ThixotropyExpLBMKernel.h"
 #include "NonNewtonianFluids/LBM/RheologyBinghamModelLBMKernel.h"
 #include "NonNewtonianFluids/LBM/RheologyHerschelBulkleyModelLBMKernel.h"
-#include "NonNewtonianFluids/LBM/RheologyInterpolationProcessor.h"
+#include "NonNewtonianFluids/LBM/RheologyInterpolator.h"
 #include "NonNewtonianFluids/LBM/Rheology.h"
 #include "NonNewtonianFluids/LBM/RheologyK17LBMKernel.h"
 #include "NonNewtonianFluids/LBM/RheologyPowellEyringModelLBMKernel.h"
+
+#endif
\ No newline at end of file
diff --git a/src/cpu/VirtualFluids.h b/src/cpu/VirtualFluids.h
index 6fa9b30bfc0e650f289d00a2970bdff545c71359..aead82d5dfc4c8565ef4abe03351b085722db2ad 100644
--- a/src/cpu/VirtualFluids.h
+++ b/src/cpu/VirtualFluids.h
@@ -208,14 +208,11 @@
 #include <TimeDependentBCSimulationObserver.h>
 
 #include <IntegrateValuesHelper.h>
-//#include <LBM/D3Q27CompactInterpolationProcessor.h>
-#include <LBM/CompressibleOffsetInterpolationProcessor.h>
-#include <LBM/CompressibleOffsetMomentsInterpolationProcessor.h>
-#include <LBM/CompressibleOffsetSquarePressureInterpolationProcessor.h>
-#include <LBM/IncompressibleOffsetInterpolationProcessor.h>
-#include <LBM/InterpolationHelper.h>
-#include <LBM/InterpolationProcessor.h>
-//#include <LBM/D3Q27OffsetInterpolationProcessor.h>
+#include <LBM/Interpolation/CompressibleOffsetInterpolator.h>
+#include <LBM/Interpolation/CompressibleOffsetMomentsInterpolator.h>
+#include <LBM/Interpolation/CompressibleOffsetSquarePressureInterpolator.h>
+#include <LBM/Interpolation/IncompressibleOffsetInterpolator.h>
+#include <LBM/Interpolation/Interpolator.h>
 #include <IncompressibleCumulantWithSpongeLayerLBMKernel.h>
 #include <LBM/CompressibleCumulant4thOrderViscosityLBMKernel.h>
 #include <LBM/CompressibleCumulantLBMKernel.h>
@@ -223,7 +220,6 @@
 #include <LBM/ICell.h>
 #include <LBM/IncompressibleCumulantLBMKernel.h>
 #include <LBM/InitDensityLBMKernel.h>
-#include <LBM/InterpolationProcessor.h>
 #include <LBM/LBMKernel.h>
 #include <LBM/LBMKernelETD3Q27BGK.h>
 #include <LBM/LBMSystem.h>
@@ -232,11 +228,6 @@
 
 #include <LBM/CumulantLBMKernel.h>
 #include <LBM/CumulantK17LBMKernel.h>
-//#include <LBM/RheologyModelLBMKernel.h>
-//#include <LBM/RheologyModelLBMKernel2.h>
-
-
-
 
 
 #include <geometry3d/CoordinateTransformation3D.h>
diff --git a/src/cpu/VirtualFluidsCore/BoundaryConditions/NoSlipBCStrategy.cpp b/src/cpu/VirtualFluidsCore/BoundaryConditions/NoSlipBCStrategy.cpp
index cabd41b30dd31ac8751c60f00f46c899cbfa2334..bb98e499421328abc36f8911a14bcb8c90ebabd1 100644
--- a/src/cpu/VirtualFluidsCore/BoundaryConditions/NoSlipBCStrategy.cpp
+++ b/src/cpu/VirtualFluidsCore/BoundaryConditions/NoSlipBCStrategy.cpp
@@ -54,23 +54,22 @@ void NoSlipBCStrategy::addDistributions(SPtr<DistributionArray3D> distributions)
 //////////////////////////////////////////////////////////////////////////
 void NoSlipBCStrategy::applyBC()
 {
-    real f[D3Q27System::ENDF + 1];
-    real feq[D3Q27System::ENDF + 1];
+    using namespace vf::basics::constant;
+    using namespace D3Q27System;
+    real f[ENDF + 1];
+    real feq[ENDF + 1];
     distributions->getDistributionInv(f, x1, x2, x3);
     real rho, vx1, vx2, vx3;
     calcMacrosFct(f, rho, vx1, vx2, vx3);
     calcFeqFct(feq, rho, vx1, vx2, vx3);
 
-    for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
+    for (int fdir = FSTARTDIR; fdir <= FENDDIR; fdir++) {
         if (bcPtr->hasNoSlipBoundaryFlag(fdir)) {
             // quadratic bounce back
-            const int invDir = D3Q27System::INVDIR[fdir];
-            real q        = bcPtr->getQ(invDir);
-            real fReturn = ((vf::basics::constant::c1o1 - q) / (vf::basics::constant::c1o1 + q)) * ((f[invDir] - feq[invDir]) / (vf::basics::constant::c1o1 - collFactor) + feq[invDir]) +
-                              ((q / (vf::basics::constant::c1o1 + q)) * (f[invDir] + f[fdir]));
-            distributions->setDistributionForDirection(fReturn, x1 + D3Q27System::DX1[invDir],
-                                                       x2 + D3Q27System::DX2[invDir], x3 + D3Q27System::DX3[invDir],
-                                                       fdir);
+            const int invDir = INVDIR[fdir];
+            real q = bcPtr->getQ(invDir);
+            real fReturn = ((c1o1 - q) / (c1o1 + q)) * ((f[invDir] - feq[invDir]) / (c1o1 - collFactor) + feq[invDir]) + ((q / (c1o1 + q)) * (f[invDir] + f[fdir]));
+            distributions->setDistributionForDirection(fReturn, x1 + DX1[invDir], x2 + DX2[invDir], x3 + DX3[invDir], fdir);
         }
     }
 }
diff --git a/src/cpu/VirtualFluidsCore/BoundaryConditions/SlipBC.cpp b/src/cpu/VirtualFluidsCore/BoundaryConditions/SlipBC.cpp
index 008adefd8196c6d6689316d29bbc2f3fe50b9f9e..eb254160395ce1ba12e22bc6ff6d6e063ce8f316 100644
--- a/src/cpu/VirtualFluidsCore/BoundaryConditions/SlipBC.cpp
+++ b/src/cpu/VirtualFluidsCore/BoundaryConditions/SlipBC.cpp
@@ -28,7 +28,7 @@
 //
 //! \file SlipBC.cpp
 //! \ingroup BoundarConditions
-//! \author Sören Freudiger
+//! \author Soeren Freudiger
 //=======================================================================================
 #include "SlipBC.h"
 #include "D3Q27Interactor.h"
diff --git a/src/cpu/VirtualFluidsCore/BoundaryConditions/SlipBC.h b/src/cpu/VirtualFluidsCore/BoundaryConditions/SlipBC.h
index 98205ba32b2d3ccec85346bd89a199e8e9a9049c..8e8788db8ded7a2f9eb0e47135f9babbc69e37da 100644
--- a/src/cpu/VirtualFluidsCore/BoundaryConditions/SlipBC.h
+++ b/src/cpu/VirtualFluidsCore/BoundaryConditions/SlipBC.h
@@ -28,7 +28,7 @@
 //
 //! \file SlipBC.h
 //! \ingroup BoundarConditions
-//! \author Sören Freudiger
+//! \author Soeren Freudiger
 //=======================================================================================
 #ifndef SlipBC_H
 #define SlipBC_H
diff --git a/src/cpu/VirtualFluidsCore/CMakeLists.txt b/src/cpu/VirtualFluidsCore/CMakeLists.txt
index 9f3cd96e889097a32ce737e56e3f1fa31dddaee0..aae663e80011c117a83d5a52d0ac0cbe0c59a5a8 100644
--- a/src/cpu/VirtualFluidsCore/CMakeLists.txt
+++ b/src/cpu/VirtualFluidsCore/CMakeLists.txt
@@ -31,6 +31,7 @@ target_include_directories(${library_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Co
 target_include_directories(${library_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Data)
 target_include_directories(${library_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Interactors)
 target_include_directories(${library_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/LBM)
+target_include_directories(${library_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/LBM/Interpolation)
 target_include_directories(${library_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Parallel)
 target_include_directories(${library_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Simulation)
 target_include_directories(${library_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/Visitors)
diff --git a/src/cpu/VirtualFluidsCore/Connectors/CoarseToFineVectorConnector.h b/src/cpu/VirtualFluidsCore/Connectors/CoarseToFineVectorConnector.h
index d7f9f72c4f86f5d849fa4f2c0cd703333007091a..ad40378f54e85cff41457fdb21a391f6ab8674b5 100644
--- a/src/cpu/VirtualFluidsCore/Connectors/CoarseToFineVectorConnector.h
+++ b/src/cpu/VirtualFluidsCore/Connectors/CoarseToFineVectorConnector.h
@@ -40,13 +40,14 @@
 #include "Block3DConnector.h"
 #include "D3Q27System.h"
 #include "Grid3D.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "LBMKernel.h"
 #include "MathUtil.hpp"
 #include "basics/container/CbVector.h"
 #include "basics/transmitter/TbTransmitter.h"
 #include "basics/transmitter/TbTransmitterLocal.h"
 #include <PointerDefinitions.h>
+#include "basics/constants/NumericConstants.h"
 
 #include "BCSet.h"
 #include "FineToCoarseVectorConnector.h"
@@ -829,6 +830,8 @@ void CoarseToFineVectorConnector<VectorTransmitter>::fillSendVectorExt(SPtr<Dist
                                                                        const int &lMaxX2, const int &lMaxX3,
                                                                        vector_type &data, int &index)
 {
+    using namespace vf::basics::constant;
+
     if (data.size() == 0)
         return;
     int ix1, ix2, ix3;
@@ -845,9 +848,9 @@ void CoarseToFineVectorConnector<VectorTransmitter>::fillSendVectorExt(SPtr<Dist
 
                 if (howManySolids == 0 || howManySolids == 8) {
                     iprocessor->readICell(fFrom, icellC, ix1, ix2, ix3);
-                    xoff = 0.0;
-                    yoff = 0.0;
-                    zoff = 0.0;
+                    xoff = c0o1;
+                    yoff = c0o1;
+                    zoff = c0o1;
                 } else {
                     if (!iprocessor->findNeighborICell(bcArray, fFrom, icellC, bMaxX1, bMaxX2, bMaxX3, ix1, ix2, ix3,
                                                        xoff, yoff, zoff)) {
@@ -1991,9 +1994,9 @@ void CoarseToFineVectorConnector<VectorTransmitter>::findCFnodes(SPtr<Distributi
 
                 if (howManySolids == 0 || howManySolids == 8) {
                     iprocessor->readICell(fFrom, icellC, ix1, ix2, ix3);
-                    xoff = 0.0;
-                    yoff = 0.0;
-                    zoff = 0.0;
+                    xoff = c0o1;
+                    yoff = c0o1;
+                    zoff = c0o1;
                 } else {
                     if (!iprocessor->findNeighborICell(bcArray, fFrom, icellC, bMaxX1, bMaxX2, bMaxX3, ix1, ix2, ix3,
                                                        xoff, yoff, zoff)) {
diff --git a/src/cpu/VirtualFluidsCore/Connectors/FineToCoarseVectorConnector.h b/src/cpu/VirtualFluidsCore/Connectors/FineToCoarseVectorConnector.h
index ffab5008241e7f8f4457c7385c83872a296ee748..94222fee2940dc13411b4c7520ac64a5ab942478 100644
--- a/src/cpu/VirtualFluidsCore/Connectors/FineToCoarseVectorConnector.h
+++ b/src/cpu/VirtualFluidsCore/Connectors/FineToCoarseVectorConnector.h
@@ -40,11 +40,12 @@
 #include "Block3DConnector.h"
 #include "D3Q27System.h"
 #include "Grid3D.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "LBMKernel.h"
 #include "MathUtil.hpp"
 #include "basics/transmitter/TbTransmitter.h"
 #include <PointerDefinitions.h>
+#include "basics/constants/NumericConstants.h"
 
 #include "BCSet.h"
 #include "DataSet3D.h"
@@ -793,6 +794,8 @@ void FineToCoarseVectorConnector<VectorTransmitter>::fillSendVector(SPtr<Distrib
                                                                     const int &lMaxX1, const int &lMaxX2,
                                                                     const int &lMaxX3, vector_type &data, int &index)
 {
+    using namespace vf::basics::constant;
+
     int ix1, ix2, ix3;
     real xoff, yoff, zoff;
     SPtr<BCArray3D> bcArray = block.lock()->getKernel()->getBCSet()->getBCArray();
@@ -807,9 +810,9 @@ void FineToCoarseVectorConnector<VectorTransmitter>::fillSendVector(SPtr<Distrib
 
                 if (howManySolids == 0 || howManySolids == 8) {
                     iprocessor->readICell(fFrom, icellF, ix1, ix2, ix3);
-                    xoff = 0.0;
-                    yoff = 0.0;
-                    zoff = 0.0;
+                    xoff = c0o1;
+                    yoff = c0o1;
+                    zoff = c0o1;
                 } else {
                     if (!iprocessor->findNeighborICell(bcArray, fFrom, icellF, bMaxX1, bMaxX2, bMaxX3, ix1, ix2, ix3,
                                                        xoff, yoff, zoff)) {
diff --git a/src/cpu/VirtualFluidsCore/Connectors/OneDistributionFullVectorConnector.cpp b/src/cpu/VirtualFluidsCore/Connectors/OneDistributionFullVectorConnector.cpp
index 1bdb92f6b0d51c3bfb8daf6e149be7c1be0fecf0..be66dfb5b0785198e826f3fe2017aa479b92b53a 100644
--- a/src/cpu/VirtualFluidsCore/Connectors/OneDistributionFullVectorConnector.cpp
+++ b/src/cpu/VirtualFluidsCore/Connectors/OneDistributionFullVectorConnector.cpp
@@ -13,6 +13,7 @@ OneDistributionFullVectorConnector::OneDistributionFullVectorConnector(SPtr<Bloc
 void OneDistributionFullVectorConnector::init()
 {
     using namespace vf::lbm::dir;
+    using namespace vf::basics::constant;
 
     FullVectorConnector::init();
     
@@ -25,36 +26,36 @@ void OneDistributionFullVectorConnector::init()
             break;
         case DIR_P00:
         case DIR_M00:
-            sender->getData().resize(maxX2 * maxX3 * anz, 0.0);
+            sender->getData().resize(maxX2 * maxX3 * anz, c0o1);
             break;
         case DIR_0P0:
         case DIR_0M0:
-            sender->getData().resize(maxX1 * maxX3 * anz, 0.0);
+            sender->getData().resize(maxX1 * maxX3 * anz, c0o1);
             break;
         case DIR_00P:
         case DIR_00M:
-            sender->getData().resize(maxX1 * maxX2 * anz, 0.0);
+            sender->getData().resize(maxX1 * maxX2 * anz, c0o1);
             break;
 
         case DIR_PP0:
         case DIR_MM0:
         case DIR_PM0:
         case DIR_MP0:
-            sender->getData().resize(maxX3 * anz, 0.0);
+            sender->getData().resize(maxX3 * anz, c0o1);
             break;
 
         case DIR_P0P:
         case DIR_M0M:
         case DIR_P0M:
         case DIR_M0P:
-            sender->getData().resize(maxX2 * anz, 0.0);
+            sender->getData().resize(maxX2 * anz, c0o1);
             break;
 
         case DIR_0PP:
         case DIR_0MM:
         case DIR_0PM:
         case DIR_0MP:
-            sender->getData().resize(maxX1 * anz, 0.0);
+            sender->getData().resize(maxX1 * anz, c0o1);
             break;
 
         case DIR_PPP:
@@ -65,7 +66,7 @@ void OneDistributionFullVectorConnector::init()
         case DIR_MPM:
         case DIR_PMM:
         case DIR_MPP:
-            sender->getData().resize(anz, 0.0);
+            sender->getData().resize(anz, c0o1);
             break;
 
         default:
diff --git a/src/cpu/VirtualFluidsCore/Connectors/ThreeDistributionsDoubleGhostLayerFullVectorConnector.h b/src/cpu/VirtualFluidsCore/Connectors/ThreeDistributionsDoubleGhostLayerFullVectorConnector.h
index e124251d8f8be21aa33ccb8dc91f7e9b40356827..c91103481e71979d93830573fe3a27a80c77a337 100644
--- a/src/cpu/VirtualFluidsCore/Connectors/ThreeDistributionsDoubleGhostLayerFullVectorConnector.h
+++ b/src/cpu/VirtualFluidsCore/Connectors/ThreeDistributionsDoubleGhostLayerFullVectorConnector.h
@@ -198,7 +198,8 @@ inline void ThreeDistributionsDoubleGhostLayerFullVectorConnector::fillData(vect
 
    sdata[index++] = (*this->zeroH2distributions)(x1, x2, x3);
 
-   sdata[index++] = (*this->pressure)(x1, x2, x3);
+   if (this->pressure) 
+      sdata[index++] = (*this->pressure)(x1, x2, x3);
 }
 //////////////////////////////////////////////////////////////////////////
 inline void ThreeDistributionsDoubleGhostLayerFullVectorConnector::distributeData(vector_type& rdata, int& index, int x1, int x2, int x3)
@@ -294,7 +295,8 @@ inline void ThreeDistributionsDoubleGhostLayerFullVectorConnector::distributeDat
 
    (*this->zeroH2distributions)(x1, x2, x3) = rdata[index++];
 
-   (*this->pressure)(x1, x2, x3) = rdata[index++];
+   if (this->pressure)
+      (*this->pressure)(x1, x2, x3) = rdata[index++];
 }
 
 
diff --git a/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsDoubleGhostLayerFullVectorConnector.cpp b/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsDoubleGhostLayerFullVectorConnector.cpp
index 8f6b88898a9da1cfca9aee49ae4cb084ee54217a..f8ff7d5c28bb04e41f51a5223dc9a64bcd0cf317 100644
--- a/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsDoubleGhostLayerFullVectorConnector.cpp
+++ b/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsDoubleGhostLayerFullVectorConnector.cpp
@@ -51,6 +51,7 @@ TwoDistributionsDoubleGhostLayerFullVectorConnector::TwoDistributionsDoubleGhost
 void TwoDistributionsDoubleGhostLayerFullVectorConnector::init()
 {
    using namespace vf::lbm::dir;
+   using namespace vf::basics::constant;
 
    FullVectorConnector::init();
 
@@ -63,26 +64,26 @@ void TwoDistributionsDoubleGhostLayerFullVectorConnector::init()
    {
    case DIR_000: UB_THROW(UbException(UB_EXARGS, "ZERO not allowed")); break;
    case DIR_P00:
-   case DIR_M00: sender->getData().resize(maxX2*maxX3*anz*2, 0.0);   break;
+   case DIR_M00: sender->getData().resize(maxX2*maxX3*anz*2, c0o1);   break;
    case DIR_0P0:
-   case DIR_0M0: sender->getData().resize(maxX1*maxX3*anz*2, 0.0);   break;
+   case DIR_0M0: sender->getData().resize(maxX1*maxX3*anz*2, c0o1);   break;
    case DIR_00P:
-   case DIR_00M: sender->getData().resize(maxX1*maxX2*anz*2, 0.0);   break;
+   case DIR_00M: sender->getData().resize(maxX1*maxX2*anz*2, c0o1);   break;
 
    case DIR_PP0:
    case DIR_MM0:
    case DIR_PM0:
-   case DIR_MP0:  sender->getData().resize(maxX3*anz*4, 0.0);   break;
+   case DIR_MP0:  sender->getData().resize(maxX3*anz*4, c0o1);   break;
 
    case DIR_P0P:
    case DIR_M0M:
    case DIR_P0M:
-   case DIR_M0P:  sender->getData().resize(maxX2*anz*4, 0.0);   break;
+   case DIR_M0P:  sender->getData().resize(maxX2*anz*4, c0o1);   break;
 
    case DIR_0PP:
    case DIR_0MM:
    case DIR_0PM:
-   case DIR_0MP:  sender->getData().resize(maxX1*anz*4, 0.0);   break;
+   case DIR_0MP:  sender->getData().resize(maxX1*anz*4, c0o1);   break;
 
    case DIR_PPP:
    case DIR_MMM:
@@ -91,7 +92,7 @@ void TwoDistributionsDoubleGhostLayerFullVectorConnector::init()
    case DIR_PMP:
    case DIR_MPM:
    case DIR_PMM:
-   case DIR_MPP:  sender->getData().resize(anz*8, 0.0);   break;
+   case DIR_MPP:  sender->getData().resize(anz*8, c0o1);   break;
 
    default: UB_THROW(UbException(UB_EXARGS, "unknown sendDir"));
    }
diff --git a/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsDoubleGhostLayerFullVectorConnector.h b/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsDoubleGhostLayerFullVectorConnector.h
index d5769c726eda127ca603d6984744274abaf2edae..67f896af34c8b7e7d7fa9c918236b5a435156c62 100644
--- a/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsDoubleGhostLayerFullVectorConnector.h
+++ b/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsDoubleGhostLayerFullVectorConnector.h
@@ -158,7 +158,8 @@ inline void TwoDistributionsDoubleGhostLayerFullVectorConnector::fillData(vector
 
    sdata[index++] = (*this->zeroHdistributions)(x1, x2, x3);
 
-   sdata[index++] = (*this->pressure)(x1, x2, x3);
+   if (this->pressure)
+      sdata[index++] = (*this->pressure)(x1, x2, x3);
 }
 //////////////////////////////////////////////////////////////////////////
 inline void TwoDistributionsDoubleGhostLayerFullVectorConnector::distributeData(vector_type& rdata, int& index, int x1, int x2, int x3)
@@ -224,7 +225,8 @@ inline void TwoDistributionsDoubleGhostLayerFullVectorConnector::distributeData(
 
    (*this->zeroHdistributions)(x1, x2, x3) = rdata[index++];
 
-   (*this->pressure)(x1, x2, x3) = rdata[index++];
+   if (this->pressure)
+      (*this->pressure)(x1, x2, x3) = rdata[index++];
 }
 
 
diff --git a/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsFullVectorConnector.cpp b/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsFullVectorConnector.cpp
index 7987c2f6c8af52fbf897ff6bbcee47add3fc0056..36e34321d0bcaecec63b70d2b059542dc5514b95 100644
--- a/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsFullVectorConnector.cpp
+++ b/src/cpu/VirtualFluidsCore/Connectors/TwoDistributionsFullVectorConnector.cpp
@@ -51,7 +51,8 @@ TwoDistributionsFullVectorConnector::TwoDistributionsFullVectorConnector(SPtr<Bl
 void TwoDistributionsFullVectorConnector::init()
 {
    using namespace vf::lbm::dir;
-
+   using namespace vf::basics::constant;
+  
    FullVectorConnector::init();
 
    fDis = dynamicPointerCast<EsoTwist3D>(block.lock()->getKernel()->getDataSet()->getFdistributions());
@@ -62,26 +63,26 @@ void TwoDistributionsFullVectorConnector::init()
    {
    case DIR_000: UB_THROW(UbException(UB_EXARGS, "ZERO not allowed")); break;
    case DIR_P00:
-   case DIR_M00: sender->getData().resize(maxX2*maxX3*anz, 0.0);   break;
+   case DIR_M00: sender->getData().resize(maxX2*maxX3*anz, c0o1);   break;
    case DIR_0P0:
-   case DIR_0M0: sender->getData().resize(maxX1*maxX3*anz, 0.0);   break;
+   case DIR_0M0: sender->getData().resize(maxX1*maxX3*anz, c0o1);   break;
    case DIR_00P:
-   case DIR_00M: sender->getData().resize(maxX1*maxX2*anz, 0.0);   break;
+   case DIR_00M: sender->getData().resize(maxX1*maxX2*anz, c0o1);   break;
 
    case DIR_PP0:
    case DIR_MM0:
    case DIR_PM0:
-   case DIR_MP0:  sender->getData().resize(maxX3*anz, 0.0);   break;
+   case DIR_MP0:  sender->getData().resize(maxX3*anz, c0o1);   break;
 
    case DIR_P0P:
    case DIR_M0M:
    case DIR_P0M:
-   case DIR_M0P:  sender->getData().resize(maxX2*anz, 0.0);   break;
+   case DIR_M0P:  sender->getData().resize(maxX2*anz, c0o1);   break;
 
    case DIR_0PP:
    case DIR_0MM:
    case DIR_0PM:
-   case DIR_0MP:  sender->getData().resize(maxX1*anz, 0.0);   break;
+   case DIR_0MP:  sender->getData().resize(maxX1*anz, c0o1);   break;
 
    case DIR_PPP:
    case DIR_MMM:
@@ -90,7 +91,7 @@ void TwoDistributionsFullVectorConnector::init()
    case DIR_PMP:
    case DIR_MPM:
    case DIR_PMM:
-   case DIR_MPP:  sender->getData().resize(anz, 0.0);   break;
+   case DIR_MPP:  sender->getData().resize(anz, c0o1);   break;
 
    default: UB_THROW(UbException(UB_EXARGS, "unknown sendDir"));
    }
diff --git a/src/cpu/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.cpp b/src/cpu/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.cpp
index 4660e7b8397482683d67e6ba74b466b1857df10c..11119ecbd59f1a4d145fb130b3d0fe2b2a671fac 100644
--- a/src/cpu/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.cpp
+++ b/src/cpu/VirtualFluidsCore/Data/D3Q27EsoTwist3DSplittedVector.cpp
@@ -259,7 +259,7 @@ void D3Q27EsoTwist3DSplittedVector::setDistributionForDirection(real f, size_t x
                                                                 int direction)
 {
     using namespace vf::lbm::dir;
-
+ 
     switch (direction) {
         case DIR_P00:
             (*this->nonLocalDistributions)(D3Q27System::ET_W, x1 + 1, x2, x3) = f;
diff --git a/src/cpu/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.cpp b/src/cpu/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.cpp
index e8746ffda6e2b44d004b0d33136779be405b5a28..c30a4cc8ceab72accc75238ea1535e923b3a3bee 100644
--- a/src/cpu/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.cpp
+++ b/src/cpu/VirtualFluidsCore/Interactors/D3Q27TriFaceMeshInteractor.cpp
@@ -233,7 +233,6 @@ void D3Q27TriFaceMeshInteractor::setQs(const real &timeStep)
     // notwendige variablen initialisieren (u.a. blockDeltas des groben levels)
     float triPoints[3][3];
     float vx1 = 0.0, vx2 = 0.0, vx3 = 0.0;
-    unsigned counterTriBoxOverlap = 0, counterAABBTriFace = 0, counterHalfspace = 0, counterBilligOBB = 0;
     std::vector<GbTriFaceMesh3D::TriFace> &triangles = *mesh->getTriangles();
     std::vector<GbTriFaceMesh3D::Vertex> &nodes      = *mesh->getNodes();
     std::map<SPtr<Block3D>, std::set<UbTupleInt3>> tmpSolidNodesFromOtherInteractors;
@@ -341,7 +340,6 @@ void D3Q27TriFaceMeshInteractor::setQs(const real &timeStep)
 
                 // wenn dreieck "vergroesserten cube" nicht schneidet/beruehrt -> keine BC moeglich -> continue
                 if (!GbMeshTools3D::triBoxOverlap(boxCenter, halfBoxSize, triPoints)) {
-                    counterTriBoxOverlap++;
                     continue;
                 }
 
@@ -396,7 +394,6 @@ void D3Q27TriFaceMeshInteractor::setQs(const real &timeStep)
                             bool pointIsOnBoundary = true;
                             if (!boundingCubeTriangle.isPointInGbObject3D(internX1, internX2, internX3,
                                                                           pointIsOnBoundary)) {
-                                counterAABBTriFace++;
                                 continue;
                             }
                             // std::cout<<"internX3  "<<internX3<<"  internX2"<<internX2<<" internX1 "<<internX1<<"\n";
@@ -408,13 +405,11 @@ void D3Q27TriFaceMeshInteractor::setQs(const real &timeStep)
                             if (useHalfSpace &&
                                 UbMath::less(distance, 0.0)) //== !halfSpace.ptInside(internX1,internX2,internX3) )
                             {
-                                counterHalfspace++;
                                 continue;
                             }
 
                             // BilligOBB-Test: wenn distance > qEinflussDelta -> kein q
                             if (UbMath::greater(fabs(distance), qEinflussDelta)) {
-                                counterBilligOBB++;
                                 continue;
                             }
 
@@ -1050,7 +1045,6 @@ void D3Q27TriFaceMeshInteractor::initInteractor2(const real &timeStep)
                                         // SG 26.08.2010 if(!bc && !bcMatrix->isSolid())
                                         if (!bc) {
                                             bc = SPtr<BoundaryConditions>(new BoundaryConditions);
-                                            ;
                                             bcMatrix->setBC(ix1, ix2, ix3, bc);
                                         } else if (UbMath::less(bc->getQ(fdir), q)) // schon ein kuerzeres q voehanden?
                                         {
@@ -1120,7 +1114,7 @@ void D3Q27TriFaceMeshInteractor::initInteractor2(const real &timeStep)
     UBLOG(logDEBUG1, "       * rejected nodes  with halfspace      test : " << counterHalfspace);
     UBLOG(logDEBUG1, "       * rejected nodes  with OBB            test : " << counterBilligOBB);
 
-    typedef std::map<SPtr<Block3D>, SolidCheckMethod>::iterator BlockSolidCheckMethodIterator;
+    using BlockSolidCheckMethodIterator = std::map<SPtr<Block3D>, SolidCheckMethod>::iterator;
 
     //////////////////////////////////////////////////////////////////////////
     // SOLID checks
diff --git a/src/cpu/VirtualFluidsCore/LBM/CompressibleCumulant4thOrderViscosityLBMKernel.cpp b/src/cpu/VirtualFluidsCore/LBM/CompressibleCumulant4thOrderViscosityLBMKernel.cpp
index 421f81a1ac3301d982178a06b4b8c6378f626e57..c6349de8f1d281d31d0be4e684c54da457d3029f 100644
--- a/src/cpu/VirtualFluidsCore/LBM/CompressibleCumulant4thOrderViscosityLBMKernel.cpp
+++ b/src/cpu/VirtualFluidsCore/LBM/CompressibleCumulant4thOrderViscosityLBMKernel.cpp
@@ -1,6 +1,6 @@
 #include "CompressibleCumulant4thOrderViscosityLBMKernel.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <cmath>
 #include "DataSet3D.h"
diff --git a/src/cpu/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp b/src/cpu/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp
index 3c0795c21ed41c1f22dc06268e5fc1fa7922c845..ded8dff43910db33bd591cd4546f1dc73cc1110b 100644
--- a/src/cpu/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp
+++ b/src/cpu/VirtualFluidsCore/LBM/CompressibleCumulantLBMKernel.cpp
@@ -1,6 +1,6 @@
 #include "CompressibleCumulantLBMKernel.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include "DataSet3D.h"
 #include "Block3D.h"
diff --git a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp b/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp
deleted file mode 100644
index 74527c0c39d5255a4ca3e647a288fffa027373ac..0000000000000000000000000000000000000000
--- a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.cpp
+++ /dev/null
@@ -1,1292 +0,0 @@
-#include "CompressibleOffsetMomentsInterpolationProcessor.h"
-#include "D3Q27System.h"
-
-//using namespace UbMath;
-using namespace vf::basics::constant;
-
-CompressibleOffsetMomentsInterpolationProcessor::CompressibleOffsetMomentsInterpolationProcessor()
-    
-{
-   this->bulkViscosity = c0o1;
-   this->shearViscosity = c0o1;
-   this->OxxPyyPzzC = c1o1;
-   this->OxxPyyPzzF = c1o1;
-}
-//////////////////////////////////////////////////////////////////////////
-CompressibleOffsetMomentsInterpolationProcessor::CompressibleOffsetMomentsInterpolationProcessor(real omegaC, real omegaF)
-   : omegaC(omegaC), omegaF(omegaF)
-{
-   this->bulkViscosity = c0o1;
-   this->shearViscosity = c0o1;
-   this->OxxPyyPzzC = c1o1;
-   this->OxxPyyPzzF = c1o1;
-}
-//////////////////////////////////////////////////////////////////////////
-CompressibleOffsetMomentsInterpolationProcessor::~CompressibleOffsetMomentsInterpolationProcessor()
-= default;
-//////////////////////////////////////////////////////////////////////////
-InterpolationProcessorPtr CompressibleOffsetMomentsInterpolationProcessor::clone()
-{
-   InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new CompressibleOffsetMomentsInterpolationProcessor(this->omegaC, this->omegaF));
-
-   dynamicPointerCast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzC = this->OxxPyyPzzC;
-   dynamicPointerCast<CompressibleOffsetMomentsInterpolationProcessor>(iproc)->OxxPyyPzzF = this->OxxPyyPzzF;
-
-   return iproc;
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetMomentsInterpolationProcessor::setOmegas( real omegaC, real omegaF )
-{
-   this->omegaC = omegaC;
-   this->omegaF = omegaF;
-
-   real dtC = (c3o1 *shearViscosity)/((c1o1/omegaC)-c1o2);
-   real dtF = (c3o1 *shearViscosity)/((c1o1/omegaF)-c1o2);
-
-   if (bulkViscosity != 0)
-   {
-      this->OxxPyyPzzC = LBMSystem::calcOmega2(bulkViscosity, dtC);
-      this->OxxPyyPzzF = LBMSystem::calcOmega2(bulkViscosity, dtF);
-   }
-   else
-   {
-      this->OxxPyyPzzC = c1o1;
-      this->OxxPyyPzzF = c1o1;
-   }
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetMomentsInterpolationProcessor::setOffsets(real xoff, real yoff, real zoff)
-{
-   this->xoff = xoff;
-   this->yoff = yoff;
-   this->zoff = zoff;     
-   this->xoff_sq = xoff * xoff;
-   this->yoff_sq = yoff * yoff;
-   this->zoff_sq = zoff * zoff;
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetMomentsInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff)
-{
-   setOffsets(xoff, yoff, zoff);
-   calcInterpolatedCoefficiets(icellC, omegaC, c1o2);
-   calcInterpolatedNodeCF(icellF.BSW, omegaF, -c1o4, -c1o4, -c1o4, calcPressBSW(), -c1o1, -c1o1, -c1o1);
-   calcInterpolatedNodeCF(icellF.BNE, omegaF,  c1o4,  c1o4, -c1o4, calcPressBNE(),  c1o1,  c1o1, -c1o1);
-   calcInterpolatedNodeCF(icellF.TNW, omegaF, -c1o4,  c1o4,  c1o4, calcPressTNW(), -c1o1,  c1o1,  c1o1);
-   calcInterpolatedNodeCF(icellF.TSE, omegaF,  c1o4, -c1o4,  c1o4, calcPressTSE(),  c1o1, -c1o1,  c1o1);
-   calcInterpolatedNodeCF(icellF.BNW, omegaF, -c1o4,  c1o4, -c1o4, calcPressBNW(), -c1o1,  c1o1, -c1o1);
-   calcInterpolatedNodeCF(icellF.BSE, omegaF,  c1o4, -c1o4, -c1o4, calcPressBSE(),  c1o1, -c1o1, -c1o1);
-   calcInterpolatedNodeCF(icellF.TSW, omegaF, -c1o4, -c1o4,  c1o4, calcPressTSW(), -c1o1, -c1o1,  c1o1);
-   calcInterpolatedNodeCF(icellF.TNE, omegaF,  c1o4,  c1o4,  c1o4, calcPressTNE(),  c1o1,  c1o1,  c1o1);
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetMomentsInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff)
-{
-   setOffsets(xoff, yoff, zoff);
-   calcInterpolatedCoefficiets(icellF, omegaF, c2o1);
-   calcInterpolatedNodeFC(icellC, omegaC);
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetMomentsInterpolationProcessor::calcMoments(const real* const f, real omega, real& press, real& vx1, real& vx2, real& vx3, 
-                                                    real& kxy, real& kyz, real& kxz, real& kxxMyy, real& kxxMzz)
-{
-   using namespace D3Q27System;
-   using namespace vf::lbm::dir;
-
-   real drho = c0o1;
-   D3Q27System::calcCompMacroscopicValues(f,drho,vx1,vx2,vx3);
-   
-   press = drho; //interpolate rho!
-
-   kxy   = -c3o1*omega*((((f[DIR_MMP]+f[DIR_PPM])-(f[DIR_MPP]+f[DIR_PMM]))+((f[DIR_MMM]+f[DIR_PPP])-(f[DIR_MPM]+f[DIR_PMP])))+((f[DIR_MM0]+f[DIR_PP0])-(f[DIR_MP0]+f[DIR_PM0]))/(c1o1 + drho)-(vx1*vx2));// might not be optimal MG 25.2.13
-   kyz   = -c3o1*omega*((((f[DIR_MMM]+f[DIR_PPP])-(f[DIR_PMP]+f[DIR_MPM]))+((f[DIR_PMM]+f[DIR_MPP])-(f[DIR_MMP]+f[DIR_PPM])))+((f[DIR_0MM]+f[DIR_0PP])-(f[DIR_0MP]+f[DIR_0PM]))/(c1o1 + drho)-(vx2*vx3));
-   kxz   = -c3o1*omega*((((f[DIR_MPM]+f[DIR_PMP])-(f[DIR_MMP]+f[DIR_PPM]))+((f[DIR_MMM]+f[DIR_PPP])-(f[DIR_PMM]+f[DIR_MPP])))+((f[DIR_M0M]+f[DIR_P0P])-(f[DIR_M0P]+f[DIR_P0M]))/(c1o1 + drho)-(vx1*vx3));
-   kxxMyy = -c3o1/c2o1*omega*((((f[DIR_M0M]+f[DIR_P0P])-(f[DIR_0MM]+f[DIR_0PP]))+((f[DIR_M0P]+f[DIR_P0M])-(f[DIR_0MP]+f[DIR_0PM])))+((f[DIR_M00]+f[DIR_P00])-(f[DIR_0M0]+f[DIR_0P0]))/(c1o1 + drho)-(vx1*vx1-vx2*vx2));
-   kxxMzz = -c3o1/c2o1*omega*((((f[DIR_MP0]+f[DIR_PM0])-(f[DIR_0MM]+f[DIR_0PP]))+((f[DIR_MM0]+f[DIR_PP0])-(f[DIR_0MP]+f[DIR_0PM])))+((f[DIR_M00]+f[DIR_P00])-(f[DIR_00M]+f[DIR_00P]))/(c1o1 + drho)-(vx1*vx1-vx3*vx3));
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedCoefficiets(const D3Q27ICell& icell, real omega, real eps_new)
-{
-   real        vx1_SWT,vx2_SWT,vx3_SWT;
-   real        vx1_NWT,vx2_NWT,vx3_NWT;
-   real        vx1_NET,vx2_NET,vx3_NET;
-   real        vx1_SET,vx2_SET,vx3_SET;
-   real        vx1_SWB,vx2_SWB,vx3_SWB;
-   real        vx1_NWB,vx2_NWB,vx3_NWB;
-   real        vx1_NEB,vx2_NEB,vx3_NEB;
-   real        vx1_SEB,vx2_SEB,vx3_SEB;
-
-   real        kxyFromfcNEQ_SWT, kyzFromfcNEQ_SWT, kxzFromfcNEQ_SWT, kxxMyyFromfcNEQ_SWT, kxxMzzFromfcNEQ_SWT;
-   real        kxyFromfcNEQ_NWT, kyzFromfcNEQ_NWT, kxzFromfcNEQ_NWT, kxxMyyFromfcNEQ_NWT, kxxMzzFromfcNEQ_NWT;
-   real        kxyFromfcNEQ_NET, kyzFromfcNEQ_NET, kxzFromfcNEQ_NET, kxxMyyFromfcNEQ_NET, kxxMzzFromfcNEQ_NET;
-   real        kxyFromfcNEQ_SET, kyzFromfcNEQ_SET, kxzFromfcNEQ_SET, kxxMyyFromfcNEQ_SET, kxxMzzFromfcNEQ_SET;
-   real        kxyFromfcNEQ_SWB, kyzFromfcNEQ_SWB, kxzFromfcNEQ_SWB, kxxMyyFromfcNEQ_SWB, kxxMzzFromfcNEQ_SWB;
-   real        kxyFromfcNEQ_NWB, kyzFromfcNEQ_NWB, kxzFromfcNEQ_NWB, kxxMyyFromfcNEQ_NWB, kxxMzzFromfcNEQ_NWB;
-   real        kxyFromfcNEQ_NEB, kyzFromfcNEQ_NEB, kxzFromfcNEQ_NEB, kxxMyyFromfcNEQ_NEB, kxxMzzFromfcNEQ_NEB;
-   real        kxyFromfcNEQ_SEB, kyzFromfcNEQ_SEB, kxzFromfcNEQ_SEB, kxxMyyFromfcNEQ_SEB, kxxMzzFromfcNEQ_SEB;
-
-   calcMoments(icell.TSW,omega,press_SWT,vx1_SWT,vx2_SWT,vx3_SWT, kxyFromfcNEQ_SWT, kyzFromfcNEQ_SWT, kxzFromfcNEQ_SWT, kxxMyyFromfcNEQ_SWT, kxxMzzFromfcNEQ_SWT);
-   calcMoments(icell.TNW,omega,press_NWT,vx1_NWT,vx2_NWT,vx3_NWT, kxyFromfcNEQ_NWT, kyzFromfcNEQ_NWT, kxzFromfcNEQ_NWT, kxxMyyFromfcNEQ_NWT, kxxMzzFromfcNEQ_NWT);
-   calcMoments(icell.TNE,omega,press_NET,vx1_NET,vx2_NET,vx3_NET, kxyFromfcNEQ_NET, kyzFromfcNEQ_NET, kxzFromfcNEQ_NET, kxxMyyFromfcNEQ_NET, kxxMzzFromfcNEQ_NET);
-   calcMoments(icell.TSE,omega,press_SET,vx1_SET,vx2_SET,vx3_SET, kxyFromfcNEQ_SET, kyzFromfcNEQ_SET, kxzFromfcNEQ_SET, kxxMyyFromfcNEQ_SET, kxxMzzFromfcNEQ_SET);
-   calcMoments(icell.BSW,omega,press_SWB,vx1_SWB,vx2_SWB,vx3_SWB, kxyFromfcNEQ_SWB, kyzFromfcNEQ_SWB, kxzFromfcNEQ_SWB, kxxMyyFromfcNEQ_SWB, kxxMzzFromfcNEQ_SWB);
-   calcMoments(icell.BNW,omega,press_NWB,vx1_NWB,vx2_NWB,vx3_NWB, kxyFromfcNEQ_NWB, kyzFromfcNEQ_NWB, kxzFromfcNEQ_NWB, kxxMyyFromfcNEQ_NWB, kxxMzzFromfcNEQ_NWB);
-   calcMoments(icell.BNE,omega,press_NEB,vx1_NEB,vx2_NEB,vx3_NEB, kxyFromfcNEQ_NEB, kyzFromfcNEQ_NEB, kxzFromfcNEQ_NEB, kxxMyyFromfcNEQ_NEB, kxxMzzFromfcNEQ_NEB);
-   calcMoments(icell.BSE,omega,press_SEB,vx1_SEB,vx2_SEB,vx3_SEB, kxyFromfcNEQ_SEB, kyzFromfcNEQ_SEB, kxzFromfcNEQ_SEB, kxxMyyFromfcNEQ_SEB, kxxMzzFromfcNEQ_SEB);
-
-   //LBMReal dxRho=c1o4*((press_NET-press_SWB)+(press_SET-press_NWB)+(press_NEB-press_SWT)+(press_SEB-press_NWT));
-   //LBMReal dyRho=c1o4*((press_NET-press_SWB)-(press_SET-press_NWB)+(press_NEB-press_SWT)-(press_SEB-press_NWT));
-   //LBMReal dzRho=c1o4*((press_NET-press_SWB)+(press_SET-press_NWB)-(press_NEB-press_SWT)-(press_SEB-press_NWT));
-
-   //   kxyFromfcNEQ_SWT+=vx1_SWT*dyRho+vx2_SWT*dxRho;
-   //   kxyFromfcNEQ_NWT+=vx1_NWT*dyRho+vx2_NWT*dxRho;
-   //   kxyFromfcNEQ_NET+=vx1_NET*dyRho+vx2_NET*dxRho;
-   //   kxyFromfcNEQ_SET+=vx1_SET*dyRho+vx2_SET*dxRho;
-   //   kxyFromfcNEQ_SWB+=vx1_SWB*dyRho+vx2_SWB*dxRho;
-   //   kxyFromfcNEQ_NWB+=vx1_NWB*dyRho+vx2_NWB*dxRho;
-   //   kxyFromfcNEQ_NEB+=vx1_NEB*dyRho+vx2_NEB*dxRho;
-   //   kxyFromfcNEQ_SEB+=vx1_SEB*dyRho+vx2_SEB*dxRho;
-
-   //   kyzFromfcNEQ_SWT+=vx3_SWT*dyRho+vx2_SWT*dzRho;
-   //   kyzFromfcNEQ_NWT+=vx3_NWT*dyRho+vx2_NWT*dzRho;
-   //   kyzFromfcNEQ_NET+=vx3_NET*dyRho+vx2_NET*dzRho;
-   //   kyzFromfcNEQ_SET+=vx3_SET*dyRho+vx2_SET*dzRho;
-   //   kyzFromfcNEQ_SWB+=vx3_SWB*dyRho+vx2_SWB*dzRho;
-   //   kyzFromfcNEQ_NWB+=vx3_NWB*dyRho+vx2_NWB*dzRho;
-   //   kyzFromfcNEQ_NEB+=vx3_NEB*dyRho+vx2_NEB*dzRho;
-   //   kyzFromfcNEQ_SEB+=vx3_SEB*dyRho+vx2_SEB*dzRho;
-
-   //   kxzFromfcNEQ_SWT+=vx1_SWT*dzRho+vx3_SWT*dxRho;
-   //   kxzFromfcNEQ_NWT+=vx1_NWT*dzRho+vx3_NWT*dxRho;
-   //   kxzFromfcNEQ_NET+=vx1_NET*dzRho+vx3_NET*dxRho;
-   //   kxzFromfcNEQ_SET+=vx1_SET*dzRho+vx3_SET*dxRho;
-   //   kxzFromfcNEQ_SWB+=vx1_SWB*dzRho+vx3_SWB*dxRho;
-   //   kxzFromfcNEQ_NWB+=vx1_NWB*dzRho+vx3_NWB*dxRho;
-   //   kxzFromfcNEQ_NEB+=vx1_NEB*dzRho+vx3_NEB*dxRho;
-   //   kxzFromfcNEQ_SEB+=vx1_SEB*dzRho+vx3_SEB*dxRho;
-
-   //   kxxMyyFromfcNEQ_SWT+=vx1_SWT*dxRho-vx2_SWT*dyRho;
-   //   kxxMyyFromfcNEQ_NWT+=vx1_NWT*dxRho-vx2_NWT*dyRho;
-   //   kxxMyyFromfcNEQ_NET+=vx1_NET*dxRho-vx2_NET*dyRho;
-   //   kxxMyyFromfcNEQ_SET+=vx1_SET*dxRho-vx2_SET*dyRho;
-   //   kxxMyyFromfcNEQ_SWB+=vx1_SWB*dxRho-vx2_SWB*dyRho;
-   //   kxxMyyFromfcNEQ_NWB+=vx1_NWB*dxRho-vx2_NWB*dyRho;
-   //   kxxMyyFromfcNEQ_NEB+=vx1_NEB*dxRho-vx2_NEB*dyRho;
-   //   kxxMyyFromfcNEQ_SEB+=vx1_SEB*dxRho-vx2_SEB*dyRho;
-
-   //   kxxMzzFromfcNEQ_SWT+=vx1_SWT*dxRho-vx3_SWT*dzRho;
-   //   kxxMzzFromfcNEQ_NWT+=vx1_NWT*dxRho-vx3_NWT*dzRho;
-   //   kxxMzzFromfcNEQ_NET+=vx1_NET*dxRho-vx3_NET*dzRho;
-   //   kxxMzzFromfcNEQ_SET+=vx1_SET*dxRho-vx3_SET*dzRho;
-   //   kxxMzzFromfcNEQ_SWB+=vx1_SWB*dxRho-vx3_SWB*dzRho;
-   //   kxxMzzFromfcNEQ_NWB+=vx1_NWB*dxRho-vx3_NWB*dzRho;
-   //   kxxMzzFromfcNEQ_NEB+=vx1_NEB*dxRho-vx3_NEB*dzRho;
-   //   kxxMzzFromfcNEQ_SEB+=vx1_SEB*dxRho-vx3_SEB*dzRho;
-
-
-      //kxxMzzFromfcNEQ_SWT=0.0;
-      //kxxMzzFromfcNEQ_NWT=0.0;
-      //kxxMzzFromfcNEQ_NET=0.0;
-      //kxxMzzFromfcNEQ_SET=0.0;
-      //kxxMzzFromfcNEQ_SWB=0.0;
-      //kxxMzzFromfcNEQ_NWB=0.0;
-      //kxxMzzFromfcNEQ_NEB=0.0;
-      //kxxMzzFromfcNEQ_SEB=0.0;
-
-
-
-
-
-   a0 = (-kxxMyyFromfcNEQ_NEB - kxxMyyFromfcNEQ_NET + kxxMyyFromfcNEQ_NWB + kxxMyyFromfcNEQ_NWT -
-      kxxMyyFromfcNEQ_SEB - kxxMyyFromfcNEQ_SET + kxxMyyFromfcNEQ_SWB + kxxMyyFromfcNEQ_SWT -
-      kxxMzzFromfcNEQ_NEB - kxxMzzFromfcNEQ_NET + kxxMzzFromfcNEQ_NWB + kxxMzzFromfcNEQ_NWT -
-      kxxMzzFromfcNEQ_SEB - kxxMzzFromfcNEQ_SET + kxxMzzFromfcNEQ_SWB + kxxMzzFromfcNEQ_SWT -
-      c2o1*kxyFromfcNEQ_NEB - c2o1*kxyFromfcNEQ_NET - c2o1*kxyFromfcNEQ_NWB - c2o1*kxyFromfcNEQ_NWT +
-      c2o1*kxyFromfcNEQ_SEB + c2o1*kxyFromfcNEQ_SET + c2o1*kxyFromfcNEQ_SWB + c2o1*kxyFromfcNEQ_SWT +
-      c2o1*kxzFromfcNEQ_NEB - c2o1*kxzFromfcNEQ_NET + c2o1*kxzFromfcNEQ_NWB - c2o1*kxzFromfcNEQ_NWT +
-      c2o1*kxzFromfcNEQ_SEB - c2o1*kxzFromfcNEQ_SET + c2o1*kxzFromfcNEQ_SWB - c2o1*kxzFromfcNEQ_SWT +
-      c8o1*vx1_NEB + c8o1*vx1_NET + c8o1*vx1_NWB + c8o1*vx1_NWT + c8o1*vx1_SEB +
-      c8o1*vx1_SET + c8o1*vx1_SWB + c8o1*vx1_SWT + c2o1*vx2_NEB + c2o1*vx2_NET -
-      c2o1*vx2_NWB - c2o1*vx2_NWT - c2o1*vx2_SEB - c2o1*vx2_SET + c2o1*vx2_SWB +
-      c2o1*vx2_SWT - c2o1*vx3_NEB + c2o1*vx3_NET + c2o1*vx3_NWB - c2o1*vx3_NWT -
-      c2o1*vx3_SEB + c2o1*vx3_SET + c2o1*vx3_SWB - c2o1*vx3_SWT)/c64o1;
-   b0 = (c2o1*kxxMyyFromfcNEQ_NEB + c2o1*kxxMyyFromfcNEQ_NET + c2o1*kxxMyyFromfcNEQ_NWB + c2o1*kxxMyyFromfcNEQ_NWT -
-      c2o1*kxxMyyFromfcNEQ_SEB - c2o1*kxxMyyFromfcNEQ_SET - c2o1*kxxMyyFromfcNEQ_SWB - c2o1*kxxMyyFromfcNEQ_SWT -
-      kxxMzzFromfcNEQ_NEB - kxxMzzFromfcNEQ_NET - kxxMzzFromfcNEQ_NWB - kxxMzzFromfcNEQ_NWT +
-      kxxMzzFromfcNEQ_SEB + kxxMzzFromfcNEQ_SET + kxxMzzFromfcNEQ_SWB + kxxMzzFromfcNEQ_SWT -
-      c2o1*kxyFromfcNEQ_NEB - c2o1*kxyFromfcNEQ_NET + c2o1*kxyFromfcNEQ_NWB + c2o1*kxyFromfcNEQ_NWT -
-      c2o1*kxyFromfcNEQ_SEB - c2o1*kxyFromfcNEQ_SET + c2o1*kxyFromfcNEQ_SWB + c2o1*kxyFromfcNEQ_SWT +
-      c2o1*kyzFromfcNEQ_NEB - c2o1*kyzFromfcNEQ_NET + c2o1*kyzFromfcNEQ_NWB - c2o1*kyzFromfcNEQ_NWT +
-      c2o1*kyzFromfcNEQ_SEB - c2o1*kyzFromfcNEQ_SET + c2o1*kyzFromfcNEQ_SWB - c2o1*kyzFromfcNEQ_SWT +
-      c2o1*vx1_NEB + c2o1*vx1_NET - c2o1*vx1_NWB - c2o1*vx1_NWT -
-      c2o1*vx1_SEB - c2o1*vx1_SET + c2o1*vx1_SWB + c2o1*vx1_SWT +
-      c8o1*vx2_NEB + c8o1*vx2_NET + c8o1*vx2_NWB + c8o1*vx2_NWT +
-      c8o1*vx2_SEB + c8o1*vx2_SET + c8o1*vx2_SWB + c8o1*vx2_SWT -
-      c2o1*vx3_NEB + c2o1*vx3_NET - c2o1*vx3_NWB + c2o1*vx3_NWT +
-      c2o1*vx3_SEB - c2o1*vx3_SET + c2o1*vx3_SWB - c2o1*vx3_SWT)/c64o1;
-   c0 = (kxxMyyFromfcNEQ_NEB - kxxMyyFromfcNEQ_NET + kxxMyyFromfcNEQ_NWB - kxxMyyFromfcNEQ_NWT +
-      kxxMyyFromfcNEQ_SEB - kxxMyyFromfcNEQ_SET + kxxMyyFromfcNEQ_SWB - kxxMyyFromfcNEQ_SWT -
-      c2o1*kxxMzzFromfcNEQ_NEB + c2o1*kxxMzzFromfcNEQ_NET - c2o1*kxxMzzFromfcNEQ_NWB + c2o1*kxxMzzFromfcNEQ_NWT -
-      c2o1*kxxMzzFromfcNEQ_SEB + c2o1*kxxMzzFromfcNEQ_SET - c2o1*kxxMzzFromfcNEQ_SWB + c2o1*kxxMzzFromfcNEQ_SWT -
-      c2o1*kxzFromfcNEQ_NEB - c2o1*kxzFromfcNEQ_NET + c2o1*kxzFromfcNEQ_NWB + c2o1*kxzFromfcNEQ_NWT -
-      c2o1*kxzFromfcNEQ_SEB - c2o1*kxzFromfcNEQ_SET + c2o1*kxzFromfcNEQ_SWB + c2o1*kxzFromfcNEQ_SWT -
-      c2o1*kyzFromfcNEQ_NEB - c2o1*kyzFromfcNEQ_NET - c2o1*kyzFromfcNEQ_NWB - c2o1*kyzFromfcNEQ_NWT +
-      c2o1*kyzFromfcNEQ_SEB + c2o1*kyzFromfcNEQ_SET + c2o1*kyzFromfcNEQ_SWB + c2o1*kyzFromfcNEQ_SWT -
-      c2o1*vx1_NEB + c2o1*vx1_NET + c2o1*vx1_NWB - c2o1*vx1_NWT -
-      c2o1*vx1_SEB + c2o1*vx1_SET + c2o1*vx1_SWB - c2o1*vx1_SWT -
-      c2o1*vx2_NEB + c2o1*vx2_NET - c2o1*vx2_NWB + c2o1*vx2_NWT +
-      c2o1*vx2_SEB - c2o1*vx2_SET + c2o1*vx2_SWB - c2o1*vx2_SWT +
-      c8o1*vx3_NEB + c8o1*vx3_NET + c8o1*vx3_NWB + c8o1*vx3_NWT +
-      c8o1*vx3_SEB + c8o1*vx3_SET + c8o1*vx3_SWB + c8o1*vx3_SWT)/c64o1;
-   ax = (vx1_NEB + vx1_NET - vx1_NWB - vx1_NWT + vx1_SEB + vx1_SET - vx1_SWB - vx1_SWT)/c4o1;
-   bx = (vx2_NEB + vx2_NET - vx2_NWB - vx2_NWT + vx2_SEB + vx2_SET - vx2_SWB - vx2_SWT)/c4o1;
-   cx = (vx3_NEB + vx3_NET - vx3_NWB - vx3_NWT + vx3_SEB + vx3_SET - vx3_SWB - vx3_SWT)/c4o1;
-   axx= (kxxMyyFromfcNEQ_NEB + kxxMyyFromfcNEQ_NET - kxxMyyFromfcNEQ_NWB - kxxMyyFromfcNEQ_NWT +
-      kxxMyyFromfcNEQ_SEB + kxxMyyFromfcNEQ_SET - kxxMyyFromfcNEQ_SWB - kxxMyyFromfcNEQ_SWT +
-      kxxMzzFromfcNEQ_NEB + kxxMzzFromfcNEQ_NET - kxxMzzFromfcNEQ_NWB - kxxMzzFromfcNEQ_NWT +
-      kxxMzzFromfcNEQ_SEB + kxxMzzFromfcNEQ_SET - kxxMzzFromfcNEQ_SWB - kxxMzzFromfcNEQ_SWT +
-      c2o1*vx2_NEB + c2o1*vx2_NET - c2o1*vx2_NWB - c2o1*vx2_NWT -
-      c2o1*vx2_SEB - c2o1*vx2_SET + c2o1*vx2_SWB + c2o1*vx2_SWT -
-      c2o1*vx3_NEB + c2o1*vx3_NET + c2o1*vx3_NWB - c2o1*vx3_NWT -
-      c2o1*vx3_SEB + c2o1*vx3_SET + c2o1*vx3_SWB - c2o1*vx3_SWT)/c16o1;
-   bxx= (kxyFromfcNEQ_NEB + kxyFromfcNEQ_NET - kxyFromfcNEQ_NWB - kxyFromfcNEQ_NWT +
-      kxyFromfcNEQ_SEB + kxyFromfcNEQ_SET - kxyFromfcNEQ_SWB - kxyFromfcNEQ_SWT -
-      c2o1*vx1_NEB - c2o1*vx1_NET + c2o1*vx1_NWB + c2o1*vx1_NWT +
-      c2o1*vx1_SEB + c2o1*vx1_SET - c2o1*vx1_SWB - c2o1*vx1_SWT)/c8o1;
-   cxx= (kxzFromfcNEQ_NEB + kxzFromfcNEQ_NET - kxzFromfcNEQ_NWB - kxzFromfcNEQ_NWT +
-      kxzFromfcNEQ_SEB + kxzFromfcNEQ_SET - kxzFromfcNEQ_SWB - kxzFromfcNEQ_SWT +
-      c2o1*vx1_NEB - c2o1*vx1_NET - c2o1*vx1_NWB + c2o1*vx1_NWT +
-      c2o1*vx1_SEB - c2o1*vx1_SET - c2o1*vx1_SWB + c2o1*vx1_SWT)/c8o1;
-   ay = (vx1_NEB + vx1_NET + vx1_NWB + vx1_NWT - vx1_SEB - vx1_SET - vx1_SWB - vx1_SWT)/c4o1;
-   by = (vx2_NEB + vx2_NET + vx2_NWB + vx2_NWT - vx2_SEB - vx2_SET - vx2_SWB - vx2_SWT)/c4o1;
-   cy = (vx3_NEB + vx3_NET + vx3_NWB + vx3_NWT - vx3_SEB - vx3_SET - vx3_SWB - vx3_SWT)/c4o1;
-   ayy= (kxyFromfcNEQ_NEB + kxyFromfcNEQ_NET + kxyFromfcNEQ_NWB + kxyFromfcNEQ_NWT -
-      kxyFromfcNEQ_SEB - kxyFromfcNEQ_SET - kxyFromfcNEQ_SWB - kxyFromfcNEQ_SWT -
-      c2o1*vx2_NEB - c2o1*vx2_NET + c2o1*vx2_NWB + c2o1*vx2_NWT +
-      c2o1*vx2_SEB + c2o1*vx2_SET - c2o1*vx2_SWB - c2o1*vx2_SWT)/c8o1;
-   byy= (-c2o1*kxxMyyFromfcNEQ_NEB - c2o1*kxxMyyFromfcNEQ_NET - c2o1*kxxMyyFromfcNEQ_NWB - c2o1*kxxMyyFromfcNEQ_NWT +
-      c2o1*kxxMyyFromfcNEQ_SEB + c2o1*kxxMyyFromfcNEQ_SET + c2o1*kxxMyyFromfcNEQ_SWB + c2o1*kxxMyyFromfcNEQ_SWT +
-      kxxMzzFromfcNEQ_NEB + kxxMzzFromfcNEQ_NET + kxxMzzFromfcNEQ_NWB + kxxMzzFromfcNEQ_NWT -
-      kxxMzzFromfcNEQ_SEB - kxxMzzFromfcNEQ_SET - kxxMzzFromfcNEQ_SWB - kxxMzzFromfcNEQ_SWT +
-      c2o1*vx1_NEB + c2o1*vx1_NET - c2o1*vx1_NWB - c2o1*vx1_NWT -
-      c2o1*vx1_SEB - c2o1*vx1_SET + c2o1*vx1_SWB + c2o1*vx1_SWT -
-      c2o1*vx3_NEB + c2o1*vx3_NET - c2o1*vx3_NWB + c2o1*vx3_NWT +
-      c2o1*vx3_SEB - c2o1*vx3_SET + c2o1*vx3_SWB - c2o1*vx3_SWT)/c16o1;
-   cyy= (kyzFromfcNEQ_NEB + kyzFromfcNEQ_NET + kyzFromfcNEQ_NWB + kyzFromfcNEQ_NWT -
-      kyzFromfcNEQ_SEB - kyzFromfcNEQ_SET - kyzFromfcNEQ_SWB - kyzFromfcNEQ_SWT +
-      c2o1*vx2_NEB - c2o1*vx2_NET + c2o1*vx2_NWB - c2o1*vx2_NWT -
-      c2o1*vx2_SEB + c2o1*vx2_SET - c2o1*vx2_SWB + c2o1*vx2_SWT)/c8o1;
-   az = (-vx1_NEB + vx1_NET - vx1_NWB + vx1_NWT - vx1_SEB + vx1_SET - vx1_SWB + vx1_SWT)/c4o1;
-   bz = (-vx2_NEB + vx2_NET - vx2_NWB + vx2_NWT - vx2_SEB + vx2_SET - vx2_SWB + vx2_SWT)/c4o1;
-   cz = (-vx3_NEB + vx3_NET - vx3_NWB + vx3_NWT - vx3_SEB + vx3_SET - vx3_SWB + vx3_SWT)/c4o1;
-   azz= (-kxzFromfcNEQ_NEB + kxzFromfcNEQ_NET - kxzFromfcNEQ_NWB + kxzFromfcNEQ_NWT -
-      kxzFromfcNEQ_SEB + kxzFromfcNEQ_SET - kxzFromfcNEQ_SWB + kxzFromfcNEQ_SWT +
-      c2o1*vx3_NEB - c2o1*vx3_NET - c2o1*vx3_NWB + c2o1*vx3_NWT +
-      c2o1*vx3_SEB - c2o1*vx3_SET - c2o1*vx3_SWB + c2o1*vx3_SWT)/c8o1;
-   bzz= (-kyzFromfcNEQ_NEB + kyzFromfcNEQ_NET - kyzFromfcNEQ_NWB + kyzFromfcNEQ_NWT -
-      kyzFromfcNEQ_SEB + kyzFromfcNEQ_SET - kyzFromfcNEQ_SWB + kyzFromfcNEQ_SWT +
-      c2o1*vx3_NEB - c2o1*vx3_NET + c2o1*vx3_NWB - c2o1*vx3_NWT -
-      c2o1*vx3_SEB + c2o1*vx3_SET - c2o1*vx3_SWB + c2o1*vx3_SWT)/c8o1;
-   czz= (-kxxMyyFromfcNEQ_NEB + kxxMyyFromfcNEQ_NET - kxxMyyFromfcNEQ_NWB + kxxMyyFromfcNEQ_NWT -
-      kxxMyyFromfcNEQ_SEB + kxxMyyFromfcNEQ_SET - kxxMyyFromfcNEQ_SWB + kxxMyyFromfcNEQ_SWT +
-      c2o1*kxxMzzFromfcNEQ_NEB - c2o1*kxxMzzFromfcNEQ_NET + c2o1*kxxMzzFromfcNEQ_NWB - c2o1*kxxMzzFromfcNEQ_NWT +
-      c2o1*kxxMzzFromfcNEQ_SEB - c2o1*kxxMzzFromfcNEQ_SET + c2o1*kxxMzzFromfcNEQ_SWB - c2o1*kxxMzzFromfcNEQ_SWT -
-      c2o1*vx1_NEB + c2o1*vx1_NET + c2o1*vx1_NWB - c2o1*vx1_NWT -
-      c2o1*vx1_SEB + c2o1*vx1_SET + c2o1*vx1_SWB - c2o1*vx1_SWT -
-      c2o1*vx2_NEB + c2o1*vx2_NET - c2o1*vx2_NWB + c2o1*vx2_NWT +
-      c2o1*vx2_SEB - c2o1*vx2_SET + c2o1*vx2_SWB - c2o1*vx2_SWT)/c16o1;
-   axy= (vx1_NEB + vx1_NET - vx1_NWB - vx1_NWT - vx1_SEB - vx1_SET + vx1_SWB + vx1_SWT)/c2o1;
-   bxy= (vx2_NEB + vx2_NET - vx2_NWB - vx2_NWT - vx2_SEB - vx2_SET + vx2_SWB + vx2_SWT)/c2o1;
-   cxy= (vx3_NEB + vx3_NET - vx3_NWB - vx3_NWT - vx3_SEB - vx3_SET + vx3_SWB + vx3_SWT)/c2o1;
-   axz= (-vx1_NEB + vx1_NET + vx1_NWB - vx1_NWT - vx1_SEB + vx1_SET + vx1_SWB - vx1_SWT)/c2o1;
-   bxz= (-vx2_NEB + vx2_NET + vx2_NWB - vx2_NWT - vx2_SEB + vx2_SET + vx2_SWB - vx2_SWT)/c2o1;
-   cxz= (-vx3_NEB + vx3_NET + vx3_NWB - vx3_NWT - vx3_SEB + vx3_SET + vx3_SWB - vx3_SWT)/c2o1;
-   ayz= (-vx1_NEB + vx1_NET - vx1_NWB + vx1_NWT + vx1_SEB - vx1_SET + vx1_SWB - vx1_SWT)/c2o1;
-   byz= (-vx2_NEB + vx2_NET - vx2_NWB + vx2_NWT + vx2_SEB - vx2_SET + vx2_SWB - vx2_SWT)/c2o1;
-   cyz= (-vx3_NEB + vx3_NET - vx3_NWB + vx3_NWT + vx3_SEB - vx3_SET + vx3_SWB - vx3_SWT)/c2o1;
-   axyz=-vx1_NEB + vx1_NET + vx1_NWB - vx1_NWT + vx1_SEB - vx1_SET - vx1_SWB + vx1_SWT;
-   bxyz=-vx2_NEB + vx2_NET + vx2_NWB - vx2_NWT + vx2_SEB - vx2_SET - vx2_SWB + vx2_SWT;
-   cxyz=-vx3_NEB + vx3_NET + vx3_NWB - vx3_NWT + vx3_SEB - vx3_SET - vx3_SWB + vx3_SWT;
-
-
-   //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-   kxyAverage       = c0o1;//(kxyFromfcNEQ_SWB+
-                       //kxyFromfcNEQ_SWT+
-                       //kxyFromfcNEQ_SET+
-                       //kxyFromfcNEQ_SEB+
-                       //kxyFromfcNEQ_NWB+
-                       //kxyFromfcNEQ_NWT+
-                       //kxyFromfcNEQ_NET+
-                       //kxyFromfcNEQ_NEB)*c1o8-(ay+bx);
-   kyzAverage       = c0o1;//(kyzFromfcNEQ_SWB+
-                       //kyzFromfcNEQ_SWT+
-                       //kyzFromfcNEQ_SET+
-                       //kyzFromfcNEQ_SEB+
-                       //kyzFromfcNEQ_NWB+
-                       //kyzFromfcNEQ_NWT+
-                       //kyzFromfcNEQ_NET+
-                       //kyzFromfcNEQ_NEB)*c1o8-(bz+cy);
-   kxzAverage       = c0o1;//(kxzFromfcNEQ_SWB+
-                       //kxzFromfcNEQ_SWT+
-                       //kxzFromfcNEQ_SET+
-                       //kxzFromfcNEQ_SEB+
-                       //kxzFromfcNEQ_NWB+
-                       //kxzFromfcNEQ_NWT+
-                       //kxzFromfcNEQ_NET+
-                       //kxzFromfcNEQ_NEB)*c1o8-(az+cx);
-   kxxMyyAverage    = c0o1;//(kxxMyyFromfcNEQ_SWB+
-                       //kxxMyyFromfcNEQ_SWT+
-                       //kxxMyyFromfcNEQ_SET+
-                       //kxxMyyFromfcNEQ_SEB+
-                       //kxxMyyFromfcNEQ_NWB+
-                       //kxxMyyFromfcNEQ_NWT+
-                       //kxxMyyFromfcNEQ_NET+
-                       //kxxMyyFromfcNEQ_NEB)*c1o8-(ax-by);
-   kxxMzzAverage    = c0o1;//(kxxMzzFromfcNEQ_SWB+
-                       //kxxMzzFromfcNEQ_SWT+
-                       //kxxMzzFromfcNEQ_SET+
-                       //kxxMzzFromfcNEQ_SEB+
-                       //kxxMzzFromfcNEQ_NWB+
-                       //kxxMzzFromfcNEQ_NWT+
-                       //kxxMzzFromfcNEQ_NET+
-                       //kxxMzzFromfcNEQ_NEB)*c1o8-(ax-cz);
-   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-   //
-   // Bernd das Brot
-   //
-   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-   a0 = a0 + xoff * ax + yoff * ay + zoff * az + xoff_sq * axx + yoff_sq * ayy + zoff_sq * azz + xoff*yoff*axy + xoff*zoff*axz + yoff*zoff*ayz + xoff*yoff*zoff*axyz ;
-   ax = ax + c2o1 * xoff * axx + yoff * axy + zoff * axz + yoff*zoff*axyz;
-   ay = ay + c2o1 * yoff * ayy + xoff * axy + zoff * ayz + xoff*zoff*axyz;
-   az = az + c2o1 * zoff * azz + xoff * axz + yoff * ayz + xoff*yoff*axyz;
-   b0 = b0 + xoff * bx + yoff * by + zoff * bz + xoff_sq * bxx + yoff_sq * byy + zoff_sq * bzz + xoff*yoff*bxy + xoff*zoff*bxz + yoff*zoff*byz + xoff*yoff*zoff*bxyz;
-   bx = bx + c2o1 * xoff * bxx + yoff * bxy + zoff * bxz + yoff*zoff*bxyz;
-   by = by + c2o1 * yoff * byy + xoff * bxy + zoff * byz + xoff*zoff*bxyz;
-   bz = bz + c2o1 * zoff * bzz + xoff * bxz + yoff * byz + xoff*yoff*bxyz;
-   c0 = c0 + xoff * cx + yoff * cy + zoff * cz + xoff_sq * cxx + yoff_sq * cyy + zoff_sq * czz + xoff*yoff*cxy + xoff*zoff*cxz + yoff*zoff*cyz + xoff*yoff*zoff*cxyz;
-   cx = cx + c2o1 * xoff * cxx + yoff * cxy + zoff * cxz + yoff*zoff*cxyz;
-   cy = cy + c2o1 * yoff * cyy + xoff * cxy + zoff * cyz + xoff*zoff*cxyz;
-   cz = cz + c2o1 * zoff * czz + xoff * cxz + yoff * cyz + xoff*yoff*cxyz;
-   axy= axy + zoff*axyz;
-   axz= axz + yoff*axyz;
-   ayz= ayz + xoff*axyz;
-   bxy= bxy + zoff*bxyz;
-   bxz= bxz + yoff*bxyz;
-   byz= byz + xoff*bxyz;
-   cxy= cxy + zoff*cxyz;
-   cxz= cxz + yoff*cxyz;
-   cyz= cyz + xoff*cxyz;
-   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-   const real o = omega;
-
-   f_E = eps_new*((c2o1*(-c2o1*ax + by + cz-kxxMzzAverage-kxxMyyAverage))/(c27o1*o));
-   f_N = eps_new*((c2o1*(ax - c2o1*by + cz+c2o1*kxxMyyAverage-kxxMzzAverage))/(c27o1*o));
-   f_T = eps_new*((c2o1*(ax + by - c2o1*cz-kxxMyyAverage+c2o1*kxxMzzAverage))/(c27o1*o));
-   f_NE = eps_new*(-(ax + c3o1*ay + c3o1*bx + by - c2o1*cz+c2o1*kxxMyyAverage-kxxMyyAverage+c3o1*kxyAverage)/(c54o1*o));
-   f_SE = eps_new*(-(ax - c3o1*ay - c3o1*bx + by - c2o1*cz+c2o1*kxxMyyAverage-kxxMyyAverage-c3o1*kxyAverage)/(c54o1*o));
-   f_TE = eps_new*(-(ax + c3o1*az - c2o1*by + c3o1*cx + cz+c2o1*kxxMyyAverage-kxxMzzAverage+c3o1*kxzAverage)/(c54o1*o));
-   f_BE = eps_new*(-(ax - c3o1*az - c2o1*by - c3o1*cx + cz+c2o1*kxxMyyAverage-kxxMzzAverage-c3o1*kxzAverage)/(c54o1*o));
-   f_TN = eps_new*(-(-c2o1*ax + by + c3o1*bz + c3o1*cy + cz-kxxMyyAverage-kxxMzzAverage+c3o1*kyzAverage)/(c54o1*o));
-   f_BN = eps_new*(-(-c2o1*ax + by - c3o1*bz - c3o1*cy + cz-kxxMyyAverage-kxxMzzAverage-c3o1*kyzAverage)/(c54o1*o));
-   f_ZERO = 0.;
-   f_TNE = eps_new*(-(ay + az + bx + bz + cx + cy+kxyAverage+kxzAverage+kyzAverage)/(c72o1*o));
-   f_TSW = eps_new*((-ay + az - bx + bz + cx + cy-kxyAverage+kxzAverage+kyzAverage)/(c72o1*o));
-   f_TSE = eps_new*((ay - az + bx + bz - cx + cy+kxyAverage-kxzAverage+kyzAverage)/(c72o1*o));
-   f_TNW = eps_new*((ay + az + bx - bz + cx - cy+kxyAverage+kxzAverage-kyzAverage)/(c72o1*o));
-
-   x_E = c1o4*eps_new*((c2o1*(-c4o1*axx + bxy + cxz))/(c27o1*o));
-   x_N = c1o4*eps_new*((c2o1*(c2o1*axx - c2o1*bxy + cxz))/(c27o1*o));
-   x_T = c1o4*eps_new*((c2o1*(c2o1*axx + bxy - c2o1*cxz))/(c27o1*o));
-   x_NE = c1o4*eps_new*(-((c2o1*axx + c3o1*axy + c6o1*bxx + bxy - c2o1*cxz))/(c54o1*o));
-   x_SE = c1o4*eps_new*(-((c2o1*axx - c3o1*axy - c6o1*bxx + bxy - c2o1*cxz))/(c54o1*o));
-   x_TE = c1o4*eps_new*(-((c2o1*axx + c3o1*axz - c2o1*bxy + c6o1*cxx + cxz))/(c54o1*o));
-   x_BE = c1o4*eps_new*(-((c2o1*axx - c3o1*axz - c2o1*bxy - c6o1*cxx + cxz))/(c54o1*o));
-   x_TN = c1o4*eps_new*(-((-c4o1*axx + bxy + c3o1*bxz + c3o1*cxy + cxz))/(c54o1*o));
-   x_BN = c1o4*eps_new*(-((-c4o1*axx + bxy - c3o1*bxz - c3o1*cxy + cxz))/(c54o1*o));
-   x_ZERO = c0o1;
-   x_TNE = c1o4*eps_new*(-((axy + axz + c2o1*bxx + bxz + c2o1*cxx + cxy))/(c72o1*o));
-   x_TSW = c1o4*eps_new*(((-axy + axz - c2o1*bxx + bxz + c2o1*cxx + cxy))/(c72o1*o));
-   x_TSE = c1o4*eps_new*(((axy - axz + c2o1*bxx + bxz - c2o1*cxx + cxy))/(c72o1*o));
-   x_TNW = c1o4*eps_new*(((axy + axz + c2o1*bxx - bxz + c2o1*cxx - cxy))/(c72o1*o));
-
-   y_E = c1o4*eps_new*(c2o1*(-c2o1*axy + c2o1*byy + cyz))/(c27o1*o);
-   y_N = c1o4*eps_new*(c2o1*(axy - c4o1*byy + cyz))/(c27o1*o);
-   y_T = c1o4*eps_new*(c2o1*(axy + c2o1*byy - c2o1*cyz))/(c27o1*o);
-   y_NE = c1o4*eps_new*(-((axy + c6o1*ayy + c3o1*bxy + c2o1*byy - c2o1*cyz))/(c54o1*o));
-   y_SE = c1o4*eps_new*(-((axy - c6o1*ayy - c3o1*bxy + c2o1*byy - c2o1*cyz))/(c54o1*o));
-   y_TE = c1o4*eps_new*(-((axy + c3o1*ayz - c4o1*byy + c3o1*cxy + cyz))/(c54o1*o));
-   y_BE = c1o4*eps_new*(-((axy - c3o1*ayz - c4o1*byy - c3o1*cxy + cyz))/(c54o1*o));
-   y_TN = c1o4*eps_new*(-((-c2o1*axy + c2o1*byy + c3o1*byz + c6o1*cyy + cyz))/(c54o1*o));
-   y_BN = c1o4*eps_new*(-((-c2o1*axy + c2o1*byy - c3o1*byz - c6o1*cyy + cyz))/(c54o1*o));
-   y_ZERO = c0o1;
-   y_TNE = c1o4*eps_new*(-((c2o1*ayy + ayz + bxy + byz + cxy + c2o1*cyy))/(c72o1*o));
-   y_TSW = c1o4*eps_new*(((-c2o1*ayy + ayz - bxy + byz + cxy + c2o1*cyy))/(c72o1*o));
-   y_TSE = c1o4*eps_new*(((c2o1*ayy - ayz + bxy + byz - cxy + c2o1*cyy))/(c72o1*o));
-   y_TNW = c1o4*eps_new*(((c2o1*ayy + ayz + bxy - byz + cxy - c2o1*cyy))/(c72o1*o));
-
-   z_E = c1o4*eps_new*((c2o1*(-c2o1*axz + byz + c2o1*czz))/(c27o1*o));
-   z_N = c1o4*eps_new*((c2o1*(axz - c2o1*byz + c2o1*czz))/(c27o1*o));
-   z_T = c1o4*eps_new*((c2o1*(axz + byz - c4o1*czz))/(c27o1*o));
-   z_NE = c1o4*eps_new*(-((axz + c3o1*ayz + c3o1*bxz + byz - c4o1*czz))/(c54o1*o));
-   z_SE = c1o4*eps_new*(-((axz - c3o1*ayz - c3o1*bxz + byz - c4o1*czz))/(c54o1*o));
-   z_TE = c1o4*eps_new*(-((axz + c6o1*azz - c2o1*byz + c3o1*cxz + c2o1*czz))/(c54o1*o));
-   z_BE = c1o4*eps_new*(-((axz - c6o1*azz - c2o1*byz - c3o1*cxz + c2o1*czz))/(c54o1*o));
-   z_TN = c1o4*eps_new*(-((-c2o1*axz + byz + c6o1*bzz + c3o1*cyz + c2o1*czz))/(c54o1*o));
-   z_BN = c1o4*eps_new*(-((-c2o1*axz + byz - c6o1*bzz - c3o1*cyz + c2o1*czz))/(c54o1*o));
-   z_ZERO = c0o1;
-   z_TNE = c1o4*eps_new*(-((ayz + c2o1*azz + bxz + c2o1*bzz + cxz + cyz))/(c72o1*o));
-   z_TSW = c1o4*eps_new*(((-ayz + c2o1*azz - bxz + c2o1*bzz + cxz + cyz))/(c72o1*o));
-   z_TSE = c1o4*eps_new*(((ayz - c2o1*azz + bxz + c2o1*bzz - cxz + cyz))/(c72o1*o));
-   z_TNW = c1o4*eps_new*(((ayz + c2o1*azz + bxz - c2o1*bzz + cxz - cyz))/(c72o1*o));
-
-   xy_E   =   c1o16*eps_new *((                       c2o1*cxyz)/(c27o1*o));
-   xy_N   =   c1o16*eps_new *((                       c2o1*cxyz)/(c27o1*o));
-   xy_T   = -(c1o16*eps_new *((                       c4o1*cxyz)/(c27o1*o)));
-   xy_NE  =   c1o16*eps_new *(                            cxyz /(c27o1*o));
-   xy_SE  =   c1o16*eps_new *(                            cxyz /(c27o1*o));
-   xy_TE  = -(c1o16*eps_new *(( c3o1*axyz            +     cxyz)/(c54o1*o)));
-   xy_BE  = -(c1o16*eps_new *((-c3o1*axyz            +     cxyz)/(c54o1*o)));
-   xy_TN  = -(c1o16*eps_new *((            c3o1*bxyz +     cxyz)/(c54o1*o)));
-   xy_BN  = -(c1o16*eps_new *((          - c3o1*bxyz +     cxyz)/(c54o1*o)));
-   //xy_ZERO=   c1o16*eps_new;
-   xy_TNE = -(c1o16*eps_new *((     axyz +     bxyz           )/(c72o1*o)));
-   xy_TSW =   c1o16*eps_new *((     axyz +     bxyz           )/(c72o1*o));
-   xy_TSE =   c1o16*eps_new *((-    axyz +     bxyz           )/(c72o1*o));
-   xy_TNW =   c1o16*eps_new *((     axyz -     bxyz           )/(c72o1*o));
-
-   xz_E   =   c1o16*eps_new *((            c2o1*bxyz           )/(c27o1*o));
-   xz_N   = -(c1o16*eps_new *((            c4o1*bxyz           )/(c27o1*o)));
-   xz_T   =   c1o16*eps_new *((            c2o1*bxyz           )/(c27o1*o));
-   xz_NE  = -(c1o16*eps_new *(( c3o1*axyz +     bxyz           )/(c54o1*o)));
-   xz_SE  = -(c1o16*eps_new *((-c3o1*axyz +     bxyz           )/(c54o1*o)));
-   xz_TE  =   c1o16*eps_new *((                bxyz           )/(c27o1*o));
-   xz_BE  =   c1o16*eps_new *((                bxyz           )/(c27o1*o));
-   xz_TN  = -(c1o16*eps_new *((                bxyz + c3o1*cxyz)/(c54o1*o)));
-   xz_BN  = -(c1o16*eps_new *((                bxyz - c3o1*cxyz)/(c54o1*o)));
-   //xz_ZERO=   c1o16*eps_new;
-   xz_TNE = -(c1o16*eps_new *((     axyz            +     cxyz)/(c72o1*o)));
-   xz_TSW =   c1o16*eps_new *((-    axyz            +     cxyz)/(c72o1*o));
-   xz_TSE =   c1o16*eps_new *((     axyz            +     cxyz)/(c72o1*o));
-   xz_TNW =   c1o16*eps_new *((     axyz            -     cxyz)/(c72o1*o));
-
-   yz_E   = -(c1o16*eps_new *(( c4o1*axyz                      )/(c27o1*o)));
-   yz_N   =   c1o16*eps_new *(( c2o1*axyz                      )/(c27o1*o));
-   yz_T   =   c1o16*eps_new *(( c2o1*axyz                      )/(c27o1*o));
-   yz_NE  = -(c1o16*eps_new *((     axyz + c3o1*bxyz           )/(c54o1*o)));
-   yz_SE  = -(c1o16*eps_new *((     axyz - c3o1*bxyz           )/(c54o1*o)));
-   yz_TE  = -(c1o16*eps_new *((     axyz            + c3o1*cxyz)/(c54o1*o)));
-   yz_BE  = -(c1o16*eps_new *((     axyz            - c3o1*cxyz)/(c54o1*o)));
-   yz_TN  =   c1o16*eps_new *((     axyz                      )/(c27o1*o));
-   yz_BN  =   c1o16*eps_new *((     axyz                      )/(c27o1*o));
-   //yz_ZERO=   c1o16*eps_new;
-   yz_TNE = -(c1o16*eps_new *((                bxyz +     cxyz)/(c72o1*o)));
-   yz_TSW =   c1o16*eps_new *((          -     bxyz +     cxyz)/(c72o1*o));
-   yz_TSE =   c1o16*eps_new *((                bxyz -     cxyz)/(c72o1*o));
-   yz_TNW =   c1o16*eps_new *((                bxyz +     cxyz)/(c72o1*o));
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedNodeCF(real* f, real omega, real x, real y, real z, real press, real xs, real ys, real zs)
-{
-   using namespace D3Q27System;
-   using namespace vf::lbm::dir;
-   using namespace vf::basics::constant;
-
-   real eps_new = c1o2;
-   real o = omega;
-   //bulk viscosity
-   real oP = OxxPyyPzzF;
-
-//   LBMReal rho  = press ;//+ (c2o1*axx*x+axy*y+axz*z+axyz*y*z+ax + c2o1*byy*y+bxy*x+byz*z+bxyz*x*z+by + c2o1*czz*z+cxz*x+cyz*y+cxyz*x*y+cz)/c3o1;
-   real vx1  = a0 + c1o4*( xs*ax + ys*ay + zs*az) + c1o16*(axx + xs*ys*axy + xs*zs*axz + ayy + ys*zs*ayz + azz) + c1o64*(xs*ys*zs*axyz);
-   real vx2  = b0 + c1o4*( xs*bx + ys*by + zs*bz) + c1o16*(bxx + xs*ys*bxy + xs*zs*bxz + byy + ys*zs*byz + bzz) + c1o64*(xs*ys*zs*bxyz);
-   real vx3  = c0 + c1o4*( xs*cx + ys*cy + zs*cz) + c1o16*(cxx + xs*ys*cxy + xs*zs*cxz + cyy + ys*zs*cyz + czz) + c1o64*(xs*ys*zs*cxyz);
-
-   real mfcbb = c0o1;
-   real mfabb = c0o1;
-   real mfbcb = c0o1;
-   real mfbab = c0o1;
-   real mfbbc = c0o1;
-   real mfbba = c0o1;
-   real mfccb = c0o1;
-   real mfaab = c0o1;
-   real mfcab = c0o1;
-   real mfacb = c0o1;
-   real mfcbc = c0o1;
-   real mfaba = c0o1;
-   real mfcba = c0o1;
-   real mfabc = c0o1;
-   real mfbcc = c0o1;
-   real mfbaa = c0o1;
-   real mfbca = c0o1;
-   real mfbac = c0o1;
-   real mfbbb = c0o1;
-   real mfccc = c0o1;
-   real mfaac = c0o1;
-   real mfcac = c0o1;
-   real mfacc = c0o1;
-   real mfcca = c0o1;
-   real mfaaa = c0o1;
-   real mfcaa = c0o1;
-   real mfaca = c0o1;
-
-   mfaaa = press; // if drho is interpolated directly
-
-   real vx1Sq = vx1*vx1;
-   real vx2Sq = vx2*vx2;
-   real vx3Sq = vx3*vx3;
-   real oMdrho = c1o1;
-
-   //c2o1f
-
-   // linear combinations
-   real mxxPyyPzz = mfaaa - c2o3*(ax + by + c2o1 *axx*x + bxy*x + axy*y + c2o1 *byy*y + axz*z + byz*z + bxyz*x*z + axyz*y*z + cz - cxz*x + cyz*y + cxyz*x*y + c2o1 *czz*z)*eps_new / oP* (c1o1 + press);
-   real mxxMyy    = -c2o3*(ax - by + kxxMyyAverage + c2o1 *axx*x - bxy*x + axy*y - c2o1 *byy*y + axz*z - byz*z - bxyz*x*z + axyz*y*z)*eps_new/o * (c1o1 + press);
-   real mxxMzz    = -c2o3*(ax - cz + kxxMzzAverage + c2o1 *axx*x - cxz*x + axy*y - cyz*y - cxyz*x*y + axz*z - c2o1 *czz*z + axyz*y*z)*eps_new/o * (c1o1 + press);
-
-   mfabb     = -c1o3 * (bz + cy + kyzAverage + bxz*x + cxy*x + byz*y + c2o1 *cyy*y + bxyz*x*y + c2o1 *bzz*z + cyz*z + cxyz*x*z)*eps_new/o * (c1o1 + press);
-   mfbab     = -c1o3 * (az + cx + kxzAverage + axz*x + c2o1 *cxx*x + ayz*y + cxy*y + axyz*x*y + c2o1 *azz*z + cxz*z + cxyz*y*z)*eps_new/o * (c1o1 + press);
-   mfbba     = -c1o3 * (ay + bx + kxyAverage + axy*x + c2o1 *bxx*x + c2o1 *ayy*y + bxy*y + ayz*z + bxz*z + axyz*x*z + bxyz*y*z)*eps_new/o * (c1o1 + press);
-
-   // linear combinations back
-   mfcaa = c1o3 * (mxxMyy +       mxxMzz + mxxPyyPzz) ;
-   mfaca = c1o3 * (-c2o1 * mxxMyy +       mxxMzz + mxxPyyPzz) ;
-   mfaac = c1o3 * (mxxMyy - c2o1 * mxxMzz + mxxPyyPzz) ;
-
-   //three
-   mfbbb = c0o1;
-   real mxxyPyzz = c0o1;
-   real mxxyMyzz = c0o1;
-   real mxxzPyyz = c0o1;
-   real mxxzMyyz = c0o1;
-   real mxyyPxzz = c0o1;
-   real mxyyMxzz = c0o1;
-
-   // linear combinations back
-   mfcba = (mxxyMyzz + mxxyPyzz) * c1o2;
-   mfabc = (-mxxyMyzz + mxxyPyzz) * c1o2;
-   mfcab = (mxxzMyyz + mxxzPyyz) * c1o2;
-   mfacb = (-mxxzMyyz + mxxzPyyz) * c1o2;
-   mfbca = (mxyyMxzz + mxyyPxzz) * c1o2;
-   mfbac = (-mxyyMxzz + mxyyPxzz) * c1o2;
-
-   //4.f
-   mfacc = mfaaa*c1o9;
-   mfcac = mfacc;
-   mfcca = mfacc;
-
-   //5.
-
-   //6.
-
-   mfccc = mfaaa*c1o27;
-   ////////////////////////////////////////////////////////////////////////////////////
-   //back
-   ////////////////////////////////////////////////////////////////////////////////////
-   //mit 1, 0, 1/3, 0, 0, 0, 1/3, 0, 1/9   Konditionieren
-   ////////////////////////////////////////////////////////////////////////////////////
-   // Z - Dir
-   real m0 =  mfaac * c1o2 +      mfaab * (vx3 - c1o2) + (mfaaa + c1o1 * oMdrho) * (vx3Sq - vx3) * c1o2;
-   real m1 = -mfaac        - c2o1 * mfaab *  vx3         +  mfaaa                * (c1o1 - vx3Sq)              - c1o1 * oMdrho * vx3Sq;
-   real m2 =  mfaac * c1o2 +      mfaab * (vx3 + c1o2) + (mfaaa + c1o1 * oMdrho) * (vx3Sq + vx3) * c1o2;
-   mfaaa = m0;
-   mfaab = m1;
-   mfaac = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfabc * c1o2 +      mfabb * (vx3 - c1o2) + mfaba * (vx3Sq - vx3) * c1o2;
-   m1 = -mfabc        - c2o1 * mfabb *  vx3         + mfaba * (c1o1 - vx3Sq);
-   m2 =  mfabc * c1o2 +      mfabb * (vx3 + c1o2) + mfaba * (vx3Sq + vx3) * c1o2;
-   mfaba = m0;
-   mfabb = m1;
-   mfabc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfacc * c1o2 +      mfacb * (vx3 - c1o2) + (mfaca + c1o3 * oMdrho) * (vx3Sq - vx3) * c1o2;
-   m1 = -mfacc        - c2o1 * mfacb *  vx3         +  mfaca                  * (c1o1 - vx3Sq)              - c1o3 * oMdrho * vx3Sq;
-   m2 =  mfacc * c1o2 +      mfacb * (vx3 + c1o2) + (mfaca + c1o3 * oMdrho) * (vx3Sq + vx3) * c1o2;
-   mfaca = m0;
-   mfacb = m1;
-   mfacc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfbac * c1o2 +      mfbab * (vx3 - c1o2) + mfbaa * (vx3Sq - vx3) * c1o2;
-   m1 = -mfbac        - c2o1 * mfbab *  vx3         + mfbaa * (c1o1 - vx3Sq);
-   m2 =  mfbac * c1o2 +      mfbab * (vx3 + c1o2) + mfbaa * (vx3Sq + vx3) * c1o2;
-   mfbaa = m0;
-   mfbab = m1;
-   mfbac = m2;
-   /////////b//////////////////////////////////////////////////////////////////////////
-   m0 =  mfbbc * c1o2 +      mfbbb * (vx3 - c1o2) + mfbba * (vx3Sq - vx3) * c1o2;
-   m1 = -mfbbc        - c2o1 * mfbbb *  vx3         + mfbba * (c1o1 - vx3Sq);
-   m2 =  mfbbc * c1o2 +      mfbbb * (vx3 + c1o2) + mfbba * (vx3Sq + vx3) * c1o2;
-   mfbba = m0;
-   mfbbb = m1;
-   mfbbc = m2;
-   /////////b//////////////////////////////////////////////////////////////////////////
-   m0 =  mfbcc * c1o2 +      mfbcb * (vx3 - c1o2) + mfbca * (vx3Sq - vx3) * c1o2;
-   m1 = -mfbcc        - c2o1 * mfbcb *  vx3         + mfbca * (c1o1 - vx3Sq);
-   m2 =  mfbcc * c1o2 +      mfbcb * (vx3 + c1o2) + mfbca * (vx3Sq + vx3) * c1o2;
-   mfbca = m0;
-   mfbcb = m1;
-   mfbcc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcac * c1o2 +      mfcab * (vx3 - c1o2) + (mfcaa + c1o3 * oMdrho) * (vx3Sq - vx3) * c1o2;
-   m1 = -mfcac        - c2o1 * mfcab *  vx3         +  mfcaa                  * (c1o1 - vx3Sq)              - c1o3 * oMdrho * vx3Sq;
-   m2 =  mfcac * c1o2 +      mfcab * (vx3 + c1o2) + (mfcaa + c1o3 * oMdrho) * (vx3Sq + vx3) * c1o2;
-   mfcaa = m0;
-   mfcab = m1;
-   mfcac = m2;
-   /////////c//////////////////////////////////////////////////////////////////////////
-   m0 =  mfcbc * c1o2 +      mfcbb * (vx3 - c1o2) + mfcba * (vx3Sq - vx3) * c1o2;
-   m1 = -mfcbc        - c2o1 * mfcbb *  vx3         + mfcba * (c1o1 - vx3Sq);
-   m2 =  mfcbc * c1o2 +      mfcbb * (vx3 + c1o2) + mfcba * (vx3Sq + vx3) * c1o2;
-   mfcba = m0;
-   mfcbb = m1;
-   mfcbc = m2;
-   /////////c//////////////////////////////////////////////////////////////////////////
-   m0 =  mfccc * c1o2 +      mfccb * (vx3 - c1o2) + (mfcca + c1o9 * oMdrho) * (vx3Sq - vx3) * c1o2;
-   m1 = -mfccc        - c2o1 * mfccb *  vx3         +  mfcca                  * (c1o1 - vx3Sq)              - c1o9 * oMdrho * vx3Sq;
-   m2 =  mfccc * c1o2 +      mfccb * (vx3 + c1o2) + (mfcca + c1o9 * oMdrho) * (vx3Sq + vx3) * c1o2;
-   mfcca = m0;
-   mfccb = m1;
-   mfccc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   //mit 1/6, 2/3, 1/6, 0, 0, 0, 1/18, 2/9, 1/18   Konditionieren
-   ////////////////////////////////////////////////////////////////////////////////////
-   // Y - Dir
-   m0 =  mfaca * c1o2 +      mfaba * (vx2 - c1o2) + (mfaaa + c1o6 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfaca        - c2o1 * mfaba *  vx2         +  mfaaa                  * (c1o1 - vx2Sq)              - c1o6 * oMdrho * vx2Sq;
-   m2 =  mfaca * c1o2 +      mfaba * (vx2 + c1o2) + (mfaaa + c1o6 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfaaa = m0;
-   mfaba = m1;
-   mfaca = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfacb * c1o2 +      mfabb * (vx2 - c1o2) + (mfaab + c2o3 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfacb        - c2o1 * mfabb *  vx2         +  mfaab                  * (c1o1 - vx2Sq)              - c2o3 * oMdrho * vx2Sq;
-   m2 =  mfacb * c1o2 +      mfabb * (vx2 + c1o2) + (mfaab + c2o3 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfaab = m0;
-   mfabb = m1;
-   mfacb = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfacc * c1o2 +      mfabc * (vx2 - c1o2) + (mfaac + c1o6 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfacc        - c2o1 * mfabc *  vx2         +  mfaac                  * (c1o1 - vx2Sq)              - c1o6 * oMdrho * vx2Sq;
-   m2 =  mfacc * c1o2 +      mfabc * (vx2 + c1o2) + (mfaac + c1o6 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfaac = m0;
-   mfabc = m1;
-   mfacc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfbca * c1o2 +      mfbba * (vx2 - c1o2) + mfbaa * (vx2Sq - vx2) * c1o2;
-   m1 = -mfbca        - c2o1 * mfbba *  vx2         + mfbaa * (c1o1 - vx2Sq);
-   m2 =  mfbca * c1o2 +      mfbba * (vx2 + c1o2) + mfbaa * (vx2Sq + vx2) * c1o2;
-   mfbaa = m0;
-   mfbba = m1;
-   mfbca = m2;
-   /////////b//////////////////////////////////////////////////////////////////////////
-   m0 =  mfbcb * c1o2 +      mfbbb * (vx2 - c1o2) + mfbab * (vx2Sq - vx2) * c1o2;
-   m1 = -mfbcb        - c2o1 * mfbbb *  vx2         + mfbab * (c1o1 - vx2Sq);
-   m2 =  mfbcb * c1o2 +      mfbbb * (vx2 + c1o2) + mfbab * (vx2Sq + vx2) * c1o2;
-   mfbab = m0;
-   mfbbb = m1;
-   mfbcb = m2;
-   /////////b//////////////////////////////////////////////////////////////////////////
-   m0 =  mfbcc * c1o2 +      mfbbc * (vx2 - c1o2) + mfbac * (vx2Sq - vx2) * c1o2;
-   m1 = -mfbcc        - c2o1 * mfbbc *  vx2         + mfbac * (c1o1 - vx2Sq);
-   m2 =  mfbcc * c1o2 +      mfbbc * (vx2 + c1o2) + mfbac * (vx2Sq + vx2) * c1o2;
-   mfbac = m0;
-   mfbbc = m1;
-   mfbcc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcca * c1o2 +      mfcba * (vx2 - c1o2) + (mfcaa + c1o18 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfcca        - c2o1 * mfcba *  vx2         +  mfcaa                   * (c1o1 - vx2Sq)              - c1o18 * oMdrho * vx2Sq;
-   m2 =  mfcca * c1o2 +      mfcba * (vx2 + c1o2) + (mfcaa + c1o18 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfcaa = m0;
-   mfcba = m1;
-   mfcca = m2;
-   /////////c//////////////////////////////////////////////////////////////////////////
-   m0 =  mfccb * c1o2 +      mfcbb * (vx2 - c1o2) + (mfcab + c2o9 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfccb        - c2o1 * mfcbb *  vx2         +  mfcab                  * (c1o1 - vx2Sq)              - c2o9 * oMdrho * vx2Sq;
-   m2 =  mfccb * c1o2 +      mfcbb * (vx2 + c1o2) + (mfcab + c2o9 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfcab = m0;
-   mfcbb = m1;
-   mfccb = m2;
-   /////////c//////////////////////////////////////////////////////////////////////////
-   m0 =  mfccc * c1o2 +      mfcbc * (vx2 - c1o2) + (mfcac + c1o18 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfccc        - c2o1 * mfcbc *  vx2         +  mfcac                   * (c1o1 - vx2Sq)              - c1o18 * oMdrho * vx2Sq;
-   m2 =  mfccc * c1o2 +      mfcbc * (vx2 + c1o2) + (mfcac + c1o18 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfcac = m0;
-   mfcbc = m1;
-   mfccc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   //mit 1/36, 1/9, 1/36, 1/9, 4/9, 1/9, 1/36, 1/9, 1/36 Konditionieren
-   ////////////////////////////////////////////////////////////////////////////////////
-   // X - Dir
-   m0 =  mfcaa * c1o2 +      mfbaa * (vx1 - c1o2) + (mfaaa + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcaa        - c2o1 * mfbaa *  vx1         +  mfaaa                   * (c1o1 - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
-   m2 =  mfcaa * c1o2 +      mfbaa * (vx1 + c1o2) + (mfaaa + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfaaa = m0;
-   mfbaa = m1;
-   mfcaa = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcba * c1o2 +      mfbba * (vx1 - c1o2) + (mfaba + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcba        - c2o1 * mfbba *  vx1         +  mfaba                  * (c1o1 - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
-   m2 =  mfcba * c1o2 +      mfbba * (vx1 + c1o2) + (mfaba + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfaba = m0;
-   mfbba = m1;
-   mfcba = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcca * c1o2 +      mfbca * (vx1 - c1o2) + (mfaca + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcca        - c2o1 * mfbca *  vx1         +  mfaca                   * (c1o1 - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
-   m2 =  mfcca * c1o2 +      mfbca * (vx1 + c1o2) + (mfaca + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfaca = m0;
-   mfbca = m1;
-   mfcca = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcab * c1o2 +      mfbab * (vx1 - c1o2) + (mfaab + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcab        - c2o1 * mfbab *  vx1         +  mfaab                  * (c1o1 - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
-   m2 =  mfcab * c1o2 +      mfbab * (vx1 + c1o2) + (mfaab + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfaab = m0;
-   mfbab = m1;
-   mfcab = m2;
-   ///////////b////////////////////////////////////////////////////////////////////////
-   m0 =  mfcbb * c1o2 +      mfbbb * (vx1 - c1o2) + (mfabb + c4o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcbb        - c2o1 * mfbbb *  vx1         +  mfabb                  * (c1o1 - vx1Sq)              - c4o9 * oMdrho * vx1Sq;
-   m2 =  mfcbb * c1o2 +      mfbbb * (vx1 + c1o2) + (mfabb + c4o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfabb = m0;
-   mfbbb = m1;
-   mfcbb = m2;
-   ///////////b////////////////////////////////////////////////////////////////////////
-   m0 =  mfccb * c1o2 +      mfbcb * (vx1 - c1o2) + (mfacb + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfccb        - c2o1 * mfbcb *  vx1         +  mfacb                  * (c1o1 - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
-   m2 =  mfccb * c1o2 +      mfbcb * (vx1 + c1o2) + (mfacb + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfacb = m0;
-   mfbcb = m1;
-   mfccb = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcac * c1o2 +      mfbac * (vx1 - c1o2) + (mfaac + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcac        - c2o1 * mfbac *  vx1         +  mfaac                   * (c1o1 - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
-   m2 =  mfcac * c1o2 +      mfbac * (vx1 + c1o2) + (mfaac + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfaac = m0;
-   mfbac = m1;
-   mfcac = m2;
-   ///////////c////////////////////////////////////////////////////////////////////////
-   m0 =  mfcbc * c1o2 +      mfbbc * (vx1 - c1o2) + (mfabc + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcbc        - c2o1 * mfbbc *  vx1         +  mfabc                  * (c1o1 - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
-   m2 =  mfcbc * c1o2 +      mfbbc * (vx1 + c1o2) + (mfabc + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfabc = m0;
-   mfbbc = m1;
-   mfcbc = m2;
-   ///////////c////////////////////////////////////////////////////////////////////////
-   m0 =  mfccc * c1o2 +      mfbcc * (vx1 - c1o2) + (mfacc + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfccc        - c2o1 * mfbcc *  vx1         +  mfacc                   * (c1o1 - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
-   m2 =  mfccc * c1o2 +      mfbcc * (vx1 + c1o2) + (mfacc + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfacc = m0;
-   mfbcc = m1;
-   mfccc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-
-   f[DIR_P00] = mfcbb;
-   f[DIR_M00] = mfabb;
-   f[DIR_0P0] = mfbcb;
-   f[DIR_0M0] = mfbab;
-   f[DIR_00P] = mfbbc;
-   f[DIR_00M] = mfbba;
-   f[DIR_PP0] = mfccb;
-   f[DIR_MM0] = mfaab;
-   f[DIR_PM0] = mfcab;
-   f[DIR_MP0] = mfacb;
-   f[DIR_P0P] = mfcbc;
-   f[DIR_M0M] = mfaba;
-   f[DIR_P0M] = mfcba;
-   f[DIR_M0P] = mfabc;
-   f[DIR_0PP] = mfbcc;
-   f[DIR_0MM] = mfbaa;
-   f[DIR_0PM] = mfbca;
-   f[DIR_0MP] = mfbac;
-   f[DIR_000] = mfbbb;
-   f[DIR_PPP] = mfccc;
-   f[DIR_PMP] = mfcac;
-   f[DIR_PPM] = mfcca;
-   f[DIR_PMM] = mfcaa;
-   f[DIR_MPP] = mfacc;
-   f[DIR_MMP] = mfaac;
-   f[DIR_MPM] = mfaca;
-   f[DIR_MMM] = mfaaa;
-}
-//////////////////////////////////////////////////////////////////////////
-//Position SWB -0.25, -0.25, -0.25
-real CompressibleOffsetMomentsInterpolationProcessor::calcPressBSW()
-{
-   return   press_SWT * (c9o64 + c3o16 * xoff + c3o16 * yoff - c9o16 * zoff) +
-      press_NWT * (c3o64 + c1o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
-      press_SET * (c3o64 - c3o16 * xoff + c1o16 * yoff - c3o16 * zoff) +
-      press_NET * (c1o64 - c1o16 * xoff - c1o16 * yoff - c1o16 * zoff) +
-      press_NEB * (c3o64 - c3o16 * xoff - c3o16 * yoff + c1o16 * zoff) +
-      press_NWB * (c9o64 + c3o16 * xoff - c9o16 * yoff + c3o16 * zoff) +
-      press_SEB * (c9o64 - c9o16 * xoff + c3o16 * yoff + c3o16 * zoff) +
-      press_SWB * (c27o64 + c9o16 * xoff + c9o16 * yoff + c9o16 * zoff);
-}
-//////////////////////////////////////////////////////////////////////////
-//Position SWT -0.25, -0.25, 0.25
-real CompressibleOffsetMomentsInterpolationProcessor::calcPressTSW()
-{
-   return   press_SWT * (c27o64 + c9o16 * xoff + c9o16 * yoff - c9o16 * zoff) +
-      press_NWT * (c9o64 + c3o16 * xoff - c9o16 * yoff - c3o16 * zoff) +
-      press_SET * (c9o64 - c9o16 * xoff + c3o16 * yoff - c3o16 * zoff) +
-      press_NET * (c3o64 - c3o16 * xoff - c3o16 * yoff - c1o16 * zoff) +
-      press_NEB * (c1o64 - c1o16 * xoff - c1o16 * yoff + c1o16 * zoff) +
-      press_NWB * (c3o64 + c1o16 * xoff - c3o16 * yoff + c3o16 * zoff) +
-      press_SEB * (c3o64 - c3o16 * xoff + c1o16 * yoff + c3o16 * zoff) +
-      press_SWB * (c9o64 + c3o16 * xoff + c3o16 * yoff + c9o16 * zoff);
-}
-//////////////////////////////////////////////////////////////////////////
-//Position SET 0.25, -0.25, 0.25
-real CompressibleOffsetMomentsInterpolationProcessor::calcPressTSE()
-{
-   return   press_SET * (c27o64 - c9o16 * xoff + c9o16 * yoff - c9o16 * zoff) +
-      press_NET * (c9o64 - c3o16 * xoff - c9o16 * yoff - c3o16 * zoff) +
-      press_SWT * (c9o64 + c9o16 * xoff + c3o16 * yoff - c3o16 * zoff) +
-      press_NWT * (c3o64 + c3o16 * xoff - c3o16 * yoff - c1o16 * zoff) +
-      press_NWB * (c1o64 + c1o16 * xoff - c1o16 * yoff + c1o16 * zoff) +
-      press_NEB * (c3o64 - c1o16 * xoff - c3o16 * yoff + c3o16 * zoff) +
-      press_SWB * (c3o64 + c3o16 * xoff + c1o16 * yoff + c3o16 * zoff) +
-      press_SEB * (c9o64 - c3o16 * xoff + c3o16 * yoff + c9o16 * zoff);
-}
-//////////////////////////////////////////////////////////////////////////
-//Position SEB 0.25, -0.25, -0.25
-real CompressibleOffsetMomentsInterpolationProcessor::calcPressBSE()
-{
-   return   press_SET * (c9o64 - c3o16 * xoff + c3o16 * yoff - c9o16 * zoff) +
-      press_NET * (c3o64 - c1o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
-      press_SWT * (c3o64 + c3o16 * xoff + c1o16 * yoff - c3o16 * zoff) +
-      press_NWT * (c1o64 + c1o16 * xoff - c1o16 * yoff - c1o16 * zoff) +
-      press_NWB * (c3o64 + c3o16 * xoff - c3o16 * yoff + c1o16 * zoff) +
-      press_NEB * (c9o64 - c3o16 * xoff - c9o16 * yoff + c3o16 * zoff) +
-      press_SWB * (c9o64 + c9o16 * xoff + c3o16 * yoff + c3o16 * zoff) +
-      press_SEB * (c27o64 - c9o16 * xoff + c9o16 * yoff + c9o16 * zoff);
-}
-//////////////////////////////////////////////////////////////////////////
-//Position NWB -0.25, 0.25, -0.25
-real CompressibleOffsetMomentsInterpolationProcessor::calcPressBNW()
-{
-   return   press_NWT * (c9o64 + c3o16 * xoff - c3o16 * yoff - c9o16 * zoff) +
-      press_NET * (c3o64 - c3o16 * xoff - c1o16 * yoff - c3o16 * zoff) +
-      press_SWT * (c3o64 + c1o16 * xoff + c3o16 * yoff - c3o16 * zoff) +
-      press_SET * (c1o64 - c1o16 * xoff + c1o16 * yoff - c1o16 * zoff) +
-      press_SEB * (c3o64 - c3o16 * xoff + c3o16 * yoff + c1o16 * zoff) +
-      press_NEB * (c9o64 - c9o16 * xoff - c3o16 * yoff + c3o16 * zoff) +
-      press_SWB * (c9o64 + c3o16 * xoff + c9o16 * yoff + c3o16 * zoff) +
-      press_NWB * (c27o64 + c9o16 * xoff - c9o16 * yoff + c9o16 * zoff);
-}
-//////////////////////////////////////////////////////////////////////////
-//Position NWT -0.25, 0.25, 0.25
-real CompressibleOffsetMomentsInterpolationProcessor::calcPressTNW()
-{
-   return   press_NWT * (c27o64 + c9o16 * xoff - c9o16 * yoff - c9o16 * zoff) +
-      press_NET * (c9o64 - c9o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
-      press_SWT * (c9o64 + c3o16 * xoff + c9o16 * yoff - c3o16 * zoff) +
-      press_SET * (c3o64 - c3o16 * xoff + c3o16 * yoff - c1o16 * zoff) +
-      press_SEB * (c1o64 - c1o16 * xoff + c1o16 * yoff + c1o16 * zoff) +
-      press_NEB * (c3o64 - c3o16 * xoff - c1o16 * yoff + c3o16 * zoff) +
-      press_SWB * (c3o64 + c1o16 * xoff + c3o16 * yoff + c3o16 * zoff) +
-      press_NWB * (c9o64 + c3o16 * xoff - c3o16 * yoff + c9o16 * zoff);
-}
-//////////////////////////////////////////////////////////////////////////
-//Position NET 0.25, 0.25, 0.25
-real CompressibleOffsetMomentsInterpolationProcessor::calcPressTNE()
-{
-   return   press_NET * (c27o64 - c9o16 * xoff - c9o16 * yoff - c9o16 * zoff) +
-      press_NWT * (c9o64 + c9o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
-      press_SET * (c9o64 - c3o16 * xoff + c9o16 * yoff - c3o16 * zoff) +
-      press_SWT * (c3o64 + c3o16 * xoff + c3o16 * yoff - c1o16 * zoff) +
-      press_SWB * (c1o64 + c1o16 * xoff + c1o16 * yoff + c1o16 * zoff) +
-      press_NWB * (c3o64 + c3o16 * xoff - c1o16 * yoff + c3o16 * zoff) +
-      press_SEB * (c3o64 - c1o16 * xoff + c3o16 * yoff + c3o16 * zoff) +
-      press_NEB * (c9o64 - c3o16 * xoff - c3o16 * yoff + c9o16 * zoff);
-}
-//////////////////////////////////////////////////////////////////////////
-//Position NEB 0.25, 0.25, -0.25
-real CompressibleOffsetMomentsInterpolationProcessor::calcPressBNE()
-{
-   return   press_NET * (c9o64 - c3o16 * xoff - c3o16 * yoff - c9o16 * zoff) +
-      press_NWT * (c3o64 + c3o16 * xoff - c1o16 * yoff - c3o16 * zoff) +
-      press_SET * (c3o64 - c1o16 * xoff + c3o16 * yoff - c3o16 * zoff) +
-      press_SWT * (c1o64 + c1o16 * xoff + c1o16 * yoff - c1o16 * zoff) +
-      press_SWB * (c3o64 + c3o16 * xoff + c3o16 * yoff + c1o16 * zoff) +
-      press_NWB * (c9o64 + c9o16 * xoff - c3o16 * yoff + c3o16 * zoff) +
-      press_SEB * (c9o64 - c3o16 * xoff + c9o16 * yoff + c3o16 * zoff) +
-      press_NEB * (c27o64 - c9o16 * xoff - c9o16 * yoff + c9o16 * zoff);
-}
-//////////////////////////////////////////////////////////////////////////
-//Position C 0.0, 0.0, 0.0
-void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedNodeFC(real* f, real omega)
-{
-   using namespace D3Q27System;
-   using namespace vf::lbm::dir;
-
-   real press  =  press_NET * (c4o32 - c1o4 * xoff - c1o4 * yoff - c1o4 * zoff) +
-      press_NWT * (c4o32 + c1o4 * xoff - c1o4 * yoff - c1o4 * zoff) +
-      press_SET * (c4o32 - c1o4 * xoff + c1o4 * yoff - c1o4 * zoff) +
-      press_SWT * (c4o32 + c1o4 * xoff + c1o4 * yoff - c1o4 * zoff) +
-      press_NEB * (c4o32 - c1o4 * xoff - c1o4 * yoff + c1o4 * zoff) +
-      press_NWB * (c4o32 + c1o4 * xoff - c1o4 * yoff + c1o4 * zoff) +
-      press_SEB * (c4o32 - c1o4 * xoff + c1o4 * yoff + c1o4 * zoff) +
-      press_SWB * (c4o32 + c1o4 * xoff + c1o4 * yoff + c1o4 * zoff);
-   real vx1  = a0;
-   real vx2  = b0;
-   real vx3  = c0;
-
-//   LBMReal rho = press ;//+ (ax+by+cz)/c3o1;
-
-   real eps_new = c2o1;
-   real o  = omega;
-   //bulk viscosity
-   real oP = OxxPyyPzzC;
-
-   real mfcbb = c0o1;
-   real mfabb = c0o1;
-   real mfbcb = c0o1;
-   real mfbab = c0o1;
-   real mfbbc = c0o1;
-   real mfbba = c0o1;
-   real mfccb = c0o1;
-   real mfaab = c0o1;
-   real mfcab = c0o1;
-   real mfacb = c0o1;
-   real mfcbc = c0o1;
-   real mfaba = c0o1;
-   real mfcba = c0o1;
-   real mfabc = c0o1;
-   real mfbcc = c0o1;
-   real mfbaa = c0o1;
-   real mfbca = c0o1;
-   real mfbac = c0o1;
-   real mfbbb = c0o1;
-   real mfccc = c0o1;
-   real mfaac = c0o1;
-   real mfcac = c0o1;
-   real mfacc = c0o1;
-   real mfcca = c0o1;
-   real mfaaa = c0o1;
-   real mfcaa = c0o1;
-   real mfaca = c0o1;
-
-   mfaaa = press; // if drho is interpolated directly
-
-   real vx1Sq = vx1*vx1;
-   real vx2Sq = vx2*vx2;
-   real vx3Sq = vx3*vx3;
-   real oMdrho = c1o1;
-   //oMdrho = one - mfaaa;
-
-   //2.f
-   // linear combinations
-
-/////////////////////////
-   real mxxPyyPzz = mfaaa    -c2o3*(ax+by+cz)*eps_new/oP*(c1o1 +press);
-
-   real mxxMyy    = -c2o3*((ax - by)+kxxMyyAverage)*eps_new/o * (c1o1 + press);
-   real mxxMzz    = -c2o3*((ax - cz)+kxxMzzAverage)*eps_new/o * (c1o1 + press);
-
-   mfabb     = -c1o3 * ((bz + cy)+kyzAverage)*eps_new/o * (c1o1 + press);
-   mfbab     = -c1o3 * ((az + cx)+kxzAverage)*eps_new/o * (c1o1 + press);
-   mfbba     = -c1o3 * ((ay + bx)+kxyAverage)*eps_new/o * (c1o1 + press);
-
-   ////////////////////////
-   // linear combinations back
-   mfcaa = c1o3 * (mxxMyy +       mxxMzz + mxxPyyPzz);
-   mfaca = c1o3 * (-c2o1 * mxxMyy +       mxxMzz + mxxPyyPzz);
-   mfaac = c1o3 * (mxxMyy - c2o1 * mxxMzz + mxxPyyPzz);
-
-   //three
-   mfbbb = c0o1;
-
-   real mxxyPyzz = c0o1;
-   real mxxyMyzz = c0o1;
-   real mxxzPyyz = c0o1;
-   real mxxzMyyz = c0o1;
-   real mxyyPxzz = c0o1;
-   real mxyyMxzz = c0o1;
-
-   // linear combinations back
-   mfcba = (mxxyMyzz + mxxyPyzz) * c1o2;
-   mfabc = (-mxxyMyzz + mxxyPyzz) * c1o2;
-   mfcab = (mxxzMyyz + mxxzPyyz) * c1o2;
-   mfacb = (-mxxzMyyz + mxxzPyyz) * c1o2;
-   mfbca = (mxyyMxzz + mxyyPxzz) * c1o2;
-   mfbac = (-mxyyMxzz + mxyyPxzz) * c1o2;
-
-   //4.f
-   mfacc = mfaaa*c1o9;
-   mfcac = mfacc;
-   mfcca = mfacc;
-   //5.
-
-   //6.
-   mfccc = mfaaa*c1o27;
-   ////////////////////////////////////////////////////////////////////////////////////
-   //back
-   ////////////////////////////////////////////////////////////////////////////////////
-   //mit 1, 0, 1/3, 0, 0, 0, 1/3, 0, 1/9   Konditionieren
-   ////////////////////////////////////////////////////////////////////////////////////
-   // Z - Dir
-   real m0 =  mfaac * c1o2 +      mfaab * (vx3 - c1o2) + (mfaaa + c1o1 * oMdrho) * (vx3Sq - vx3) * c1o2;
-   real m1 = -mfaac        - c2o1 * mfaab *  vx3         +  mfaaa                * (c1o1 - vx3Sq)              - c1o1 * oMdrho * vx3Sq;
-   real m2 =  mfaac * c1o2 +      mfaab * (vx3 + c1o2) + (mfaaa + c1o1 * oMdrho) * (vx3Sq + vx3) * c1o2;
-   mfaaa = m0;
-   mfaab = m1;
-   mfaac = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfabc * c1o2 +      mfabb * (vx3 - c1o2) + mfaba * (vx3Sq - vx3) * c1o2;
-   m1 = -mfabc        - c2o1 * mfabb *  vx3         + mfaba * (c1o1 - vx3Sq);
-   m2 =  mfabc * c1o2 +      mfabb * (vx3 + c1o2) + mfaba * (vx3Sq + vx3) * c1o2;
-   mfaba = m0;
-   mfabb = m1;
-   mfabc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfacc * c1o2 +      mfacb * (vx3 - c1o2) + (mfaca + c1o3 * oMdrho) * (vx3Sq - vx3) * c1o2;
-   m1 = -mfacc        - c2o1 * mfacb *  vx3         +  mfaca                  * (c1o1 - vx3Sq)              - c1o3 * oMdrho * vx3Sq;
-   m2 =  mfacc * c1o2 +      mfacb * (vx3 + c1o2) + (mfaca + c1o3 * oMdrho) * (vx3Sq + vx3) * c1o2;
-   mfaca = m0;
-   mfacb = m1;
-   mfacc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfbac * c1o2 +      mfbab * (vx3 - c1o2) + mfbaa * (vx3Sq - vx3) * c1o2;
-   m1 = -mfbac        - c2o1 * mfbab *  vx3         + mfbaa * (c1o1 - vx3Sq);
-   m2 =  mfbac * c1o2 +      mfbab * (vx3 + c1o2) + mfbaa * (vx3Sq + vx3) * c1o2;
-   mfbaa = m0;
-   mfbab = m1;
-   mfbac = m2;
-   /////////b//////////////////////////////////////////////////////////////////////////
-   m0 =  mfbbc * c1o2 +      mfbbb * (vx3 - c1o2) + mfbba * (vx3Sq - vx3) * c1o2;
-   m1 = -mfbbc        - c2o1 * mfbbb *  vx3         + mfbba * (c1o1 - vx3Sq);
-   m2 =  mfbbc * c1o2 +      mfbbb * (vx3 + c1o2) + mfbba * (vx3Sq + vx3) * c1o2;
-   mfbba = m0;
-   mfbbb = m1;
-   mfbbc = m2;
-   /////////b//////////////////////////////////////////////////////////////////////////
-   m0 =  mfbcc * c1o2 +      mfbcb * (vx3 - c1o2) + mfbca * (vx3Sq - vx3) * c1o2;
-   m1 = -mfbcc        - c2o1 * mfbcb *  vx3         + mfbca * (c1o1 - vx3Sq);
-   m2 =  mfbcc * c1o2 +      mfbcb * (vx3 + c1o2) + mfbca * (vx3Sq + vx3) * c1o2;
-   mfbca = m0;
-   mfbcb = m1;
-   mfbcc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcac * c1o2 +      mfcab * (vx3 - c1o2) + (mfcaa + c1o3 * oMdrho) * (vx3Sq - vx3) * c1o2;
-   m1 = -mfcac        - c2o1 * mfcab *  vx3         +  mfcaa                  * (c1o1 - vx3Sq)              - c1o3 * oMdrho * vx3Sq;
-   m2 =  mfcac * c1o2 +      mfcab * (vx3 + c1o2) + (mfcaa + c1o3 * oMdrho) * (vx3Sq + vx3) * c1o2;
-   mfcaa = m0;
-   mfcab = m1;
-   mfcac = m2;
-   /////////c//////////////////////////////////////////////////////////////////////////
-   m0 =  mfcbc * c1o2 +      mfcbb * (vx3 - c1o2) + mfcba * (vx3Sq - vx3) * c1o2;
-   m1 = -mfcbc        - c2o1 * mfcbb *  vx3         + mfcba * (c1o1 - vx3Sq);
-   m2 =  mfcbc * c1o2 +      mfcbb * (vx3 + c1o2) + mfcba * (vx3Sq + vx3) * c1o2;
-   mfcba = m0;
-   mfcbb = m1;
-   mfcbc = m2;
-   /////////c//////////////////////////////////////////////////////////////////////////
-   m0 =  mfccc * c1o2 +      mfccb * (vx3 - c1o2) + (mfcca + c1o9 * oMdrho) * (vx3Sq - vx3) * c1o2;
-   m1 = -mfccc        - c2o1 * mfccb *  vx3         +  mfcca                  * (c1o1 - vx3Sq)              - c1o9 * oMdrho * vx3Sq;
-   m2 =  mfccc * c1o2 +      mfccb * (vx3 + c1o2) + (mfcca + c1o9 * oMdrho) * (vx3Sq + vx3) * c1o2;
-   mfcca = m0;
-   mfccb = m1;
-   mfccc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   //mit 1/6, 2/3, 1/6, 0, 0, 0, 1/18, 2/9, 1/18   Konditionieren
-   ////////////////////////////////////////////////////////////////////////////////////
-   // Y - Dir
-   m0 =  mfaca * c1o2 +      mfaba * (vx2 - c1o2) + (mfaaa + c1o6 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfaca        - c2o1 * mfaba *  vx2         +  mfaaa                  * (c1o1 - vx2Sq)              - c1o6 * oMdrho * vx2Sq;
-   m2 =  mfaca * c1o2 +      mfaba * (vx2 + c1o2) + (mfaaa + c1o6 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfaaa = m0;
-   mfaba = m1;
-   mfaca = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfacb * c1o2 +      mfabb * (vx2 - c1o2) + (mfaab + c2o3 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfacb        - c2o1 * mfabb *  vx2         +  mfaab                  * (c1o1 - vx2Sq)              - c2o3 * oMdrho * vx2Sq;
-   m2 =  mfacb * c1o2 +      mfabb * (vx2 + c1o2) + (mfaab + c2o3 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfaab = m0;
-   mfabb = m1;
-   mfacb = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfacc * c1o2 +      mfabc * (vx2 - c1o2) + (mfaac + c1o6 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfacc        - c2o1 * mfabc *  vx2         +  mfaac                  * (c1o1 - vx2Sq)              - c1o6 * oMdrho * vx2Sq;
-   m2 =  mfacc * c1o2 +      mfabc * (vx2 + c1o2) + (mfaac + c1o6 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfaac = m0;
-   mfabc = m1;
-   mfacc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfbca * c1o2 +      mfbba * (vx2 - c1o2) + mfbaa * (vx2Sq - vx2) * c1o2;
-   m1 = -mfbca        - c2o1 * mfbba *  vx2         + mfbaa * (c1o1 - vx2Sq);
-   m2 =  mfbca * c1o2 +      mfbba * (vx2 + c1o2) + mfbaa * (vx2Sq + vx2) * c1o2;
-   mfbaa = m0;
-   mfbba = m1;
-   mfbca = m2;
-   /////////b//////////////////////////////////////////////////////////////////////////
-   m0 =  mfbcb * c1o2 +      mfbbb * (vx2 - c1o2) + mfbab * (vx2Sq - vx2) * c1o2;
-   m1 = -mfbcb        - c2o1 * mfbbb *  vx2         + mfbab * (c1o1 - vx2Sq);
-   m2 =  mfbcb * c1o2 +      mfbbb * (vx2 + c1o2) + mfbab * (vx2Sq + vx2) * c1o2;
-   mfbab = m0;
-   mfbbb = m1;
-   mfbcb = m2;
-   /////////b//////////////////////////////////////////////////////////////////////////
-   m0 =  mfbcc * c1o2 +      mfbbc * (vx2 - c1o2) + mfbac * (vx2Sq - vx2) * c1o2;
-   m1 = -mfbcc        - c2o1 * mfbbc *  vx2         + mfbac * (c1o1 - vx2Sq);
-   m2 =  mfbcc * c1o2 +      mfbbc * (vx2 + c1o2) + mfbac * (vx2Sq + vx2) * c1o2;
-   mfbac = m0;
-   mfbbc = m1;
-   mfbcc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcca * c1o2 +      mfcba * (vx2 - c1o2) + (mfcaa + c1o18 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfcca        - c2o1 * mfcba *  vx2         +  mfcaa                   * (c1o1 - vx2Sq)              - c1o18 * oMdrho * vx2Sq;
-   m2 =  mfcca * c1o2 +      mfcba * (vx2 + c1o2) + (mfcaa + c1o18 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfcaa = m0;
-   mfcba = m1;
-   mfcca = m2;
-   /////////c//////////////////////////////////////////////////////////////////////////
-   m0 =  mfccb * c1o2 +      mfcbb * (vx2 - c1o2) + (mfcab + c2o9 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfccb        - c2o1 * mfcbb *  vx2         +  mfcab                  * (c1o1 - vx2Sq)              - c2o9 * oMdrho * vx2Sq;
-   m2 =  mfccb * c1o2 +      mfcbb * (vx2 + c1o2) + (mfcab + c2o9 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfcab = m0;
-   mfcbb = m1;
-   mfccb = m2;
-   /////////c//////////////////////////////////////////////////////////////////////////
-   m0 =  mfccc * c1o2 +      mfcbc * (vx2 - c1o2) + (mfcac + c1o18 * oMdrho) * (vx2Sq - vx2) * c1o2;
-   m1 = -mfccc        - c2o1 * mfcbc *  vx2         +  mfcac                   * (c1o1 - vx2Sq)              - c1o18 * oMdrho * vx2Sq;
-   m2 =  mfccc * c1o2 +      mfcbc * (vx2 + c1o2) + (mfcac + c1o18 * oMdrho) * (vx2Sq + vx2) * c1o2;
-   mfcac = m0;
-   mfcbc = m1;
-   mfccc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   //mit 1/36, 1/9, 1/36, 1/9, 4/9, 1/9, 1/36, 1/9, 1/36 Konditionieren
-   ////////////////////////////////////////////////////////////////////////////////////
-   // X - Dir
-   m0 =  mfcaa * c1o2 +      mfbaa * (vx1 - c1o2) + (mfaaa + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcaa        - c2o1 * mfbaa *  vx1         +  mfaaa                   * (c1o1 - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
-   m2 =  mfcaa * c1o2 +      mfbaa * (vx1 + c1o2) + (mfaaa + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfaaa = m0;
-   mfbaa = m1;
-   mfcaa = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcba * c1o2 +      mfbba * (vx1 - c1o2) + (mfaba + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcba        - c2o1 * mfbba *  vx1         +  mfaba                  * (c1o1 - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
-   m2 =  mfcba * c1o2 +      mfbba * (vx1 + c1o2) + (mfaba + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfaba = m0;
-   mfbba = m1;
-   mfcba = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcca * c1o2 +      mfbca * (vx1 - c1o2) + (mfaca + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcca        - c2o1 * mfbca *  vx1         +  mfaca                   * (c1o1 - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
-   m2 =  mfcca * c1o2 +      mfbca * (vx1 + c1o2) + (mfaca + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfaca = m0;
-   mfbca = m1;
-   mfcca = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcab * c1o2 +      mfbab * (vx1 - c1o2) + (mfaab + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcab        - c2o1 * mfbab *  vx1         +  mfaab                  * (c1o1 - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
-   m2 =  mfcab * c1o2 +      mfbab * (vx1 + c1o2) + (mfaab + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfaab = m0;
-   mfbab = m1;
-   mfcab = m2;
-   ///////////b////////////////////////////////////////////////////////////////////////
-   m0 =  mfcbb * c1o2 +      mfbbb * (vx1 - c1o2) + (mfabb + c4o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcbb        - c2o1 * mfbbb *  vx1         +  mfabb                  * (c1o1 - vx1Sq)              - c4o9 * oMdrho * vx1Sq;
-   m2 =  mfcbb * c1o2 +      mfbbb * (vx1 + c1o2) + (mfabb + c4o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfabb = m0;
-   mfbbb = m1;
-   mfcbb = m2;
-   ///////////b////////////////////////////////////////////////////////////////////////
-   m0 =  mfccb * c1o2 +      mfbcb * (vx1 - c1o2) + (mfacb + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfccb        - c2o1 * mfbcb *  vx1         +  mfacb                  * (c1o1 - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
-   m2 =  mfccb * c1o2 +      mfbcb * (vx1 + c1o2) + (mfacb + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfacb = m0;
-   mfbcb = m1;
-   mfccb = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-   ////////////////////////////////////////////////////////////////////////////////////
-   m0 =  mfcac * c1o2 +      mfbac * (vx1 - c1o2) + (mfaac + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcac        - c2o1 * mfbac *  vx1         +  mfaac                   * (c1o1 - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
-   m2 =  mfcac * c1o2 +      mfbac * (vx1 + c1o2) + (mfaac + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfaac = m0;
-   mfbac = m1;
-   mfcac = m2;
-   ///////////c////////////////////////////////////////////////////////////////////////
-   m0 =  mfcbc * c1o2 +      mfbbc * (vx1 - c1o2) + (mfabc + c1o9 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfcbc        - c2o1 * mfbbc *  vx1         +  mfabc                  * (c1o1 - vx1Sq)              - c1o9 * oMdrho * vx1Sq;
-   m2 =  mfcbc * c1o2 +      mfbbc * (vx1 + c1o2) + (mfabc + c1o9 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfabc = m0;
-   mfbbc = m1;
-   mfcbc = m2;
-   ///////////c////////////////////////////////////////////////////////////////////////
-   m0 =  mfccc * c1o2 +      mfbcc * (vx1 - c1o2) + (mfacc + c1o36 * oMdrho) * (vx1Sq - vx1) * c1o2;
-   m1 = -mfccc        - c2o1 * mfbcc *  vx1         +  mfacc                   * (c1o1 - vx1Sq)              - c1o36 * oMdrho * vx1Sq;
-   m2 =  mfccc * c1o2 +      mfbcc * (vx1 + c1o2) + (mfacc + c1o36 * oMdrho) * (vx1Sq + vx1) * c1o2;
-   mfacc = m0;
-   mfbcc = m1;
-   mfccc = m2;
-   ////////////////////////////////////////////////////////////////////////////////////
-
-   f[DIR_P00] = mfcbb;
-   f[DIR_M00] = mfabb;
-   f[DIR_0P0] = mfbcb;
-   f[DIR_0M0] = mfbab;
-   f[DIR_00P] = mfbbc;
-   f[DIR_00M] = mfbba;
-   f[DIR_PP0] = mfccb;
-   f[DIR_MM0] = mfaab;
-   f[DIR_PM0] = mfcab;
-   f[DIR_MP0] = mfacb;
-   f[DIR_P0P] = mfcbc;
-   f[DIR_M0M] = mfaba;
-   f[DIR_P0M] = mfcba;
-   f[DIR_M0P] = mfabc;
-   f[DIR_0PP] = mfbcc;
-   f[DIR_0MM] = mfbaa;
-   f[DIR_0PM] = mfbca;
-   f[DIR_0MP] = mfbac;
-   f[DIR_000] = mfbbb;
-   f[DIR_PPP] = mfccc;
-   f[DIR_PMP] = mfcac;
-   f[DIR_PPM] = mfcca;
-   f[DIR_PMM] = mfcaa;
-   f[DIR_MPP] = mfacc;
-   f[DIR_MMP] = mfaac;
-   f[DIR_MPM] = mfaca;
-   f[DIR_MMM] = mfaaa;
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedVelocity(real x, real y, real z, real& vx1, real& vx2, real& vx3)
-{
-	vx1  = a0 + ax*x + ay*y + az*z + axx*x*x + ayy*y*y + azz*z*z + axy*x*y + axz*x*z + ayz*y*z+axyz*x*y*z;
-	vx2  = b0 + bx*x + by*y + bz*z + bxx*x*x + byy*y*y + bzz*z*z + bxy*x*y + bxz*x*z + byz*y*z+bxyz*x*y*z;
-	vx3  = c0 + cx*x + cy*y + cz*z + cxx*x*x + cyy*y*y + czz*z*z + cxy*x*y + cxz*x*z + cyz*y*z+cxyz*x*y*z;
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetMomentsInterpolationProcessor::calcInterpolatedShearStress(real x, real y, real z,real& tauxx, real& tauyy, real& tauzz,real& tauxy, real& tauxz, real& tauyz)
-{
-	tauxx=ax+c2o1*axx*x+axy*y+axz*z+axyz*y*z;
-	tauyy=by+c2o1*byy*y+bxy*x+byz*z+bxyz*x*z;
-	tauzz=cz+c2o1*czz*z+cxz*x+cyz*y+cxyz*x*y;
-	tauxy= c1o2*((ay+c2o1*ayy*y+axy*x+ayz*z+axyz*x*z)+(bx+c2o1*bxx*x+bxy*y+bxz*z+bxyz*y*z));
-	tauxz= c1o2*((az+c2o1*azz*z+axz*x+ayz*y+axyz*x*y)+(cx+c2o1*cxx*x+cxy*y+cxz*z+cxyz*y*z));
-	tauyz= c1o2*((bz+c2o1*bzz*z+bxz*x+byz*y+bxyz*x*y)+(cy+c2o1*cyy*y+cxy*x+cyz*z+cxyz*x*z));
-}
-//////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetMomentsInterpolationProcessor::setBulkViscosity(real shearViscosity, real bulkViscosity)
-{
-   this->shearViscosity = shearViscosity;
-   this->bulkViscosity  = bulkViscosity;
-}
-
diff --git a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h b/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h
deleted file mode 100644
index 32ab8cedf89e2e644f2f939f49ed4b0101eb0e32..0000000000000000000000000000000000000000
--- a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetMomentsInterpolationProcessor.h
+++ /dev/null
@@ -1,82 +0,0 @@
-#ifndef CompressibleOffsetMomentsInterpolationProcessor_H_
-#define CompressibleOffsetMomentsInterpolationProcessor_H_
-
-#include "InterpolationProcessor.h"
-#include "D3Q27System.h"
-
-//////////////////////////////////////////////////////////////////////////
-//it works only for cascaded LBM
-//super compact interpolation method by Martin Geier
-//////////////////////////////////////////////////////////////////////////
-
-class CompressibleOffsetMomentsInterpolationProcessor;
-
-class CompressibleOffsetMomentsInterpolationProcessor : public InterpolationProcessor
-{
-public:
-   CompressibleOffsetMomentsInterpolationProcessor();
-   CompressibleOffsetMomentsInterpolationProcessor(real omegaC, real omegaF);
-   ~CompressibleOffsetMomentsInterpolationProcessor() override;
-   InterpolationProcessorPtr clone() override;
-   void setOmegas(real omegaC, real omegaF) override;
-   void interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF) override;
-   void interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff) override;
-   void interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC) override; 
-   void interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff) override; 
-   void setBulkViscosity(real shearViscosity, real bulkViscosity);
-protected:   
-private:
-   real omegaC{0.0}, omegaF{0.0};
-   real a0, ax, ay, az, axx, ayy, azz, axy, axz, ayz, b0, bx, by, bz, bxx, byy, bzz, bxy, bxz, byz, c0, cx, cy, cz, cxx, cyy, czz, cxy, cxz, cyz, axyz, bxyz, cxyz;
-   real xoff,    yoff,    zoff;
-   real xoff_sq, yoff_sq, zoff_sq;
-   real press_SWT, press_NWT, press_NET, press_SET, press_SWB, press_NWB, press_NEB, press_SEB;
-
-   real  f_E,  f_N,  f_T,  f_NE,  f_SE,  f_BE,  f_TE,  f_TN,  f_BN,  f_TNE,  f_TNW,  f_TSE,  f_TSW,  f_ZERO;
-   real  x_E,  x_N,  x_T,  x_NE,  x_SE,  x_BE,  x_TE,  x_TN,  x_BN,  x_TNE,  x_TNW,  x_TSE,  x_TSW,  x_ZERO;
-   real  y_E,  y_N,  y_T,  y_NE,  y_SE,  y_BE,  y_TE,  y_TN,  y_BN,  y_TNE,  y_TNW,  y_TSE,  y_TSW,  y_ZERO;
-   real  z_E,  z_N,  z_T,  z_NE,  z_SE,  z_BE,  z_TE,  z_TN,  z_BN,  z_TNE,  z_TNW,  z_TSE,  z_TSW,  z_ZERO;
-   real xy_E, xy_N, xy_T, xy_NE, xy_SE, xy_BE, xy_TE, xy_TN, xy_BN, xy_TNE, xy_TNW, xy_TSE, xy_TSW/*, xy_ZERO*/;
-   real xz_E, xz_N, xz_T, xz_NE, xz_SE, xz_BE, xz_TE, xz_TN, xz_BN, xz_TNE, xz_TNW, xz_TSE, xz_TSW/*, xz_ZERO*/;
-   real yz_E, yz_N, yz_T, yz_NE, yz_SE, yz_BE, yz_TE, yz_TN, yz_BN, yz_TNE, yz_TNW, yz_TSE, yz_TSW/*, yz_ZERO*/;
-
-   real kxyAverage, kyzAverage, kxzAverage, kxxMyyAverage, kxxMzzAverage; 
-
-//   real a,b,c;
-
-   // bulk viscosity
-   real shearViscosity;
-   real bulkViscosity;
-   real OxxPyyPzzC;
-   real OxxPyyPzzF;
-
-   void setOffsets(real xoff, real yoff, real zoff) override;
-   void calcMoments(const real* const f, real omega, real& rho, real& vx1, real& vx2, real& vx3, 
-      real& kxy, real& kyz, real& kxz, real& kxxMyy, real& kxxMzz);
-   void calcInterpolatedCoefficiets(const D3Q27ICell& icell, real omega, real eps_new) override;
-   void calcInterpolatedNodeCF(real* f, real omega, real x, real y, real z, real press, real xs, real ys, real zs);
-   real calcPressBSW();
-   real calcPressTSW();
-   real calcPressTSE();
-   real calcPressBSE();
-   real calcPressBNW();
-   real calcPressTNW();
-   real calcPressTNE();
-   real calcPressBNE();
-   void calcInterpolatedNodeFC(real* f, real omega) override;
-   void calcInterpolatedVelocity(real x, real y, real z,real& vx1, real& vx2, real& vx3) override;
-   void calcInterpolatedShearStress(real x, real y, real z,real& tauxx, real& tauyy, real& tauzz,real& tauxy, real& tauxz, real& tauyz) override;
-};
-
-//////////////////////////////////////////////////////////////////////////
-inline void CompressibleOffsetMomentsInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF)
-{
-   this->interpolateCoarseToFine(icellC, icellF, 0.0, 0.0, 0.0);
-}
-//////////////////////////////////////////////////////////////////////////
-inline void CompressibleOffsetMomentsInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC)
-{
-   this->interpolateFineToCoarse(icellF, icellC, 0.0, 0.0, 0.0);
-}
-
-#endif
diff --git a/src/cpu/VirtualFluidsCore/LBM/CumulantLBMKernel.cpp b/src/cpu/VirtualFluidsCore/LBM/CumulantLBMKernel.cpp
index 548339f940d45ab2239ce6cb1cebbfa9bf0082b5..1b8d5a230ddf7a2d9b58c9e7ca8231f5c9d3500f 100644
--- a/src/cpu/VirtualFluidsCore/LBM/CumulantLBMKernel.cpp
+++ b/src/cpu/VirtualFluidsCore/LBM/CumulantLBMKernel.cpp
@@ -1,6 +1,6 @@
 #include "CumulantLBMKernel.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include <math.h>
 #include "DataSet3D.h"
diff --git a/src/cpu/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.cpp b/src/cpu/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.cpp
index 990bb8f89f4b6abb1a0e77b550af4d751ad49a40..39d6fd268a56f4824babaccea3449ea097c85bf2 100644
--- a/src/cpu/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.cpp
+++ b/src/cpu/VirtualFluidsCore/LBM/IncompressibleCumulantLBMKernel.cpp
@@ -1,6 +1,6 @@
 #include "IncompressibleCumulantLBMKernel.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27EsoTwist3DSplittedVector.h"
 #include "DataSet3D.h"
 #include <cmath>
diff --git a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetInterpolator.cpp
similarity index 95%
rename from src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp
rename to src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetInterpolator.cpp
index 5cf501e20012804b7e84090243dad466e06ad06c..509115d26edfaa398877739bf1f25919595e9aa6 100644
--- a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.cpp
+++ b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetInterpolator.cpp
@@ -1,32 +1,32 @@
-#include "CompressibleOffsetInterpolationProcessor.h"
+#include "CompressibleOffsetInterpolator.h"
 #include "D3Q27System.h"
 
 //using namespace UbMath;
 using namespace vf::basics::constant;
 
 //////////////////////////////////////////////////////////////////////////
-CompressibleOffsetInterpolationProcessor::CompressibleOffsetInterpolationProcessor(real omegaC, real omegaF)
+CompressibleOffsetInterpolator::CompressibleOffsetInterpolator(real omegaC, real omegaF)
    : omegaC(omegaC), omegaF(omegaF)
 {
 
 }
 
 //////////////////////////////////////////////////////////////////////////
-InterpolationProcessorPtr CompressibleOffsetInterpolationProcessor::clone()
+InterpolationProcessorPtr CompressibleOffsetInterpolator::clone()
 {
-   InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new CompressibleOffsetInterpolationProcessor(this->omegaC, this->omegaF));
+   InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new CompressibleOffsetInterpolator(this->omegaC, this->omegaF));
    //dynamicPointerCast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingC = forcingC;
    //dynamicPointerCast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingF = forcingF;
    return iproc;
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetInterpolationProcessor::setOmegas( real omegaC, real omegaF )
+void CompressibleOffsetInterpolator::setOmegas( real omegaC, real omegaF )
 {
    this->omegaC = omegaC;
    this->omegaF = omegaF;
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetInterpolationProcessor::setOffsets(real xoff, real yoff, real zoff)
+void CompressibleOffsetInterpolator::setOffsets(real xoff, real yoff, real zoff)
 {
    this->xoff = xoff;
    this->yoff = yoff;
@@ -36,7 +36,7 @@ void CompressibleOffsetInterpolationProcessor::setOffsets(real xoff, real yoff,
    this->zoff_sq = zoff * zoff;
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff)
+void CompressibleOffsetInterpolator::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff)
 {
    setOffsets(xoff, yoff, zoff);
    calcInterpolatedCoefficiets(icellC, omegaC, c1o2);
@@ -50,14 +50,14 @@ void CompressibleOffsetInterpolationProcessor::interpolateCoarseToFine(D3Q27ICel
    calcInterpolatedNodeCF(icellF.TNE, omegaF,  c1o4,  c1o4,  c1o4, calcPressTNE(),  c1o1,  c1o1,  c1o1);
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff)
+void CompressibleOffsetInterpolator::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff)
 {
    setOffsets(xoff, yoff, zoff);
    calcInterpolatedCoefficiets(icellF, omegaF, c2o1);
    calcInterpolatedNodeFC(icellC, omegaC);
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetInterpolationProcessor::calcMoments(const real* const f, real omega, real& press, real& vx1, real& vx2, real& vx3, 
+void CompressibleOffsetInterpolator::calcMoments(const real* const f, real omega, real& press, real& vx1, real& vx2, real& vx3, 
                                                     real& kxy, real& kyz, real& kxz, real& kxxMyy, real& kxxMzz)
 {
    using namespace D3Q27System;
@@ -76,7 +76,7 @@ void CompressibleOffsetInterpolationProcessor::calcMoments(const real* const f,
    kxxMzz = -c3o1/c2o1*omega*((((f[DIR_MP0]+f[DIR_PM0])-(f[DIR_0MM]+f[DIR_0PP]))+((f[DIR_MM0]+f[DIR_PP0])-(f[DIR_0MP]+f[DIR_0PM])))+((f[DIR_M00]+f[DIR_P00])-(f[DIR_00M]+f[DIR_00P]))/(c1o1 + drho)-(vx1*vx1-vx3*vx3));
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetInterpolationProcessor::calcInterpolatedCoefficiets(const D3Q27ICell& icell, real omega, real eps_new)
+void CompressibleOffsetInterpolator::calcInterpolatedCoefficiets(const D3Q27ICell& icell, real omega, real eps_new)
 {
    real        vx1_SWT,vx2_SWT,vx3_SWT;
    real        vx1_NWT,vx2_NWT,vx3_NWT;
@@ -457,7 +457,7 @@ void CompressibleOffsetInterpolationProcessor::calcInterpolatedCoefficiets(const
    yz_TNW =   c1o16*eps_new *((                bxyz +     cxyz)/(c72o1*o));
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetInterpolationProcessor::calcInterpolatedNodeCF(real* f, real  /*omega*/, real  /*x*/, real  /*y*/, real  /*z*/, real press, real xs, real ys, real zs)
+void CompressibleOffsetInterpolator::calcInterpolatedNodeCF(real* f, real  /*omega*/, real  /*x*/, real  /*y*/, real  /*z*/, real press, real xs, real ys, real zs)
 {
    using namespace D3Q27System;
    using namespace vf::lbm::dir;
@@ -504,8 +504,8 @@ void CompressibleOffsetInterpolationProcessor::calcInterpolatedNodeCF(real* f, r
    f[DIR_000] = f_ZERO + xs*x_ZERO + ys*y_ZERO + zs*z_ZERO                                                 + feq[DIR_000];
 }
 //////////////////////////////////////////////////////////////////////////
-//Position SWB -c1o4, -c1o4, -c1o4
-real CompressibleOffsetInterpolationProcessor::calcPressBSW()
+//Position SWB -0.25, -0.25, -0.25
+real CompressibleOffsetInterpolator::calcPressBSW()
 {
    return   press_SWT * (c9o64 + c3o16 * xoff + c3o16 * yoff - c9o16 * zoff) +
       press_NWT * (c3o64 + c1o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
@@ -517,8 +517,8 @@ real CompressibleOffsetInterpolationProcessor::calcPressBSW()
       press_SWB * (c27o64 + c9o16 * xoff + c9o16 * yoff + c9o16 * zoff);
 }
 //////////////////////////////////////////////////////////////////////////
-//Position SWT -c1o4, -c1o4, c1o4
-real CompressibleOffsetInterpolationProcessor::calcPressTSW()
+//Position SWT -0.25, -0.25, 0.25
+real CompressibleOffsetInterpolator::calcPressTSW()
 {
    return   press_SWT * (c27o64 + c9o16 * xoff + c9o16 * yoff - c9o16 * zoff) +
       press_NWT * (c9o64 + c3o16 * xoff - c9o16 * yoff - c3o16 * zoff) +
@@ -531,7 +531,7 @@ real CompressibleOffsetInterpolationProcessor::calcPressTSW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SET 0.25, -0.25, 0.25
-real CompressibleOffsetInterpolationProcessor::calcPressTSE()
+real CompressibleOffsetInterpolator::calcPressTSE()
 {
    return   press_SET * (c27o64 - c9o16 * xoff + c9o16 * yoff - c9o16 * zoff) +
       press_NET * (c9o64 - c3o16 * xoff - c9o16 * yoff - c3o16 * zoff) +
@@ -544,7 +544,7 @@ real CompressibleOffsetInterpolationProcessor::calcPressTSE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SEB 0.25, -0.25, -0.25
-real CompressibleOffsetInterpolationProcessor::calcPressBSE()
+real CompressibleOffsetInterpolator::calcPressBSE()
 {
    return   press_SET * (c9o64 - c3o16 * xoff + c3o16 * yoff - c9o16 * zoff) +
       press_NET * (c3o64 - c1o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
@@ -557,7 +557,7 @@ real CompressibleOffsetInterpolationProcessor::calcPressBSE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NWB -0.25, 0.25, -0.25
-real CompressibleOffsetInterpolationProcessor::calcPressBNW()
+real CompressibleOffsetInterpolator::calcPressBNW()
 {
    return   press_NWT * (c9o64 + c3o16 * xoff - c3o16 * yoff - c9o16 * zoff) +
       press_NET * (c3o64 - c3o16 * xoff - c1o16 * yoff - c3o16 * zoff) +
@@ -570,7 +570,7 @@ real CompressibleOffsetInterpolationProcessor::calcPressBNW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NWT -0.25, 0.25, 0.25
-real CompressibleOffsetInterpolationProcessor::calcPressTNW()
+real CompressibleOffsetInterpolator::calcPressTNW()
 {
    return   press_NWT * (c27o64 + c9o16 * xoff - c9o16 * yoff - c9o16 * zoff) +
       press_NET * (c9o64 - c9o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
@@ -583,7 +583,7 @@ real CompressibleOffsetInterpolationProcessor::calcPressTNW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NET 0.25, 0.25, 0.25
-real CompressibleOffsetInterpolationProcessor::calcPressTNE()
+real CompressibleOffsetInterpolator::calcPressTNE()
 {
    return   press_NET * (c27o64 - c9o16 * xoff - c9o16 * yoff - c9o16 * zoff) +
       press_NWT * (c9o64 + c9o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
@@ -596,7 +596,7 @@ real CompressibleOffsetInterpolationProcessor::calcPressTNE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NEB 0.25, 0.25, -0.25
-real CompressibleOffsetInterpolationProcessor::calcPressBNE()
+real CompressibleOffsetInterpolator::calcPressBNE()
 {
    return   press_NET * (c9o64 - c3o16 * xoff - c3o16 * yoff - c9o16 * zoff) +
       press_NWT * (c3o64 + c3o16 * xoff - c1o16 * yoff - c3o16 * zoff) +
@@ -609,7 +609,7 @@ real CompressibleOffsetInterpolationProcessor::calcPressBNE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position C 0.0, 0.0, 0.0
-void CompressibleOffsetInterpolationProcessor::calcInterpolatedNodeFC(real* f, real omega)
+void CompressibleOffsetInterpolator::calcInterpolatedNodeFC(real* f, real omega)
 {
    using namespace D3Q27System;
    using namespace vf::lbm::dir;
@@ -699,14 +699,14 @@ void CompressibleOffsetInterpolationProcessor::calcInterpolatedNodeFC(real* f, r
    f[DIR_000] = f_ZERO + feq[DIR_000];
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetInterpolationProcessor::calcInterpolatedVelocity(real x, real y, real z, real& vx1, real& vx2, real& vx3)
+void CompressibleOffsetInterpolator::calcInterpolatedVelocity(real x, real y, real z, real& vx1, real& vx2, real& vx3)
 {
 	vx1  = a0 + ax*x + ay*y + az*z + axx*x*x + ayy*y*y + azz*z*z + axy*x*y + axz*x*z + ayz*y*z+axyz*x*y*z;
 	vx2  = b0 + bx*x + by*y + bz*z + bxx*x*x + byy*y*y + bzz*z*z + bxy*x*y + bxz*x*z + byz*y*z+bxyz*x*y*z;
 	vx3  = c0 + cx*x + cy*y + cz*z + cxx*x*x + cyy*y*y + czz*z*z + cxy*x*y + cxz*x*z + cyz*y*z+cxyz*x*y*z;
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetInterpolationProcessor::calcInterpolatedShearStress(real x, real y, real z,real& tauxx, real& tauyy, real& tauzz,real& tauxy, real& tauxz, real& tauyz)
+void CompressibleOffsetInterpolator::calcInterpolatedShearStress(real x, real y, real z,real& tauxx, real& tauyy, real& tauzz,real& tauxy, real& tauxz, real& tauyz)
 {
 	tauxx=ax+c2o1*axx*x+axy*y+axz*z+axyz*y*z;
 	tauyy=by+c2o1*byy*y+bxy*x+byz*z+bxyz*x*z;
diff --git a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetInterpolator.h
similarity index 85%
rename from src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h
rename to src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetInterpolator.h
index fefd6ed1566fe0a4c3c414748a522edbfede48a1..8b295977773ad95c00b36a9ef775d45140fe34df 100644
--- a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetInterpolationProcessor.h
+++ b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetInterpolator.h
@@ -1,7 +1,7 @@
 #ifndef CompressibleOffsetInterpolationProcessor_H_
 #define CompressibleOffsetInterpolationProcessor_H_
 
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27System.h"
 
 //////////////////////////////////////////////////////////////////////////
@@ -9,14 +9,14 @@
 //super compact interpolation method by Martin Geier
 //////////////////////////////////////////////////////////////////////////
 
-class CompressibleOffsetInterpolationProcessor;
+class CompressibleOffsetInterpolator;
 
-class CompressibleOffsetInterpolationProcessor : public InterpolationProcessor
+class CompressibleOffsetInterpolator : public Interpolator
 {
 public:
-   CompressibleOffsetInterpolationProcessor() = default;
-   CompressibleOffsetInterpolationProcessor(real omegaC, real omegaF);
-   ~CompressibleOffsetInterpolationProcessor() override = default;
+   CompressibleOffsetInterpolator() = default;
+   CompressibleOffsetInterpolator(real omegaC, real omegaF);
+   ~CompressibleOffsetInterpolator() override = default;
 
    InterpolationProcessorPtr clone() override;
    void setOmegas(real omegaC, real omegaF) override;
@@ -64,12 +64,12 @@ private:
 };
 
 //////////////////////////////////////////////////////////////////////////
-inline void CompressibleOffsetInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF)
+inline void CompressibleOffsetInterpolator::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF)
 {
    this->interpolateCoarseToFine(icellC, icellF, 0.0, 0.0, 0.0);
 }
 //////////////////////////////////////////////////////////////////////////
-inline void CompressibleOffsetInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC)
+inline void CompressibleOffsetInterpolator::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC)
 {
    this->interpolateFineToCoarse(icellF, icellC, 0.0, 0.0, 0.0);
 }
diff --git a/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetMomentsInterpolator.cpp b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetMomentsInterpolator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e7d891df037a05fed023fff3aaaa0db19f0cfa43
--- /dev/null
+++ b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetMomentsInterpolator.cpp
@@ -0,0 +1,65 @@
+#include "CompressibleOffsetMomentsInterpolator.h"
+
+#include <algorithm>
+
+#include <basics/constants/NumericConstants.h>
+
+#include <lbm/refinement/InterpolationCF.h>
+#include <lbm/refinement/InterpolationFC.h>
+#include <lbm/refinement/Coefficients.h>
+
+
+void calculateCoefficients(vf::lbm::Coefficients& coefficients, const D3Q27ICell& icell, real omega, real xoff, real yoff, real zoff)
+{
+    vf::lbm::MomentsOnSourceNodeSet momentsSet;
+
+    momentsSet.calculateMMM(icell.BSW, omega);
+    momentsSet.calculateMMP(icell.TSW, omega);
+    momentsSet.calculateMPP(icell.TNW, omega);
+    momentsSet.calculateMPM(icell.BNW, omega);
+    momentsSet.calculatePMM(icell.BSE, omega);
+    momentsSet.calculatePPP(icell.TNE, omega);
+    momentsSet.calculatePMP(icell.TSE, omega);
+    momentsSet.calculatePPM(icell.BNE, omega);
+
+    momentsSet.calculateCoefficients(coefficients, xoff, yoff, zoff);
+}
+
+CompressibleOffsetMomentsInterpolator::CompressibleOffsetMomentsInterpolator(real omegaC, real omegaF)
+   : omegaC(omegaC), omegaF(omegaF)
+{
+}
+
+InterpolationProcessorPtr CompressibleOffsetMomentsInterpolator::clone()
+{
+   return InterpolationProcessorPtr (new CompressibleOffsetMomentsInterpolator(this->omegaC, this->omegaF));
+}
+
+void CompressibleOffsetMomentsInterpolator::setOmegas(real omegaC, real omegaF)
+{
+   this->omegaC = omegaC;
+   this->omegaF = omegaF;
+}
+
+void CompressibleOffsetMomentsInterpolator::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff)
+{
+    vf::lbm::Coefficients coefficients;
+    calculateCoefficients(coefficients, icellC, omegaC, xoff, yoff, zoff);
+
+     vf::lbm::interpolateCF(icellF.BSW, omegaF, vf::basics::constant::c1o2, coefficients, -0.25, -0.25, -0.25);
+     vf::lbm::interpolateCF(icellF.BNE, omegaF, vf::basics::constant::c1o2, coefficients,  0.25,  0.25, -0.25);
+     vf::lbm::interpolateCF(icellF.TNW, omegaF, vf::basics::constant::c1o2, coefficients, -0.25,  0.25,  0.25);
+     vf::lbm::interpolateCF(icellF.TSE, omegaF, vf::basics::constant::c1o2, coefficients,  0.25, -0.25,  0.25);
+     vf::lbm::interpolateCF(icellF.BNW, omegaF, vf::basics::constant::c1o2, coefficients, -0.25,  0.25, -0.25);
+     vf::lbm::interpolateCF(icellF.BSE, omegaF, vf::basics::constant::c1o2, coefficients,  0.25, -0.25, -0.25);
+     vf::lbm::interpolateCF(icellF.TSW, omegaF, vf::basics::constant::c1o2, coefficients, -0.25, -0.25,  0.25);
+     vf::lbm::interpolateCF(icellF.TNE, omegaF, vf::basics::constant::c1o2, coefficients,  0.25,  0.25,  0.25);
+}
+
+void CompressibleOffsetMomentsInterpolator::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff)
+{
+    vf::lbm::Coefficients coefficients;
+    calculateCoefficients(coefficients, icellF, omegaF, xoff, yoff, zoff);
+
+    vf::lbm::interpolateFC(icellC, vf::basics::constant::c2o1, omegaC, coefficients);
+}
diff --git a/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetMomentsInterpolator.h b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetMomentsInterpolator.h
new file mode 100644
index 0000000000000000000000000000000000000000..444170d565fc80cf735cd134f0b46ac54fc38902
--- /dev/null
+++ b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetMomentsInterpolator.h
@@ -0,0 +1,41 @@
+#ifndef CompressibleOffsetMomentsInterpolationProcessor_H_
+#define CompressibleOffsetMomentsInterpolationProcessor_H_
+
+#include "Interpolator.h"
+#include "D3Q27System.h"
+
+//////////////////////////////////////////////////////////////////////////
+//it works only for cascaded LBM
+//super compact interpolation method by Martin Geier
+//////////////////////////////////////////////////////////////////////////
+
+class CompressibleOffsetMomentsInterpolator : public Interpolator
+{
+public:
+    CompressibleOffsetMomentsInterpolator() = default;
+    CompressibleOffsetMomentsInterpolator(real omegaC, real omegaF);
+    InterpolationProcessorPtr clone() override;
+
+    void setOmegas(real omegaC, real omegaF) override;
+
+    void interpolateCoarseToFine(D3Q27ICell &icellC, D3Q27ICell &icellF) override;
+    void interpolateCoarseToFine(D3Q27ICell &icellC, D3Q27ICell &icellF, real xoff, real yoff, real zoff) override;
+    void interpolateFineToCoarse(D3Q27ICell &icellF, real *icellC) override;
+    void interpolateFineToCoarse(D3Q27ICell &icellF, real *icellC, real xoff, real yoff, real zoff) override;
+
+private:
+    real omegaC{ 0.0 }, omegaF{ 0.0 };
+};
+
+//////////////////////////////////////////////////////////////////////////
+inline void CompressibleOffsetMomentsInterpolator::interpolateCoarseToFine(D3Q27ICell &icellC, D3Q27ICell &icellF)
+{
+    this->interpolateCoarseToFine(icellC, icellF, 0.0, 0.0, 0.0);
+}
+//////////////////////////////////////////////////////////////////////////
+inline void CompressibleOffsetMomentsInterpolator::interpolateFineToCoarse(D3Q27ICell &icellF, real *icellC)
+{
+    this->interpolateFineToCoarse(icellF, icellC, 0.0, 0.0, 0.0);
+}
+
+#endif
diff --git a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetSquarePressureInterpolationProcessor.cpp b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetSquarePressureInterpolator.cpp
similarity index 96%
rename from src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetSquarePressureInterpolationProcessor.cpp
rename to src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetSquarePressureInterpolator.cpp
index dee6d12a5812e29d91aa1c12c25d61ade0759ef8..3b5d7386ae4e615a6f89d6ed07eb78d02b295799 100644
--- a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetSquarePressureInterpolationProcessor.cpp
+++ b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetSquarePressureInterpolator.cpp
@@ -1,10 +1,10 @@
-#include "CompressibleOffsetSquarePressureInterpolationProcessor.h"
+#include "CompressibleOffsetSquarePressureInterpolator.h"
 #include "D3Q27System.h"
 
 //using namespace UbMath;
 using namespace vf::basics::constant;
 
-CompressibleOffsetSquarePressureInterpolationProcessor::CompressibleOffsetSquarePressureInterpolationProcessor()
+CompressibleOffsetSquarePressureInterpolator::CompressibleOffsetSquarePressureInterpolator()
     
 {
    this->bulkOmegaToOmega = false;
@@ -12,7 +12,7 @@ CompressibleOffsetSquarePressureInterpolationProcessor::CompressibleOffsetSquare
    this->OxxPyyPzzF = c1o1;
 }
 //////////////////////////////////////////////////////////////////////////
-CompressibleOffsetSquarePressureInterpolationProcessor::CompressibleOffsetSquarePressureInterpolationProcessor(real omegaC, real omegaF)
+CompressibleOffsetSquarePressureInterpolator::CompressibleOffsetSquarePressureInterpolator(real omegaC, real omegaF)
    : omegaC(omegaC), omegaF(omegaF)
 {
    this->bulkOmegaToOmega = false;
@@ -20,32 +20,32 @@ CompressibleOffsetSquarePressureInterpolationProcessor::CompressibleOffsetSquare
    this->OxxPyyPzzF = c1o1;
 }
 //////////////////////////////////////////////////////////////////////////
-CompressibleOffsetSquarePressureInterpolationProcessor::~CompressibleOffsetSquarePressureInterpolationProcessor()
+CompressibleOffsetSquarePressureInterpolator::~CompressibleOffsetSquarePressureInterpolator()
 = default;
 //////////////////////////////////////////////////////////////////////////
-InterpolationProcessorPtr CompressibleOffsetSquarePressureInterpolationProcessor::clone()
+InterpolationProcessorPtr CompressibleOffsetSquarePressureInterpolator::clone()
 {
-   InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new CompressibleOffsetSquarePressureInterpolationProcessor(this->omegaC, this->omegaF));
+   InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new CompressibleOffsetSquarePressureInterpolator(this->omegaC, this->omegaF));
    if (bulkOmegaToOmega)
    {
-      dynamicPointerCast<CompressibleOffsetSquarePressureInterpolationProcessor>(iproc)->OxxPyyPzzC = omegaC;
-      dynamicPointerCast<CompressibleOffsetSquarePressureInterpolationProcessor>(iproc)->OxxPyyPzzF = omegaF;
+      dynamicPointerCast<CompressibleOffsetSquarePressureInterpolator>(iproc)->OxxPyyPzzC = omegaC;
+      dynamicPointerCast<CompressibleOffsetSquarePressureInterpolator>(iproc)->OxxPyyPzzF = omegaF;
    }
    else
    {
-      dynamicPointerCast<CompressibleOffsetSquarePressureInterpolationProcessor>(iproc)->OxxPyyPzzC = c1o1;
-      dynamicPointerCast<CompressibleOffsetSquarePressureInterpolationProcessor>(iproc)->OxxPyyPzzF = c1o1;
+      dynamicPointerCast<CompressibleOffsetSquarePressureInterpolator>(iproc)->OxxPyyPzzC = c1o1;
+      dynamicPointerCast<CompressibleOffsetSquarePressureInterpolator>(iproc)->OxxPyyPzzF = c1o1;
    }
    return iproc;
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetSquarePressureInterpolationProcessor::setOmegas( real omegaC, real omegaF )
+void CompressibleOffsetSquarePressureInterpolator::setOmegas( real omegaC, real omegaF )
 {
    this->omegaC = omegaC;
    this->omegaF = omegaF;
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetSquarePressureInterpolationProcessor::setOffsets(real xoff, real yoff, real zoff)
+void CompressibleOffsetSquarePressureInterpolator::setOffsets(real xoff, real yoff, real zoff)
 {
    this->xoff = xoff;
    this->yoff = yoff;
@@ -55,7 +55,7 @@ void CompressibleOffsetSquarePressureInterpolationProcessor::setOffsets(real xof
    this->zoff_sq = zoff * zoff;
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetSquarePressureInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff)
+void CompressibleOffsetSquarePressureInterpolator::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff)
 {
    setOffsets(xoff, yoff, zoff);
    calcInterpolatedCoefficiets(icellC, omegaC, c1o2);
@@ -69,14 +69,14 @@ void CompressibleOffsetSquarePressureInterpolationProcessor::interpolateCoarseTo
    calcInterpolatedNodeCF(icellF.TNE, omegaF,  c1o4,  c1o4,  c1o4, calcPressTNE(),  c1o1,  c1o1,  c1o1);
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetSquarePressureInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff)
+void CompressibleOffsetSquarePressureInterpolator::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff)
 {
    setOffsets(xoff, yoff, zoff);
    calcInterpolatedCoefficiets(icellF, omegaF, c2o1);
    calcInterpolatedNodeFC(icellC, omegaC);
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetSquarePressureInterpolationProcessor::calcMoments(const real* const f, real omega, real& press, real& vx1, real& vx2, real& vx3, 
+void CompressibleOffsetSquarePressureInterpolator::calcMoments(const real* const f, real omega, real& press, real& vx1, real& vx2, real& vx3, 
                                                     real& kxy, real& kyz, real& kxz, real& kxxMyy, real& kxxMzz)
 {
    using namespace D3Q27System;
@@ -94,7 +94,7 @@ void CompressibleOffsetSquarePressureInterpolationProcessor::calcMoments(const r
    kxxMzz = -c3o1/c2o1*omega*((((f[DIR_MP0]+f[DIR_PM0])-(f[DIR_0MM]+f[DIR_0PP]))+((f[DIR_MM0]+f[DIR_PP0])-(f[DIR_0MP]+f[DIR_0PM])))+((f[DIR_M00]+f[DIR_P00])-(f[DIR_00M]+f[DIR_00P]))/(c1o1 + drho)-(vx1*vx1-vx3*vx3));
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetSquarePressureInterpolationProcessor::calcInterpolatedCoefficiets(const D3Q27ICell& icell, real omega, real eps_new)
+void CompressibleOffsetSquarePressureInterpolator::calcInterpolatedCoefficiets(const D3Q27ICell& icell, real omega, real eps_new)
 {
    real        vx1_SWT,vx2_SWT,vx3_SWT;
    real        vx1_NWT,vx2_NWT,vx3_NWT;
@@ -475,7 +475,7 @@ void CompressibleOffsetSquarePressureInterpolationProcessor::calcInterpolatedCoe
    yz_TNW =   c1o16*eps_new *((                bxyz +     cxyz)/(c72o1*o));
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetSquarePressureInterpolationProcessor::calcInterpolatedNodeCF(real* f, real omega, real x, real y, real z, real press, real xs, real ys, real zs)
+void CompressibleOffsetSquarePressureInterpolator::calcInterpolatedNodeCF(real* f, real omega, real x, real y, real z, real press, real xs, real ys, real zs)
 {
    using namespace D3Q27System;
    using namespace vf::lbm::dir;
@@ -812,8 +812,8 @@ void CompressibleOffsetSquarePressureInterpolationProcessor::calcInterpolatedNod
    f[DIR_MMM]  = mfaaa;
 }
 //////////////////////////////////////////////////////////////////////////
-//Position SWB -c1o4, -c1o4, -c1o4
-real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressBSW()
+//Position SWB -0.25, -0.25, -0.25
+real CompressibleOffsetSquarePressureInterpolator::calcPressBSW()
 {
    return   press_SWT * (c9o64 + c3o16 * xoff + c3o16 * yoff - c9o16 * zoff) +
       press_NWT * (c3o64 + c1o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
@@ -826,7 +826,7 @@ real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressBSW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SWT -0.25, -0.25, 0.25
-real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressTSW()
+real CompressibleOffsetSquarePressureInterpolator::calcPressTSW()
 {
    return   press_SWT * (c27o64 + c9o16 * xoff + c9o16 * yoff - c9o16 * zoff) +
       press_NWT * (c9o64 + c3o16 * xoff - c9o16 * yoff - c3o16 * zoff) +
@@ -839,7 +839,7 @@ real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressTSW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SET 0.25, -0.25, 0.25
-real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressTSE()
+real CompressibleOffsetSquarePressureInterpolator::calcPressTSE()
 {
    return   press_SET * (c27o64 - c9o16 * xoff + c9o16 * yoff - c9o16 * zoff) +
       press_NET * (c9o64 - c3o16 * xoff - c9o16 * yoff - c3o16 * zoff) +
@@ -852,7 +852,7 @@ real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressTSE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SEB 0.25, -0.25, -0.25
-real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressBSE()
+real CompressibleOffsetSquarePressureInterpolator::calcPressBSE()
 {
    return   press_SET * (c9o64 - c3o16 * xoff + c3o16 * yoff - c9o16 * zoff) +
       press_NET * (c3o64 - c1o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
@@ -865,7 +865,7 @@ real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressBSE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NWB -0.25, 0.25, -0.25
-real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressBNW()
+real CompressibleOffsetSquarePressureInterpolator::calcPressBNW()
 {
    return   press_NWT * (c9o64 + c3o16 * xoff - c3o16 * yoff - c9o16 * zoff) +
       press_NET * (c3o64 - c3o16 * xoff - c1o16 * yoff - c3o16 * zoff) +
@@ -878,7 +878,7 @@ real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressBNW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NWT -0.25, 0.25, 0.25
-real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressTNW()
+real CompressibleOffsetSquarePressureInterpolator::calcPressTNW()
 {
    return   press_NWT * (c27o64 + c9o16 * xoff - c9o16 * yoff - c9o16 * zoff) +
       press_NET * (c9o64 - c9o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
@@ -891,7 +891,7 @@ real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressTNW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NET 0.25, 0.25, 0.25
-real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressTNE()
+real CompressibleOffsetSquarePressureInterpolator::calcPressTNE()
 {
    return   press_NET * (c27o64 - c9o16 * xoff - c9o16 * yoff - c9o16 * zoff) +
       press_NWT * (c9o64 + c9o16 * xoff - c3o16 * yoff - c3o16 * zoff) +
@@ -904,7 +904,7 @@ real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressTNE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NEB 0.25, 0.25, -0.25
-real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressBNE()
+real CompressibleOffsetSquarePressureInterpolator::calcPressBNE()
 {
    return   press_NET * (c9o64 - c3o16 * xoff - c3o16 * yoff - c9o16 * zoff) +
       press_NWT * (c3o64 + c3o16 * xoff - c1o16 * yoff - c3o16 * zoff) +
@@ -917,7 +917,7 @@ real CompressibleOffsetSquarePressureInterpolationProcessor::calcPressBNE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position C 0.0, 0.0, 0.0
-void CompressibleOffsetSquarePressureInterpolationProcessor::calcInterpolatedNodeFC(real* f, real omega)
+void CompressibleOffsetSquarePressureInterpolator::calcInterpolatedNodeFC(real* f, real omega)
 {
    using namespace D3Q27System;
    using namespace vf::lbm::dir;
@@ -1266,14 +1266,14 @@ void CompressibleOffsetSquarePressureInterpolationProcessor::calcInterpolatedNod
    f[DIR_MMM]  = mfaaa;
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetSquarePressureInterpolationProcessor::calcInterpolatedVelocity(real x, real y, real z, real& vx1, real& vx2, real& vx3)
+void CompressibleOffsetSquarePressureInterpolator::calcInterpolatedVelocity(real x, real y, real z, real& vx1, real& vx2, real& vx3)
 {
 	vx1  = a0 + ax*x + ay*y + az*z + axx*x*x + ayy*y*y + azz*z*z + axy*x*y + axz*x*z + ayz*y*z+axyz*x*y*z;
 	vx2  = b0 + bx*x + by*y + bz*z + bxx*x*x + byy*y*y + bzz*z*z + bxy*x*y + bxz*x*z + byz*y*z+bxyz*x*y*z;
 	vx3  = c0 + cx*x + cy*y + cz*z + cxx*x*x + cyy*y*y + czz*z*z + cxy*x*y + cxz*x*z + cyz*y*z+cxyz*x*y*z;
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetSquarePressureInterpolationProcessor::calcInterpolatedShearStress(real x, real y, real z,real& tauxx, real& tauyy, real& tauzz,real& tauxy, real& tauxz, real& tauyz)
+void CompressibleOffsetSquarePressureInterpolator::calcInterpolatedShearStress(real x, real y, real z,real& tauxx, real& tauyy, real& tauzz,real& tauxy, real& tauxz, real& tauyz)
 {
 	tauxx=ax+c2o1*axx*x+axy*y+axz*z+axyz*y*z;
 	tauyy=by+c2o1*byy*y+bxy*x+byz*z+bxyz*x*z;
@@ -1283,7 +1283,7 @@ void CompressibleOffsetSquarePressureInterpolationProcessor::calcInterpolatedShe
 	tauyz=c1o2*((bz+c2o1*bzz*z+bxz*x+byz*y+bxyz*x*y)+(cy+c2o1*cyy*y+cxy*x+cyz*z+cxyz*x*z));
 }
 //////////////////////////////////////////////////////////////////////////
-void CompressibleOffsetSquarePressureInterpolationProcessor::setBulkOmegaToOmega(bool value)
+void CompressibleOffsetSquarePressureInterpolator::setBulkOmegaToOmega(bool value)
 {
    bulkOmegaToOmega = value;
 }
diff --git a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetSquarePressureInterpolationProcessor.h b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetSquarePressureInterpolator.h
similarity index 84%
rename from src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetSquarePressureInterpolationProcessor.h
rename to src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetSquarePressureInterpolator.h
index d9285289f63e7dfca694342df092b6e5f4ecb4d5..8a6308f947f79305079b1fa45edff0fb9c703a55 100644
--- a/src/cpu/VirtualFluidsCore/LBM/CompressibleOffsetSquarePressureInterpolationProcessor.h
+++ b/src/cpu/VirtualFluidsCore/LBM/Interpolation/CompressibleOffsetSquarePressureInterpolator.h
@@ -1,7 +1,7 @@
 #ifndef CompressibleOffsetSquarePressureInterpolationProcessor_H_
 #define CompressibleOffsetSquarePressureInterpolationProcessor_H_
 
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27System.h"
 
 //////////////////////////////////////////////////////////////////////////
@@ -9,14 +9,14 @@
 //super compact interpolation method by Martin Geier
 //////////////////////////////////////////////////////////////////////////
 
-class CompressibleOffsetSquarePressureInterpolationProcessor;
+class CompressibleOffsetSquarePressureInterpolator;
 
-class CompressibleOffsetSquarePressureInterpolationProcessor : public InterpolationProcessor
+class CompressibleOffsetSquarePressureInterpolator : public Interpolator
 {
 public:
-   CompressibleOffsetSquarePressureInterpolationProcessor();
-   CompressibleOffsetSquarePressureInterpolationProcessor(real omegaC, real omegaF);
-   ~CompressibleOffsetSquarePressureInterpolationProcessor() override;
+   CompressibleOffsetSquarePressureInterpolator();
+   CompressibleOffsetSquarePressureInterpolator(real omegaC, real omegaF);
+   ~CompressibleOffsetSquarePressureInterpolator() override;
    InterpolationProcessorPtr clone() override;
    void setOmegas(real omegaC, real omegaF) override;
    void interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF) override;
@@ -68,12 +68,12 @@ private:
 };
 
 //////////////////////////////////////////////////////////////////////////
-inline void CompressibleOffsetSquarePressureInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF)
+inline void CompressibleOffsetSquarePressureInterpolator::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF)
 {
    this->interpolateCoarseToFine(icellC, icellF, 0.0, 0.0, 0.0);
 }
 //////////////////////////////////////////////////////////////////////////
-inline void CompressibleOffsetSquarePressureInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC)
+inline void CompressibleOffsetSquarePressureInterpolator::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC)
 {
    this->interpolateFineToCoarse(icellF, icellC, 0.0, 0.0, 0.0);
 }
diff --git a/src/cpu/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp b/src/cpu/VirtualFluidsCore/LBM/Interpolation/IncompressibleOffsetInterpolator.cpp
similarity index 95%
rename from src/cpu/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp
rename to src/cpu/VirtualFluidsCore/LBM/Interpolation/IncompressibleOffsetInterpolator.cpp
index 26635dbac5d4b2844e6f0205f30a063c5533d612..0cd44125559e1ccf2ed0704f1a7214888a27739d 100644
--- a/src/cpu/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.cpp
+++ b/src/cpu/VirtualFluidsCore/LBM/Interpolation/IncompressibleOffsetInterpolator.cpp
@@ -1,31 +1,31 @@
-#include "IncompressibleOffsetInterpolationProcessor.h"
+#include "IncompressibleOffsetInterpolator.h"
 #include "D3Q27System.h"
 
 
 
 //////////////////////////////////////////////////////////////////////////
-IncompressibleOffsetInterpolationProcessor::IncompressibleOffsetInterpolationProcessor(real omegaC, real omegaF)
+IncompressibleOffsetInterpolator::IncompressibleOffsetInterpolator(real omegaC, real omegaF)
    : omegaC(omegaC), omegaF(omegaF)
 {
 
 }
 
 //////////////////////////////////////////////////////////////////////////
-InterpolationProcessorPtr IncompressibleOffsetInterpolationProcessor::clone()
+InterpolationProcessorPtr IncompressibleOffsetInterpolator::clone()
 {
-   InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new IncompressibleOffsetInterpolationProcessor(this->omegaC, this->omegaF));
+   InterpolationProcessorPtr iproc = InterpolationProcessorPtr (new IncompressibleOffsetInterpolator(this->omegaC, this->omegaF));
    //dynamicPointerCast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingC = forcingC;
    //dynamicPointerCast<D3Q27IncompressibleOffsetInterpolationProcessor>(iproc)->forcingF = forcingF;
    return iproc;
 }
 //////////////////////////////////////////////////////////////////////////
-void IncompressibleOffsetInterpolationProcessor::setOmegas( real omegaC, real omegaF )
+void IncompressibleOffsetInterpolator::setOmegas( real omegaC, real omegaF )
 {
    this->omegaC = omegaC;
    this->omegaF = omegaF;
 }
 //////////////////////////////////////////////////////////////////////////
-void IncompressibleOffsetInterpolationProcessor::setOffsets(real xoff, real yoff, real zoff)
+void IncompressibleOffsetInterpolator::setOffsets(real xoff, real yoff, real zoff)
 {
    this->xoff = xoff;
    this->yoff = yoff;
@@ -35,7 +35,7 @@ void IncompressibleOffsetInterpolationProcessor::setOffsets(real xoff, real yoff
    this->zoff_sq = zoff * zoff;
 }
 //////////////////////////////////////////////////////////////////////////
-void IncompressibleOffsetInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff)
+void IncompressibleOffsetInterpolator::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF, real xoff, real yoff, real zoff)
 {
     using namespace vf::basics::constant;
 
@@ -51,14 +51,14 @@ void IncompressibleOffsetInterpolationProcessor::interpolateCoarseToFine(D3Q27IC
    calcInterpolatedNode(icellF.TNE, omegaF,  c1o4,  c1o4,  c1o4, calcPressTNE(),  c1o1,  c1o1,  c1o1);
 }
 //////////////////////////////////////////////////////////////////////////
-void IncompressibleOffsetInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff)
+void IncompressibleOffsetInterpolator::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff)
 {
    setOffsets(xoff, yoff, zoff);
    calcInterpolatedCoefficiets(icellF, omegaF, vf::basics::constant::c2o1);
    calcInterpolatedNodeFC(icellC, omegaC);
 }
 //////////////////////////////////////////////////////////////////////////
-void IncompressibleOffsetInterpolationProcessor::calcMoments(const real* const f, real omega, real& press, real& vx1, real& vx2, real& vx3, 
+void IncompressibleOffsetInterpolator::calcMoments(const real* const f, real omega, real& press, real& vx1, real& vx2, real& vx3, 
                                                     real& kxy, real& kyz, real& kxz, real& kxxMyy, real& kxxMzz)
 {
    using namespace D3Q27System;
@@ -104,7 +104,7 @@ void IncompressibleOffsetInterpolationProcessor::calcMoments(const real* const f
    //UBLOG(logINFO,"f[TN]  = " << f[TN] << " TN  = " << TN);
 }
 //////////////////////////////////////////////////////////////////////////
-void IncompressibleOffsetInterpolationProcessor::calcInterpolatedCoefficiets(const D3Q27ICell& icell, real omega, real eps_new)
+void IncompressibleOffsetInterpolator::calcInterpolatedCoefficiets(const D3Q27ICell& icell, real omega, real eps_new)
 {
     using namespace vf::basics::constant;
 
@@ -532,7 +532,7 @@ void IncompressibleOffsetInterpolationProcessor::calcInterpolatedCoefficiets(con
    yz_TNW =   c1o16*eps_new *((                bxyz +     cxyz)/(c72o1*o));
 }
 //////////////////////////////////////////////////////////////////////////
-void IncompressibleOffsetInterpolationProcessor::calcInterpolatedNode(real* f, real  /*omega*/, real  /*x*/, real  /*y*/, real  /*z*/, real press, real xs, real ys, real zs)
+void IncompressibleOffsetInterpolator::calcInterpolatedNode(real* f, real  /*omega*/, real  /*x*/, real  /*y*/, real  /*z*/, real press, real xs, real ys, real zs)
 {
    using namespace D3Q27System;
    using namespace vf::lbm::dir;
@@ -581,7 +581,7 @@ void IncompressibleOffsetInterpolationProcessor::calcInterpolatedNode(real* f, r
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SWB -0.25, -0.25, -0.25
-real IncompressibleOffsetInterpolationProcessor::calcPressBSW()
+real IncompressibleOffsetInterpolator::calcPressBSW()
 {
     using namespace vf::basics::constant;
 
@@ -596,7 +596,7 @@ real IncompressibleOffsetInterpolationProcessor::calcPressBSW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SWT -0.25, -0.25, 0.25
-real IncompressibleOffsetInterpolationProcessor::calcPressTSW()
+real IncompressibleOffsetInterpolator::calcPressTSW()
 {
     using namespace vf::basics::constant;
 
@@ -611,7 +611,7 @@ real IncompressibleOffsetInterpolationProcessor::calcPressTSW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SET 0.25, -0.25, 0.25
-real IncompressibleOffsetInterpolationProcessor::calcPressTSE()
+real IncompressibleOffsetInterpolator::calcPressTSE()
 {
     using namespace vf::basics::constant;
 
@@ -626,7 +626,7 @@ real IncompressibleOffsetInterpolationProcessor::calcPressTSE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position SEB 0.25, -0.25, -0.25
-real IncompressibleOffsetInterpolationProcessor::calcPressBSE()
+real IncompressibleOffsetInterpolator::calcPressBSE()
 {
     using namespace vf::basics::constant;
 
@@ -641,7 +641,7 @@ real IncompressibleOffsetInterpolationProcessor::calcPressBSE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NWB -0.25, 0.25, -0.25
-real IncompressibleOffsetInterpolationProcessor::calcPressBNW()
+real IncompressibleOffsetInterpolator::calcPressBNW()
 {
     using namespace vf::basics::constant;
 
@@ -656,7 +656,7 @@ real IncompressibleOffsetInterpolationProcessor::calcPressBNW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NWT -0.25, 0.25, 0.25
-real IncompressibleOffsetInterpolationProcessor::calcPressTNW()
+real IncompressibleOffsetInterpolator::calcPressTNW()
 {
     using namespace vf::basics::constant;
 
@@ -671,7 +671,7 @@ real IncompressibleOffsetInterpolationProcessor::calcPressTNW()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NET 0.25, 0.25, 0.25
-real IncompressibleOffsetInterpolationProcessor::calcPressTNE()
+real IncompressibleOffsetInterpolator::calcPressTNE()
 {
     using namespace vf::basics::constant;
 
@@ -686,7 +686,7 @@ real IncompressibleOffsetInterpolationProcessor::calcPressTNE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position NEB 0.25, 0.25, -0.25
-real IncompressibleOffsetInterpolationProcessor::calcPressBNE()
+real IncompressibleOffsetInterpolator::calcPressBNE()
 {
     using namespace vf::basics::constant;
 
@@ -701,7 +701,7 @@ real IncompressibleOffsetInterpolationProcessor::calcPressBNE()
 }
 //////////////////////////////////////////////////////////////////////////
 //Position C 0.0, 0.0, 0.0
-void IncompressibleOffsetInterpolationProcessor::calcInterpolatedNodeFC(real* f, real omega)
+void IncompressibleOffsetInterpolator::calcInterpolatedNodeFC(real* f, real omega)
 {
    using namespace D3Q27System;
    using namespace vf::lbm::dir;
@@ -792,14 +792,14 @@ void IncompressibleOffsetInterpolationProcessor::calcInterpolatedNodeFC(real* f,
    f[DIR_000] = f_ZERO + feq[DIR_000];
 }
 //////////////////////////////////////////////////////////////////////////
-void IncompressibleOffsetInterpolationProcessor::calcInterpolatedVelocity(real x, real y, real z, real& vx1, real& vx2, real& vx3)
+void IncompressibleOffsetInterpolator::calcInterpolatedVelocity(real x, real y, real z, real& vx1, real& vx2, real& vx3)
 {
 	vx1  = a0 + ax*x + ay*y + az*z + axx*x*x + ayy*y*y + azz*z*z + axy*x*y + axz*x*z + ayz*y*z+axyz*x*y*z;
 	vx2  = b0 + bx*x + by*y + bz*z + bxx*x*x + byy*y*y + bzz*z*z + bxy*x*y + bxz*x*z + byz*y*z+bxyz*x*y*z;
 	vx3  = c0 + cx*x + cy*y + cz*z + cxx*x*x + cyy*y*y + czz*z*z + cxy*x*y + cxz*x*z + cyz*y*z+cxyz*x*y*z;
 }
 //////////////////////////////////////////////////////////////////////////
-void IncompressibleOffsetInterpolationProcessor::calcInterpolatedShearStress(real x, real y, real z,real& tauxx, real& tauyy, real& tauzz,real& tauxy, real& tauxz, real& tauyz)
+void IncompressibleOffsetInterpolator::calcInterpolatedShearStress(real x, real y, real z,real& tauxx, real& tauyy, real& tauzz,real& tauxy, real& tauxz, real& tauyz)
 {
     using namespace vf::basics::constant;
 
diff --git a/src/cpu/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.h b/src/cpu/VirtualFluidsCore/LBM/Interpolation/IncompressibleOffsetInterpolator.h
similarity index 83%
rename from src/cpu/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.h
rename to src/cpu/VirtualFluidsCore/LBM/Interpolation/IncompressibleOffsetInterpolator.h
index 866c0f6933e67d66b3b36d65a0f484ba2d8cbf86..2fee5d62c30162e0f2af514e3551c8aa93ca9dab 100644
--- a/src/cpu/VirtualFluidsCore/LBM/IncompressibleOffsetInterpolationProcessor.h
+++ b/src/cpu/VirtualFluidsCore/LBM/Interpolation/IncompressibleOffsetInterpolator.h
@@ -1,7 +1,7 @@
 #ifndef IncompressibleOffsetInterpolationProcessor_H_
 #define IncompressibleOffsetInterpolationProcessor_H_
 
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "D3Q27System.h"
 
 //////////////////////////////////////////////////////////////////////////
@@ -9,15 +9,15 @@
 //super compact interpolation method by Martin Geier
 //////////////////////////////////////////////////////////////////////////
 
-class IncompressibleOffsetInterpolationProcessor;
-using D3Q27IncompressibleOffsetInterpolationProcessorPtr = SPtr<IncompressibleOffsetInterpolationProcessor>;
+class IncompressibleOffsetInterpolator;
+using D3Q27IncompressibleOffsetInterpolationProcessorPtr = SPtr<IncompressibleOffsetInterpolator>;
 
-class IncompressibleOffsetInterpolationProcessor : public InterpolationProcessor
+class IncompressibleOffsetInterpolator : public Interpolator
 {
 public:
-   IncompressibleOffsetInterpolationProcessor() = default;
-   IncompressibleOffsetInterpolationProcessor(real omegaC, real omegaF);
-   ~IncompressibleOffsetInterpolationProcessor() override = default;
+   IncompressibleOffsetInterpolator() = default;
+   IncompressibleOffsetInterpolator(real omegaC, real omegaF);
+   ~IncompressibleOffsetInterpolator() override = default;
    InterpolationProcessorPtr clone() override;
    void setOmegas(real omegaC, real omegaF) override;
    void interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF) override;
@@ -25,7 +25,7 @@ public:
    void interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC) override; 
    void interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC, real xoff, real yoff, real zoff) override; 
    //real forcingC, forcingF;
-protected:   
+protected:
 private:
    real omegaC{0.0}, omegaF{0.0};
    real a0, ax, ay, az, axx, ayy, azz, axy, axz, ayz, b0, bx, by, bz, bxx, byy, bzz, bxy, bxz, byz, c0, cx, cy, cz, cxx, cyy, czz, cxy, cxz, cyz, axyz, bxyz, cxyz;
@@ -64,12 +64,12 @@ private:
 };
 
 //////////////////////////////////////////////////////////////////////////
-inline void IncompressibleOffsetInterpolationProcessor::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF)
+inline void IncompressibleOffsetInterpolator::interpolateCoarseToFine(D3Q27ICell& icellC, D3Q27ICell& icellF)
 {
    this->interpolateCoarseToFine(icellC, icellF, 0.0, 0.0, 0.0);
 }
 //////////////////////////////////////////////////////////////////////////
-inline void IncompressibleOffsetInterpolationProcessor::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC)
+inline void IncompressibleOffsetInterpolator::interpolateFineToCoarse(D3Q27ICell& icellF, real* icellC)
 {
    this->interpolateFineToCoarse(icellF, icellC, 0.0, 0.0, 0.0);
 }
diff --git a/src/cpu/VirtualFluidsCore/LBM/InterpolationProcessor.cpp b/src/cpu/VirtualFluidsCore/LBM/Interpolation/Interpolator.cpp
similarity index 73%
rename from src/cpu/VirtualFluidsCore/LBM/InterpolationProcessor.cpp
rename to src/cpu/VirtualFluidsCore/LBM/Interpolation/Interpolator.cpp
index a82f397c9f89d7605d8409b8f32f8d87a8f8a402..f28b1efed4836ca71b09a390078dd2aaf5463710 100644
--- a/src/cpu/VirtualFluidsCore/LBM/InterpolationProcessor.cpp
+++ b/src/cpu/VirtualFluidsCore/LBM/Interpolation/Interpolator.cpp
@@ -1,11 +1,22 @@
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
+
+
+struct Range
+{
+    Range(int maxX1, int maxX2, int maxX3) : m_maxX1(maxX1), m_maxX2(maxX2), m_maxX3(maxX3) {}
+    inline bool operator()(int x1, int x2, int x3)
+    {
+        return x1 >= 0 && x1 < m_maxX1 && x2 >= 0 && x2 < m_maxX2 && x3 >= 0 && x3 < m_maxX3;
+    }
+
+    int m_maxX1;
+    int m_maxX2;
+    int m_maxX3;
+};
+
 
 //////////////////////////////////////////////////////////////////////////
-InterpolationProcessor::InterpolationProcessor() = default;
-//////////////////////////////////////////////////////////////////////////
-InterpolationProcessor::~InterpolationProcessor() = default;
-//////////////////////////////////////////////////////////////////////////
-void InterpolationProcessor::readICell(SPtr<DistributionArray3D> f, D3Q27ICell &icell, int x1, int x2, int x3)
+void Interpolator::readICell(SPtr<DistributionArray3D> f, D3Q27ICell &icell, int x1, int x2, int x3)
 {
     f->getDistribution(icell.BSW, x1, x2, x3);
     f->getDistribution(icell.BSE, x1 + 1, x2, x3);
@@ -17,7 +28,7 @@ void InterpolationProcessor::readICell(SPtr<DistributionArray3D> f, D3Q27ICell &
     f->getDistribution(icell.TNE, x1 + 1, x2 + 1, x3 + 1);
 }
 //////////////////////////////////////////////////////////////////////////
-void InterpolationProcessor::writeICell(SPtr<DistributionArray3D> f, const D3Q27ICell &icell, int x1, int x2, int x3)
+void Interpolator::writeICell(SPtr<DistributionArray3D> f, const D3Q27ICell &icell, int x1, int x2, int x3)
 {
     f->setDistribution(icell.BSW, x1, x2, x3);
     f->setDistribution(icell.BSE, x1 + 1, x2, x3);
@@ -29,7 +40,7 @@ void InterpolationProcessor::writeICell(SPtr<DistributionArray3D> f, const D3Q27
     f->setDistribution(icell.TNE, x1 + 1, x2 + 1, x3 + 1);
 }
 //////////////////////////////////////////////////////////////////////////
-void InterpolationProcessor::writeICellInv(SPtr<DistributionArray3D> f, const D3Q27ICell &icell, int x1, int x2, int x3)
+void Interpolator::writeICellInv(SPtr<DistributionArray3D> f, const D3Q27ICell &icell, int x1, int x2, int x3)
 {
     f->setDistributionInv(icell.BSW, x1, x2, x3);
     f->setDistributionInv(icell.BSE, x1 + 1, x2, x3);
@@ -41,18 +52,18 @@ void InterpolationProcessor::writeICellInv(SPtr<DistributionArray3D> f, const D3
     f->setDistributionInv(icell.TNE, x1 + 1, x2 + 1, x3 + 1);
 }
 //////////////////////////////////////////////////////////////////////////
-void InterpolationProcessor::writeINode(SPtr<DistributionArray3D> f, const real *const inode, int x1, int x2, int x3)
+void Interpolator::writeINode(SPtr<DistributionArray3D> f, const real *const inode, int x1, int x2, int x3)
 {
     f->setDistribution(inode, x1, x2, x3);
 }
 //////////////////////////////////////////////////////////////////////////
-void InterpolationProcessor::writeINodeInv(SPtr<DistributionArray3D> f, const real *const inode, int x1, int x2,
+void Interpolator::writeINodeInv(SPtr<DistributionArray3D> f, const real *const inode, int x1, int x2,
                                            int x3)
 {
     f->setDistributionInv(inode, x1, x2, x3);
 }
 //////////////////////////////////////////////////////////////////////////
-bool InterpolationProcessor::iCellHasSolid(const SPtr<BCArray3D> bcArray, int x1, int x2, int x3)
+bool Interpolator::iCellHasSolid(const SPtr<BCArray3D> bcArray, int x1, int x2, int x3)
 {
     for (int ix3 = x3; ix3 <= x3 + 1; ix3++)
         for (int ix2 = x2; ix2 <= x2 + 1; ix2++)
@@ -63,13 +74,12 @@ bool InterpolationProcessor::iCellHasSolid(const SPtr<BCArray3D> bcArray, int x1
     return false;
 }
 //////////////////////////////////////////////////////////////////////////
-bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SPtr<DistributionArray3D> f,
+bool Interpolator::findNeighborICell(const SPtr<BCArray3D> bcArray, SPtr<DistributionArray3D> f,
                                                D3Q27ICell &icell, int maxX1, int maxX2, int maxX3, int x1, int x2,
                                                int x3, real &xoff, real &yoff, real &zoff)
 {
-    m_maxX1 = maxX1;
-    m_maxX2 = maxX2;
-    m_maxX3 = maxX3;
+
+    Range inRange(maxX1, maxX2, maxX3);
 
     // GoWest
     if (inRange(x1 - 1, x2, x3) && !iCellHasSolid(bcArray, x1 - 1, x2, x3)) {
@@ -80,7 +90,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     }
     // GoEast
     else if (inRange(x1 + 2, x2, x3) &&
-             !iCellHasSolid(bcArray, x1 + 1, x2, x3)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+             !iCellHasSolid(bcArray, x1 + 1, x2, x3)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 + 1, x2, x3);
         xoff = -1;
@@ -96,7 +106,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     }
     // GoNorth
     else if (inRange(x1, x2 + 2, x3) &&
-             !iCellHasSolid(bcArray, x1, x2 + 1, x3)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+             !iCellHasSolid(bcArray, x1, x2 + 1, x3)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1, x2 + 1, x3);
         xoff = 0;
@@ -112,7 +122,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     }
     // GoTop
     else if (inRange(x1, x2, x3 + 2) &&
-             !iCellHasSolid(bcArray, x1, x2, x3 + 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+             !iCellHasSolid(bcArray, x1, x2, x3 + 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1, x2, x3 + 1);
         xoff = 0;
@@ -122,7 +132,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoNW
     else if (inRange(x1 - 1, x2 + 2, x3) &&
              !iCellHasSolid(bcArray, x1 - 1, x2 + 1,
-                            x3)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 - 1, x2 + 1, x3);
         xoff = 1;
@@ -132,7 +142,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoNE
     else if (inRange(x1 + 2, x2 + 2, x3) &&
              !iCellHasSolid(bcArray, x1 + 1, x2 + 1,
-                            x3)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 + 1, x2 + 1, x3);
         xoff = -1;
@@ -142,7 +152,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoSW
     else if (inRange(x1 - 1, x2 - 1, x3) &&
              !iCellHasSolid(bcArray, x1 - 1, x2 - 1,
-                            x3)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 - 1, x2 - 1, x3);
         xoff = 1;
@@ -152,7 +162,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoSE
     else if (inRange(x1 + 2, x2 - 1, x3) &&
              !iCellHasSolid(bcArray, x1 + 1, x2 - 1,
-                            x3)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 + 1, x2 - 1, x3);
         xoff = -1;
@@ -169,7 +179,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoBE
     else if (inRange(x1 + 2, x2, x3 - 1) &&
              !iCellHasSolid(bcArray, x1 + 1, x2,
-                            x3 - 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 - 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 + 1, x2, x3 - 1);
         xoff = -1;
@@ -186,7 +196,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoBN
     else if (inRange(x1, x2 + 2, x3 - 1) &&
              !iCellHasSolid(bcArray, x1, x2 + 1,
-                            x3 - 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 - 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1, x2 + 1, x3 - 1);
         xoff = 0;
@@ -203,7 +213,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoTE
     else if (inRange(x1 + 2, x2, x3 + 2) &&
              !iCellHasSolid(bcArray, x1 + 1, x2,
-                            x3 + 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 + 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 + 1, x2, x3 + 1);
         xoff = -1;
@@ -220,7 +230,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoTN
     else if (inRange(x1, x2 + 2, x3 + 2) &&
              !iCellHasSolid(bcArray, x1, x2 + 1,
-                            x3 + 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 + 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1, x2 + 1, x3 + 1);
         xoff = 0;
@@ -230,7 +240,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoTNW
     else if (inRange(x1 - 1, x2 + 2, x3 + 2) &&
              !iCellHasSolid(bcArray, x1 - 1, x2 + 1,
-                            x3 + 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 + 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 - 1, x2 + 1, x3 + 1);
         xoff = 1;
@@ -240,7 +250,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoTNE
     else if (inRange(x1 + 2, x2 + 2, x3 + 2) &&
              !iCellHasSolid(bcArray, x1 + 1, x2 + 1,
-                            x3 + 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 + 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 + 1, x2 + 1, x3 + 1);
         xoff = -1;
@@ -250,7 +260,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoTSE
     else if (inRange(x1 + 2, x2 - 1, x3 + 2) &&
              !iCellHasSolid(bcArray, x1 + 1, x2 - 1,
-                            x3 + 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 + 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 + 1, x2 - 1, x3 + 1);
         xoff = -1;
@@ -260,7 +270,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoTSW
     else if (inRange(x1 - 1, x2 - 1, x3 + 2) &&
              !iCellHasSolid(bcArray, x1 - 1, x2 - 1,
-                            x3 + 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 + 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 - 1, x2 - 1, x3 + 1);
         xoff = 1;
@@ -270,7 +280,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoBNW
     else if (inRange(x1 - 1, x2 + 2, x3 - 1) &&
              !iCellHasSolid(bcArray, x1 - 1, x2 + 1,
-                            x3 - 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 - 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 - 1, x2 + 1, x3 - 1);
         xoff = 1;
@@ -280,7 +290,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoBNE
     else if (inRange(x1 + 2, x2 + 2, x3 - 1) &&
              !iCellHasSolid(bcArray, x1 + 1, x2 + 1,
-                            x3 - 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 - 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 + 1, x2 + 1, x3 - 1);
         xoff = -1;
@@ -290,7 +300,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoBSE
     else if (inRange(x1 + 2, x2 - 1, x3 - 1) &&
              !iCellHasSolid(bcArray, x1 + 1, x2 - 1,
-                            x3 - 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 - 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 + 1, x2 - 1, x3 - 1);
         xoff = -1;
@@ -300,7 +310,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     // GoBSW
     else if (inRange(x1 - 1, x2 - 1, x3 - 1) &&
              !iCellHasSolid(bcArray, x1 - 1, x2 - 1,
-                            x3 - 1)) // ist �bern�chster Knoten auch im Gebiet (Grundknoten bei 0,0,0
+                            x3 - 1)) // is next but one node in area (base node at 0,0,0)
     {
         readICell(f, icell, x1 - 1, x2 - 1, x3 - 1);
         xoff = 1;
@@ -320,7 +330,7 @@ bool InterpolationProcessor::findNeighborICell(const SPtr<BCArray3D> bcArray, SP
     return true;
 }
 //////////////////////////////////////////////////////////////////////////
-int InterpolationProcessor::iCellHowManySolids(const SPtr<BCArray3D> bcArray, int x1, int x2, int x3)
+int Interpolator::iCellHowManySolids(const SPtr<BCArray3D> bcArray, int x1, int x2, int x3)
 {
     int count = 0;
     for (int ix3 = x3; ix3 <= x3 + 1; ix3++)
diff --git a/src/cpu/VirtualFluidsCore/LBM/InterpolationProcessor.h b/src/cpu/VirtualFluidsCore/LBM/Interpolation/Interpolator.h
similarity index 75%
rename from src/cpu/VirtualFluidsCore/LBM/InterpolationProcessor.h
rename to src/cpu/VirtualFluidsCore/LBM/Interpolation/Interpolator.h
index f298a531b61ca4c4d9ddffc6e2dfeab535be0aa1..81a0d7a363b73a01f079c412b2fd97765841d939 100644
--- a/src/cpu/VirtualFluidsCore/LBM/InterpolationProcessor.h
+++ b/src/cpu/VirtualFluidsCore/LBM/Interpolation/Interpolator.h
@@ -1,5 +1,7 @@
-#ifndef INTERPOLATIONPROCESSOR_H
-#define INTERPOLATIONPROCESSOR_H
+#ifndef CPU_INTERPOLATER_H
+#define CPU_INTERPOLATER_H
+
+#include <memory>
 
 #include "BCArray3D.h"
 #include "BoundaryConditions.h"
@@ -17,17 +19,16 @@ struct D3Q27ICell {
     real BSE[27];
 };
 
-class InterpolationProcessor;
-using InterpolationProcessorPtr = SPtr<InterpolationProcessor>;
+class Interpolator;
+using InterpolationProcessorPtr = std::shared_ptr<Interpolator>;
 
-#include "InterpolationHelper.h"
 
-class InterpolationProcessor
+class Interpolator
 {
 public:
-    InterpolationProcessor();
-    virtual ~InterpolationProcessor();
-    virtual InterpolationProcessorPtr clone()                                    = 0;
+    virtual ~Interpolator() = default;
+    virtual InterpolationProcessorPtr clone() = 0;
+
     virtual void setOmegas(real omegaC, real omegaF)                       = 0;
     virtual void interpolateCoarseToFine(D3Q27ICell &icellC, D3Q27ICell &icellF) = 0;
     virtual void interpolateCoarseToFine(D3Q27ICell &icellC, D3Q27ICell &icellF, real xoff, real yoff,
@@ -52,21 +53,9 @@ protected:
     virtual void calcInterpolatedNodeFC(real *f, real omega) {}
     virtual void calcInterpolatedVelocity(real x, real y, real z, real &vx1, real &vx2, real &vx3) {}
     virtual void calcInterpolatedShearStress(real x, real y, real z, real &tauxx, real &tauyy,
-                                             real &tauzz, real &tauxy, real &tauxz, real &tauyz)
-    {
-    }
+                                             real &tauzz, real &tauxy, real &tauxz, real &tauyz) {}
     virtual void setOffsets(real xoff, real yoff, real zoff) {}
-    friend class InterpolationHelper;
 
-private:
-    bool inRange(int x1, int x2, int x3);
-    int m_maxX1, m_maxX2, m_maxX3;
 };
 
-//////////////////////////////////////////////////////////////////////////
-inline bool InterpolationProcessor::inRange(int x1, int x2, int x3)
-{
-    return x1 >= 0 && x1 < m_maxX1 && x2 >= 0 && x2 < m_maxX2 && x3 >= 0 && x3 < m_maxX3;
-}
-
 #endif
diff --git a/src/cpu/VirtualFluidsCore/LBM/InterpolationHelper.cpp b/src/cpu/VirtualFluidsCore/LBM/InterpolationHelper.cpp
deleted file mode 100644
index f4b54988b4c3c20928f93359b22d74cf671c03e6..0000000000000000000000000000000000000000
--- a/src/cpu/VirtualFluidsCore/LBM/InterpolationHelper.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "InterpolationHelper.h"
-
-InterpolationHelper::InterpolationHelper(InterpolationProcessorPtr iProcessor) : iProcessor(iProcessor) {}
-//////////////////////////////////////////////////////////////////////////
-InterpolationHelper::~InterpolationHelper() = default;
-//////////////////////////////////////////////////////////////////////////
-void InterpolationHelper::interpolate8to1(D3Q27ICell &icellF, real *icellC, real /*x1*/, real /*x2*/,
-                                          real /*x3*/, real omega)
-{
-    iProcessor->calcInterpolatedCoefficiets(icellF, omega, vf::basics::constant::c1o1);
-    iProcessor->calcInterpolatedNodeFC(icellC, omega);
-}
-//////////////////////////////////////////////////////////////////////////
-void InterpolationHelper::interpolate8to1WithVelocity(D3Q27ICell &icellF, real x1, real x2, real x3,
-                                                      real omega, real &vx1, real &vx2, real &vx3)
-{
-    iProcessor->setOffsets(vf::basics::constant::c0o1, vf::basics::constant::c0o1, vf::basics::constant::c0o1);
-    iProcessor->calcInterpolatedCoefficiets(icellF, omega, vf::basics::constant::c0o1);
-    iProcessor->calcInterpolatedVelocity(x1, x2, x3, vx1, vx2, vx3);
-}
-//////////////////////////////////////////////////////////////////////////
-void InterpolationHelper::interpolate8to1WithVelocityWithShearStress(D3Q27ICell &icellF, real x1, real x2,
-                                                                     real x3, real omega, real &vx1,
-                                                                     real &vx2, real &vx3, real &tauxx,
-                                                                     real &tauyy, real &tauzz, real &tauxy,
-                                                                     real &tauxz, real &tauyz)
-{
-    iProcessor->setOffsets(vf::basics::constant::c0o1, vf::basics::constant::c0o1, vf::basics::constant::c0o1);
-    iProcessor->calcInterpolatedCoefficiets(icellF, omega, vf::basics::constant::c0o1);
-    iProcessor->calcInterpolatedVelocity(x1, x2, x3, vx1, vx2, vx3);
-    iProcessor->calcInterpolatedShearStress(x1, x2, x3, tauxx, tauyy, tauzz, tauxy, tauxz, tauyz);
-}
-
-//////////////////////////////////////////////////////////////////////////
diff --git a/src/cpu/VirtualFluidsCore/LBM/InterpolationHelper.h b/src/cpu/VirtualFluidsCore/LBM/InterpolationHelper.h
deleted file mode 100644
index b67e8d18ac5c54c775c098aad484d4b5657a917b..0000000000000000000000000000000000000000
--- a/src/cpu/VirtualFluidsCore/LBM/InterpolationHelper.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef D3Q27InterpolationHelper_H_
-#define D3Q27InterpolationHelper_H_
-
-#include "InterpolationProcessor.h"
-
-class InterpolationHelper;
-using InterpolationHelperPtr = SPtr<InterpolationHelper>;
-
-class InterpolationHelper
-{
-public:
-    InterpolationHelper(InterpolationProcessorPtr iProcessor);
-    ~InterpolationHelper();
-    void interpolate8to1(D3Q27ICell &icellF, real *icellC, real x1, real x2, real x3, real omega);
-    void interpolate8to1WithVelocity(D3Q27ICell &icellF, real x1, real x2, real x3, real omega, real &vx1,
-                                     real &vx2, real &vx3);
-    void interpolate8to1WithVelocityWithShearStress(D3Q27ICell &icellF, real x1, real x2, real x3, real omega,
-                                                    real &vx1, real &vx2, real &vx3, real &tauxx,
-                                                    real &tauyy, real &tauzz, real &tauxy, real &tauxz,
-                                                    real &tauyz);
-
-protected:
-private:
-    InterpolationProcessorPtr iProcessor;
-};
-
-#endif
diff --git a/src/cpu/VirtualFluidsCore/Parallel/MetisPartitioner.cpp b/src/cpu/VirtualFluidsCore/Parallel/MetisPartitioner.cpp
index 51d74e3bf1b5d5109904e1fa581bcff366fad505..a2da1904ecbfda60be9139aa9ded1cb1b5efc15f 100644
--- a/src/cpu/VirtualFluidsCore/Parallel/MetisPartitioner.cpp
+++ b/src/cpu/VirtualFluidsCore/Parallel/MetisPartitioner.cpp
@@ -17,8 +17,6 @@ MetisPartitioner::MetisPartitioner()
     // options[METIS_OPTION_IPTYPE] = METIS_IPTYPE_GROW;
 }
 //////////////////////////////////////////////////////////////////////////
-MetisPartitioner::~MetisPartitioner() = default;
-//////////////////////////////////////////////////////////////////////////
 idx_t *MetisPartitioner::getMetisOptions() { return options; }
 void MetisPartitioner::setMetisOptions(int option, idx_t value) { options[option] = value; }
 //////////////////////////////////////////////////////////////////////////
diff --git a/src/cpu/VirtualFluidsCore/Parallel/MetisPartitioner.h b/src/cpu/VirtualFluidsCore/Parallel/MetisPartitioner.h
index 8fd7a82d52e1ac4c7199d5b2e1a1cbe43ea25369..18e222760bf4a0c93db17ea6fa96a6afdf7f3313 100644
--- a/src/cpu/VirtualFluidsCore/Parallel/MetisPartitioner.h
+++ b/src/cpu/VirtualFluidsCore/Parallel/MetisPartitioner.h
@@ -10,7 +10,6 @@
 
 #if defined VF_METIS
 
-#include "basics/utilities/UbLogger.h"
 #include "basics/utilities/UbSystem.h"
 #include "metis.h"
 #include <PointerDefinitions.h>
@@ -24,7 +23,6 @@ public:
 
 public:
     MetisPartitioner();
-    virtual ~MetisPartitioner();
     idx_t *getMetisOptions();
     void setMetisOptions(int option, idx_t value);
     int partition(int nofParts, PartType ptype);
@@ -47,9 +45,9 @@ public:
     real_t *
         ubvec; // This is an array of size ncon that specifies the allowed load imbalance tolerance for each constraint.
     // For the ith partition and jth constraint the allowed weight is the ubvec[j]*tpwgts[i*ncon+j] fraction
-    // of the jth’s constraint total weight. The load imbalances must be greater than 1.0.
+    // of the jths constraint total weight. The load imbalances must be greater than 1.0.
     // A NULL value can be passed indicating that the load imbalance tolerance for each constraint should
-    // be 1.001 (for ncon=1) or 1.01 (for ncon¿1).
+    // be 1.001 (for ncon=1) or 1.01 (for ncon1).
 
     std::vector<idx_t>
         part; // This is a vector of size n that upon successful completion stores the partition vector of the graph.
diff --git a/src/cpu/VirtualFluidsCore/Simulation/Grid3D.cpp b/src/cpu/VirtualFluidsCore/Simulation/Grid3D.cpp
index a214b4bd0137b2bf319925b519f1dcb77fabded4..ed467597f473119fe1569fe2d198507ac0744909 100644
--- a/src/cpu/VirtualFluidsCore/Simulation/Grid3D.cpp
+++ b/src/cpu/VirtualFluidsCore/Simulation/Grid3D.cpp
@@ -64,10 +64,12 @@ Grid3D::Grid3D(std::shared_ptr<vf::mpi::Communicator> comm, int blockNx1, int bl
 
       blockNx1(blockNx1), blockNx2(blockNx2), blockNx3(blockNx2), nx1(gridNx1), nx2(gridNx2), nx3(gridNx3)
 {
+    using namespace vf::basics::constant;
+
     levelSet.resize(D3Q27System::MAXLEVEL + 1);
     bundle = comm->getBundleID();
     rank  = comm->getProcessID();
-    trafo = std::make_shared<CoordinateTransformation3D>(0.0, 0.0, 0.0, (real)blockNx1, (real)blockNx2,
+    trafo = std::make_shared<CoordinateTransformation3D>(c0o1, c0o1, c0o1, (real)blockNx1, (real)blockNx2,
                                                          (real)blockNx3);
     UbTupleInt3 minInd(0, 0, 0);
     UbTupleInt3 maxInd(gridNx1, gridNx2, gridNx3);
@@ -481,7 +483,8 @@ UbTupleDouble3 Grid3D::getBlockLengths(const SPtr<Block3D> block) const
                        trafo->getX3CoordinateScaling() * delta);
 }
 //////////////////////////////////////////////////////////////////////////
-UbTupleDouble6 Grid3D::getBlockOversize() const { return makeUbTuple(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); }
+using namespace vf::basics::constant;
+UbTupleDouble6 Grid3D::getBlockOversize() const { return makeUbTuple(c0o1, c0o1, c0o1, c0o1, c0o1, c0o1); }
 //////////////////////////////////////////////////////////////////////////
 void Grid3D::setCoordinateTransformator(SPtr<CoordinateTransformation3D> trafo) { this->trafo = trafo; }
 //////////////////////////////////////////////////////////////////////////
@@ -2233,7 +2236,7 @@ int Grid3D::getGhostLayerWidth() const
 //////////////////////////////////////////////////////////////////////////
 void Grid3D::setGhostLayerWidth(int ghostLayerWidth)
 {
-    this->offset = static_cast<real>(ghostLayerWidth) - 0.5;
+    this->offset = static_cast<real>(ghostLayerWidth) - c1o2;
 }
 //////////////////////////////////////////////////////////////////////////
 void Grid3D::setTimeStep(real step) { timeStep = step; }
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/AdjustForcingSimulationObserver.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/AdjustForcingSimulationObserver.cpp
index 2254b9b02ea383e18c654a7569f0e5b2e973c839..3d6feaf15c6555cec3141c7bcc48d9a94db9c91c 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/AdjustForcingSimulationObserver.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/AdjustForcingSimulationObserver.cpp
@@ -18,25 +18,27 @@ AdjustForcingSimulationObserver::AdjustForcingSimulationObserver(SPtr<Grid3D> gr
 
     : SimulationObserver(grid, s), path(path), integrateValues(integrateValues), comm(comm), vx1Targed(vTarged)
 {
+    using namespace  vf::basics::constant;
+
     // cnodes = integrateValues->getCNodes();
     root = comm->isRoot();
 
     Ta = scheduler->getMaxStep();
 
-    Kpcrit = 3.0 / Ta; // 0.3;
-    Tcrit  = 3.0 * Ta; // 30.0;
-    Tn     = 0.5 * Tcrit;
-    Tv     = 0.12 * Tcrit;
+    Kpcrit = c3o1 / Ta; // 0.3;
+    Tcrit  = c3o1 * Ta; // 30.0;
+    Tn     = c1o2 * Tcrit;
+    Tv     = c12o1 / c100o1 * Tcrit;
 
-    Kp = 0.6 * Kpcrit;
+    Kp = c6o1 / c10o1 * Kpcrit;
     Ki = Kp / Tn;
     Kd = Kp * Tv;
 
-    y       = 0;
-    e       = 0;
-    esum    = 0;
-    eold    = 0;
-    forcing = 0;
+    y       = c0o1;
+    e       = c0o1;
+    esum    = c0o1;
+    eold    = c0o1;
+    forcing = c0o1;
 
     if (root) {
         std::string fname = path + "/forcing/forcing.csv";
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/AverageValuesSimulationObserver.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/AverageValuesSimulationObserver.cpp
index 1adf3ad9944a49c8065756988e95ab837e9f6d15..6213f5713c281b18dd516d304cd47f0d3195f9f3 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/AverageValuesSimulationObserver.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/AverageValuesSimulationObserver.cpp
@@ -78,6 +78,8 @@ void AverageValuesSimulationObserver::update(real step)
 
 void AverageValuesSimulationObserver::resetDataRMS(real step)
 {
+    using namespace vf::basics::constant;
+    
     resetStepRMS = (int)step;
 
     for (int level = minInitLevel; level <= maxInitLevel; level++) {
@@ -103,13 +105,13 @@ void AverageValuesSimulationObserver::resetDataRMS(real step)
                                 //////////////////////////////////////////////////////////////////////////
                                 // compute average values
                                 //////////////////////////////////////////////////////////////////////////
-                                (*av)(AvVxx, ix1, ix2, ix3)  = 0.0;
-                                (*av)(AvVyy, ix1, ix2, ix3)  = 0.0;
-                                (*av)(AvVzz, ix1, ix2, ix3)  = 0.0;
-                                (*av)(AvVxy, ix1, ix2, ix3)  = 0.0;
-                                (*av)(AvVxz, ix1, ix2, ix3)  = 0.0;
-                                (*av)(AvVyz, ix1, ix2, ix3)  = 0.0;
-                                (*av)(AvPrms, ix1, ix2, ix3) = 0.0;
+                                (*av)(AvVxx, ix1, ix2, ix3)  = c0o1;
+                                (*av)(AvVyy, ix1, ix2, ix3)  = c0o1;
+                                (*av)(AvVzz, ix1, ix2, ix3)  = c0o1;
+                                (*av)(AvVxy, ix1, ix2, ix3)  = c0o1;
+                                (*av)(AvVxz, ix1, ix2, ix3)  = c0o1;
+                                (*av)(AvVyz, ix1, ix2, ix3)  = c0o1;
+                                (*av)(AvPrms, ix1, ix2, ix3) = c0o1;
                                 //////////////////////////////////////////////////////////////////////////
                             }
                         }
@@ -122,6 +124,8 @@ void AverageValuesSimulationObserver::resetDataRMS(real step)
 //////////////////////////////////////////////////////////////////////////
 void AverageValuesSimulationObserver::resetDataMeans(real step)
 {
+    using namespace vf::basics::constant;
+    
     resetStepMeans = (int)step;
 
     for (int level = minInitLevel; level <= maxInitLevel; level++) {
@@ -147,10 +151,10 @@ void AverageValuesSimulationObserver::resetDataMeans(real step)
                                 //////////////////////////////////////////////////////////////////////////
                                 // compute average values
                                 //////////////////////////////////////////////////////////////////////////
-                                (*av)(AvVx, ix1, ix2, ix3) = 0.0;
-                                (*av)(AvVy, ix1, ix2, ix3) = 0.0;
-                                (*av)(AvVz, ix1, ix2, ix3) = 0.0;
-                                (*av)(AvP, ix1, ix2, ix3)  = 0.0;
+                                (*av)(AvVx, ix1, ix2, ix3) = c0o1;
+                                (*av)(AvVy, ix1, ix2, ix3) = c0o1;
+                                (*av)(AvVz, ix1, ix2, ix3) = c0o1;
+                                (*av)(AvP, ix1, ix2, ix3)  = c0o1;
                                 //////////////////////////////////////////////////////////////////////////
                             }
                         }
@@ -333,6 +337,7 @@ void AverageValuesSimulationObserver::addData(const SPtr<Block3D> block)
 void AverageValuesSimulationObserver::calculateAverageValues(real timeStep)
 {
     using namespace D3Q27System;
+    using namespace vf::basics::constant;
 
     // Funktionszeiger
     calcMacros = NULL;
@@ -391,50 +396,50 @@ void AverageValuesSimulationObserver::calculateAverageValues(real timeStep)
                                 // mean velocity
                                 (*av)(AvVx, ix1, ix2, ix3) =
                                     ((*av)(AvVx, ix1, ix2, ix3) * timeStepAfterResetMeans + vx) /
-                                    (timeStepAfterResetMeans + 1.0);
+                                    (timeStepAfterResetMeans + c1o1);
                                 (*av)(AvVy, ix1, ix2, ix3) =
                                     ((*av)(AvVy, ix1, ix2, ix3) * timeStepAfterResetMeans + vy) /
-                                    (timeStepAfterResetMeans + 1.0);
+                                    (timeStepAfterResetMeans + c1o1);
                                 (*av)(AvVz, ix1, ix2, ix3) =
                                     ((*av)(AvVz, ix1, ix2, ix3) * timeStepAfterResetMeans + vz) /
-                                    (timeStepAfterResetMeans + 1.0);
+                                    (timeStepAfterResetMeans + c1o1);
 
                                 // rms
                                 (*av)(AvVxx, ix1, ix2, ix3) =
                                     ((vx - (*av)(AvVx, ix1, ix2, ix3)) * (vx - (*av)(AvVx, ix1, ix2, ix3)) +
                                      (*av)(AvVxx, ix1, ix2, ix3) * timeStepAfterResetRMS) /
-                                    (timeStepAfterResetRMS + 1.0);
+                                    (timeStepAfterResetRMS + c1o1);
                                 (*av)(AvVyy, ix1, ix2, ix3) =
                                     ((vy - (*av)(AvVy, ix1, ix2, ix3)) * (vy - (*av)(AvVy, ix1, ix2, ix3)) +
                                      (*av)(AvVyy, ix1, ix2, ix3) * timeStepAfterResetRMS) /
-                                    (timeStepAfterResetRMS + 1.0);
+                                    (timeStepAfterResetRMS + c1o1);
                                 (*av)(AvVzz, ix1, ix2, ix3) =
                                     ((vz - (*av)(AvVz, ix1, ix2, ix3)) * (vz - (*av)(AvVz, ix1, ix2, ix3)) +
                                      (*av)(AvVzz, ix1, ix2, ix3) * timeStepAfterResetRMS) /
-                                    (timeStepAfterResetRMS + 1.0);
+                                    (timeStepAfterResetRMS + c1o1);
 
                                 // cross-correlations
                                 (*av)(AvVxy, ix1, ix2, ix3) =
                                     ((vx - (*av)(AvVx, ix1, ix2, ix3)) * (vy - (*av)(AvVy, ix1, ix2, ix3)) +
                                      (*av)(AvVxy, ix1, ix2, ix3) * timeStepAfterResetRMS) /
-                                    (timeStepAfterResetRMS + 1.0);
+                                    (timeStepAfterResetRMS + c1o1);
                                 (*av)(AvVxz, ix1, ix2, ix3) =
                                     ((vx - (*av)(AvVx, ix1, ix2, ix3)) * (vz - (*av)(AvVz, ix1, ix2, ix3)) +
                                      (*av)(AvVxz, ix1, ix2, ix3) * timeStepAfterResetRMS) /
-                                    (timeStepAfterResetRMS + 1.0);
+                                    (timeStepAfterResetRMS + c1o1);
                                 (*av)(AvVyz, ix1, ix2, ix3) =
                                     ((vy - (*av)(AvVy, ix1, ix2, ix3)) * (vz - (*av)(AvVz, ix1, ix2, ix3)) +
                                      (*av)(AvVyz, ix1, ix2, ix3) * timeStepAfterResetRMS) /
-                                    (timeStepAfterResetRMS + 1.0);
+                                    (timeStepAfterResetRMS + c1o1);
 
                                 // mean and rms press
                                 (*av)(AvP, ix1, ix2, ix3) =
                                     ((*av)(AvP, ix1, ix2, ix3) * timeStepAfterResetMeans + press) /
-                                    (timeStepAfterResetMeans + 1.0);
+                                    (timeStepAfterResetMeans + c1o1);
                                 (*av)(AvPrms, ix1, ix2, ix3) =
                                     ((press - (*av)(AvP, ix1, ix2, ix3)) * (press - (*av)(AvP, ix1, ix2, ix3)) +
                                      (*av)(AvPrms, ix1, ix2, ix3) * timeStepAfterResetRMS) /
-                                    (timeStepAfterResetRMS + 1.0);
+                                    (timeStepAfterResetRMS + c1o1);
 
                                 //////////////////////////////////////////////////////////////////////////
                             }
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/CalculateForcesSimulationObserver.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/CalculateForcesSimulationObserver.cpp
index 8610c5df9e4b56496c3dc3ba1c25fabfd355f294..3b501424f1426b99a341906fbc3d3b638204ce20 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/CalculateForcesSimulationObserver.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/CalculateForcesSimulationObserver.cpp
@@ -103,15 +103,17 @@ void CalculateForcesSimulationObserver::collectData(real step)
 //////////////////////////////////////////////////////////////////////////
 void CalculateForcesSimulationObserver::calculateForces()
 {
-    forceX1global = 0.0;
-    forceX2global = 0.0;
-    forceX3global = 0.0;
+    using namespace  vf::basics::constant;
+
+    forceX1global = c0o1;
+    forceX2global = c0o1;
+    forceX3global = c0o1;
 
     for (SPtr<D3Q27Interactor> interactor : interactors) {
         for (BcNodeIndicesMap::value_type t : interactor->getBcNodeIndicesMap()) {
-            real forceX1 = 0.0;
-            real forceX2 = 0.0;
-            real forceX3 = 0.0;
+            real forceX1 = c0o1;
+            real forceX2 = c0o1;
+            real forceX3 = c0o1;
 
             SPtr<Block3D> block                             = t.first;
             std::set<std::vector<int>> &transNodeIndicesSet = t.second;
@@ -172,9 +174,9 @@ void CalculateForcesSimulationObserver::calculateForces()
 
     rvalues = comm->gather(values);
     if (comm->getProcessID() == comm->getRoot()) {
-        forceX1global = 0.0;
-        forceX2global = 0.0;
-        forceX3global = 0.0;
+        forceX1global = c0o1;
+        forceX2global = c0o1;
+        forceX3global = c0o1;
 
         for (int i = 0; i < (int)rvalues.size(); i += 3) {
             forceX1global += rvalues[i];
@@ -187,7 +189,9 @@ void CalculateForcesSimulationObserver::calculateForces()
 UbTupleDouble3 CalculateForcesSimulationObserver::getForces(int x1, int x2, int x3, SPtr<DistributionArray3D> distributions,
                                                      SPtr<BoundaryConditions> bc)
 {
-    UbTupleDouble3 force(0.0, 0.0, 0.0);
+    using namespace  vf::basics::constant;
+
+    UbTupleDouble3 force(c0o1, c0o1, c0o1);
 
     if (bc) {
         // references to tuple "force"
@@ -217,14 +221,16 @@ UbTupleDouble3 CalculateForcesSimulationObserver::getForces(int x1, int x2, int
 //////////////////////////////////////////////////////////////////////////
 void CalculateForcesSimulationObserver::calculateCoefficients()
 {
+    using namespace  vf::basics::constant;
+    
     real F1 = forceX1global;
     real F2 = forceX2global;
     real F3 = forceX3global;
 
     // return 2*F/(rho*v*v*a);
-    C1 = 2.0 * F1 / (v * v * a);
-    C2 = 2.0 * F2 / (v * v * a);
-    C3 = 2.0 * F3 / (v * v * a);
+    C1 = c2o1 * F1 / (v * v * a);
+    C2 = c2o1 * F2 / (v * v * a);
+    C3 = c2o1 * F3 / (v * v * a);
 }
 //////////////////////////////////////////////////////////////////////////
 void CalculateForcesSimulationObserver::addInteractor(SPtr<D3Q27Interactor> interactor) { interactors.push_back(interactor); }
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/CalculateTorqueSimulationObserver.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/CalculateTorqueSimulationObserver.cpp
index 768fbbb26241edfe5771bf056b6b83be21b02312..09409ccf11dfb38c5b615f05a667701444d6f208 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/CalculateTorqueSimulationObserver.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/CalculateTorqueSimulationObserver.cpp
@@ -82,9 +82,11 @@ void CalculateTorqueSimulationObserver::collectData( real step )
 //////////////////////////////////////////////////////////////////////////
 void CalculateTorqueSimulationObserver::calculateForces()
 {
-   torqueX1global = 0.0;
-   torqueX2global = 0.0;
-   torqueX3global = 0.0;
+    using namespace  vf::basics::constant;
+
+   torqueX1global = c0o1;
+   torqueX2global = c0o1;
+   torqueX3global = c0o1;
 
    for(SPtr<D3Q27Interactor> interactor : interactors)
    {
@@ -94,9 +96,9 @@ void CalculateTorqueSimulationObserver::calculateForces()
 
       for(BcNodeIndicesMap::value_type t : interactor->getBcNodeIndicesMap())
       {
-         real torqueX1 = 0.0;
-         real torqueX2 = 0.0;
-         real torqueX3 = 0.0;
+         real torqueX1 = c0o1;
+         real torqueX2 = c0o1;
+         real torqueX3 = c0o1;
 
          SPtr<Block3D> block = t.first;
          std::set< std::vector<int> >& transNodeIndicesSet = t.second;
@@ -167,9 +169,9 @@ void CalculateTorqueSimulationObserver::calculateForces()
    rvalues = comm->gather(values);
    if (comm->getProcessID() == comm->getRoot())
    {
-      torqueX1global = 0.0;
-      torqueX2global = 0.0;
-      torqueX3global = 0.0;
+      torqueX1global = c0o1;
+      torqueX2global = c0o1;
+      torqueX3global = c0o1;
       
       for (int i = 0; i < (int)rvalues.size(); i+=3)
       {
@@ -182,7 +184,9 @@ void CalculateTorqueSimulationObserver::calculateForces()
 //////////////////////////////////////////////////////////////////////////
 UbTupleDouble3 CalculateTorqueSimulationObserver::getForces(int x1, int x2, int x3,  SPtr<DistributionArray3D> distributions, SPtr<BoundaryConditions> bc)
 {
-   UbTupleDouble3 force(0.0,0.0,0.0);
+    using namespace  vf::basics::constant;
+
+   UbTupleDouble3 force(c0o1,c0o1,c0o1);
 
    if(bc)
    {
@@ -217,7 +221,7 @@ UbTupleDouble3 CalculateTorqueSimulationObserver::getForces(int x1, int x2, int
 UbTupleDouble3 CalculateTorqueSimulationObserver::getForcesFromMoments(int x1, int x2, int x3, SPtr<ILBMKernel> kernel, SPtr<DistributionArray3D> distributions, SPtr<BoundaryConditions> bc, real nx, real ny, real nz)
 {
    using namespace vf::basics::constant;
-   UbTupleDouble3 force(0.0, 0.0, 0.0);
+   UbTupleDouble3 force(c0o1, c0o1, c0o1);
 
 
    if (bc) {
@@ -252,7 +256,7 @@ UbTupleDouble3 CalculateTorqueSimulationObserver::getForcesFromMoments(int x1, i
 UbTupleDouble3 CalculateTorqueSimulationObserver::getForcesFromStressTensor(int x1, int x2, int x3, SPtr<ILBMKernel> kernel, SPtr<DistributionArray3D> distributions, SPtr<BoundaryConditions> bc, real nx, real ny, real nz)
 {
    using namespace vf::basics::constant;
-   UbTupleDouble3 force(0.0, 0.0, 0.0);
+   UbTupleDouble3 force(c0o1, c0o1, c0o1);
 
    if (bc) {
       real f[D3Q27System::ENDF + 1];
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/ForceCalculator.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/ForceCalculator.cpp
index 9a39ce11ed15e939e9fc32eaeb15d541675387aa..25e0e30a5e0c0d5789284df71b6f550da6856006 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/ForceCalculator.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/ForceCalculator.cpp
@@ -20,9 +20,11 @@ ForceCalculator::~ForceCalculator() = default;
 Vector3D ForceCalculator::getForces(int x1, int x2, int x3, SPtr<DistributionArray3D> distributions,
                                     SPtr<BoundaryConditions> bc, const Vector3D &boundaryVelocity) const
 {
-    real forceX1 = 0;
-    real forceX2 = 0;
-    real forceX3 = 0;
+    using namespace vf::basics::constant;
+    
+    real forceX1 = c0o1;
+    real forceX2 = c0o1;
+    real forceX3 = c0o1;
     if (bc) {
         for (int fdir = D3Q27System::FSTARTDIR; fdir <= D3Q27System::FENDDIR; fdir++) {
             if (bc->hasNoSlipBoundaryFlag(fdir) || bc->hasVelocityBoundaryFlag(fdir)) {
@@ -31,7 +33,7 @@ Vector3D ForceCalculator::getForces(int x1, int x2, int x3, SPtr<DistributionArr
                 const real fnbr = distributions->getDistributionInvForDirection(
                     x1 + D3Q27System::DX1[invDir], x2 + D3Q27System::DX2[invDir], x3 + D3Q27System::DX3[invDir], fdir);
 
-                real correction[3] = { 0.0, 0.0, 0.0 };
+                real correction[3] = { c0o1, c0o1, c0o1 };
                 if (bc->hasVelocityBoundaryFlag(fdir)) {
                     const real forceTerm = f - fnbr;
                     correction[0]          = forceTerm * boundaryVelocity[0];
@@ -54,15 +56,17 @@ Vector3D ForceCalculator::getForces(int x1, int x2, int x3, SPtr<DistributionArr
 
 void ForceCalculator::calculateForces(std::vector<SPtr<D3Q27Interactor>> interactors)
 {
-    forceX1global = 0.0;
-    forceX2global = 0.0;
-    forceX3global = 0.0;
+    using namespace vf::basics::constant;
+
+    forceX1global = c0o1;
+    forceX2global = c0o1;
+    forceX3global = c0o1;
 
     for (const auto &interactor : interactors) {
         for (const auto &t : interactor->getBcNodeIndicesMap()) {
-            real forceX1 = 0.0;
-            real forceX2 = 0.0;
-            real forceX3 = 0.0;
+            real forceX1 = c0o1;
+            real forceX2 = c0o1;
+            real forceX3 = c0o1;
 
             SPtr<Block3D> block                     = t.first;
             SPtr<ILBMKernel> kernel                 = block->getKernel();
@@ -104,6 +108,8 @@ void ForceCalculator::calculateForces(std::vector<SPtr<D3Q27Interactor>> interac
 
 void ForceCalculator::gatherGlobalForces()
 {
+    using namespace vf::basics::constant;
+
     std::vector<real>
         values; // intel compiler 17 dasn't support this { forceX1global , forceX2global, forceX3global };
     values.push_back(forceX1global);
@@ -112,9 +118,9 @@ void ForceCalculator::gatherGlobalForces()
     std::vector<real> rvalues = comm->gather(values);
 
     if (comm->isRoot()) {
-        forceX1global = 0.0;
-        forceX2global = 0.0;
-        forceX3global = 0.0;
+        forceX1global = c0o1;
+        forceX2global = c0o1;
+        forceX3global = c0o1;
 
         for (int i = 0; i < (int)rvalues.size(); i += 3) {
             forceX1global += rvalues[i];
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/IntegrateValuesHelper.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/IntegrateValuesHelper.cpp
index 7eabcd2849f2fca11cb057357492fa1062c46dce..89938deb91f5c2a13cf04d073a1589fbe65ba6c2 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/IntegrateValuesHelper.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/IntegrateValuesHelper.cpp
@@ -36,6 +36,8 @@ IntegrateValuesHelper::~IntegrateValuesHelper() = default;
 //////////////////////////////////////////////////////////////////////////
 void IntegrateValuesHelper::init(int level)
 {
+    using namespace vf::basics::constant;
+
     root = comm->isRoot();
 
     real orgX1, orgX2, orgX3;
@@ -49,8 +51,8 @@ void IntegrateValuesHelper::init(int level)
         maxInitLevel = level;
     }
 
-    real numSolids = 0.0;
-    real numFluids = 0.0;
+    real numSolids = c0o1;
+    real numFluids = c0o1;
     for (int level_it = minInitLevel; level_it <= maxInitLevel; level_it++) {
         std::vector<SPtr<Block3D>> blockVector;
         grid->getBlocks(level_it, gridRank, blockVector);
@@ -101,8 +103,8 @@ void IntegrateValuesHelper::init(int level)
     rvalues = comm->gather(values);
 
     if (root) {
-        numberOfSolidNodes  = 0.0;
-        numberOfFluidsNodes = 0.0;
+        numberOfSolidNodes  = c0o1;
+        numberOfFluidsNodes = c0o1;
         int rsize           = (int)rvalues.size();
         int vsize           = (int)values.size();
         for (int i = 0; i < rsize; i += vsize) {
@@ -230,21 +232,23 @@ void IntegrateValuesHelper::calculateMQ()
 //////////////////////////////////////////////////////////////////////////
 void IntegrateValuesHelper::clearData()
 {
-    sRho        = 0.0;
-    sVx1        = 0.0;
-    sVx2        = 0.0;
-    sVx3        = 0.0;
-    sCellVolume = 0.0;
+    using namespace vf::basics::constant;
+ 
+    sRho        = c0o1;
+    sVx1        = c0o1;
+    sVx2        = c0o1;
+    sVx3        = c0o1;
+    sCellVolume = c0o1;
     // sVm = 0.0;
     // sPress = 0.0;
     // numberOfFluidsNodes = 0.0;
-    sAvVx1  = 0.0;
-    sAvVx2  = 0.0;
-    sAvVx3  = 0.0;
-    sTSx1   = 0.0;
-    sTSx2   = 0.0;
-    sTSx3   = 0.0;
-    sTSx1x3 = 0.0;
+    sAvVx1  = c0o1;
+    sAvVx2  = c0o1;
+    sAvVx3  = c0o1;
+    sTSx1   = c0o1;
+    sTSx2   = c0o1;
+    sTSx3   = c0o1;
+    sTSx1x3 = c0o1;
 }
 //////////////////////////////////////////////////////////////////////////
 real IntegrateValuesHelper::getNumberOfFluidsNodes() { return this->numberOfFluidsNodes; }
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/MPIIOMigrationBESimulationObserver.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/MPIIOMigrationBESimulationObserver.cpp
index ef220856838baabadb3b8cf40270d0e505147069..5cdc87c6867c5ec2a8676e66a228ba5e768014fb 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/MPIIOMigrationBESimulationObserver.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/MPIIOMigrationBESimulationObserver.cpp
@@ -130,7 +130,6 @@ void MPIIOMigrationBESimulationObserver::writeDataSet(int step)
     DSArraysPresence arrPresence;
     bool firstBlock        = true;
     int doubleCountInBlock = 0;
-    int ic                 = 0;
     SPtr<D3Q27EsoTwist3DSplittedVector> D3Q27EsoTwist3DSplittedVectorPtrF = 0, D3Q27EsoTwist3DSplittedVectorPtrH1 = 0, D3Q27EsoTwist3DSplittedVectorPtrH2 = 0;
     CbArray4D<real, IndexerX4X3X2X1>::CbArray4DPtr localDistributionsF = 0, localDistributionsH1 = 0, localDistributionsH2 = 0;
     CbArray4D<real, IndexerX4X3X2X1>::CbArray4DPtr nonLocalDistributionsF = 0, nonLocalDistributionsH1 = 0, nonLocalDistributionsH2 = 0;
@@ -280,8 +279,6 @@ void MPIIOMigrationBESimulationObserver::writeDataSet(int step)
                 if (zeroDistributionsH2 && (dataSetParamStr3.nx[0] > 0) && (dataSetParamStr3.nx[1] > 0) && (dataSetParamStr3.nx[2] > 0))
                 doubleValuesArrayH2.insert(doubleValuesArrayH2.end(), zeroDistributionsH2->getDataVector().begin(), zeroDistributionsH2->getDataVector().end());
             }
-
-            ic++;
         }
     }
 
@@ -431,7 +428,6 @@ void MPIIOMigrationBESimulationObserver::write4DArray(int step, Arrays arrayType
     dataSetParam dataSetParamStr;
     bool firstBlock        = true;
     int doubleCountInBlock = 0;
-    int ic                 = 0;
     SPtr<CbArray4D<real, IndexerX4X3X2X1>> ___Array;
 
     if (comm->isRoot()) 
@@ -482,8 +478,6 @@ void MPIIOMigrationBESimulationObserver::write4DArray(int step, Arrays arrayType
 
             if ((dataSetParamStr.nx[0] > 0) && (dataSetParamStr.nx[1] > 0) && (dataSetParamStr.nx[2] > 0) && (dataSetParamStr.nx[3] > 0))
                 doubleValuesArray.insert(doubleValuesArray.end(), ___Array->getDataVector().begin(), ___Array->getDataVector().end());
-
-            ic++;
         }
     }
 
@@ -550,7 +544,6 @@ void MPIIOMigrationBESimulationObserver::write3DArray(int step, Arrays arrayType
     dataSetParam dataSetParamStr;
     bool firstBlock        = true;
     int doubleCountInBlock = 0;
-    int ic                 = 0;
     SPtr<CbArray3D<real, IndexerX3X2X1>> ___Array;
 
     if (comm->isRoot()) 
@@ -599,8 +592,6 @@ void MPIIOMigrationBESimulationObserver::write3DArray(int step, Arrays arrayType
 
             if ((dataSetParamStr.nx[0] > 0) && (dataSetParamStr.nx[1] > 0) && (dataSetParamStr.nx[2] > 0))
                 doubleValuesArray.insert(doubleValuesArray.end(), ___Array->getDataVector().begin(), ___Array->getDataVector().end());
-
-            ic++;
         }
     }
 
@@ -659,8 +650,6 @@ void MPIIOMigrationBESimulationObserver::writeBoundaryConds(int step)
 
     int blocksCount          = 0; // quantity of blocks, that belong to this process
     size_t allBytesCount     = 0; // quantity of bytes, that one process writes to the file
-    size_t count_boundCond   = 0; // how many BoundaryConditions in all blocks
-    int count_indexContainer = 0; // how many indexContainer-values in all blocks
 
     std::vector<SPtr<Block3D>> blocksVector[25];
     int minInitLevel = this->grid->getCoarsestInitializedLevel();
@@ -721,7 +710,6 @@ void MPIIOMigrationBESimulationObserver::writeBoundaryConds(int step)
 
                 bcVector[ic].push_back(*bouCond);
                 bcAddArray[ic].boundCond_count++;
-                count_boundCond++;
                 bytesCount[ic] += sizeof(BoundaryCondition);
             }
 
@@ -738,7 +726,6 @@ void MPIIOMigrationBESimulationObserver::writeBoundaryConds(int step)
 
             indexContainerVector[ic].insert(indexContainerVector[ic].begin(), bcArr->indexContainer.begin(), bcArr->indexContainer.end());
             bcAddArray[ic].indexContainer_count = static_cast<int>(bcArr->indexContainer.size());
-            count_indexContainer += bcAddArray[ic].indexContainer_count;
             bytesCount[ic] += bcAddArray[ic].indexContainer_count * sizeof(int);
 
             allBytesCount += bytesCount[ic];
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/MPIIOMigrationSimulationObserver.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/MPIIOMigrationSimulationObserver.cpp
index 32e6ba5188626c0a37fba8e9db0ad4447502d001..860b3f02ab1db6c1554ca9f87069281520100bd6 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/MPIIOMigrationSimulationObserver.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/MPIIOMigrationSimulationObserver.cpp
@@ -730,8 +730,6 @@ void MPIIOMigrationSimulationObserver::writeBoundaryConds(int step)
 
     int blocksCount          = 0; // quantity of blocks, that belong to this process
     size_t allBytesCount     = 0; // quantity of bytes, that one process writes to the file
-    size_t count_boundCond   = 0; // how many BoundaryConditions in all blocks
-    int count_indexContainer = 0; // how many indexContainer-values in all blocks
 
     std::vector<SPtr<Block3D>> blocksVector[25];
     int minInitLevel = this->grid->getCoarsestInitializedLevel();
@@ -793,7 +791,6 @@ void MPIIOMigrationSimulationObserver::writeBoundaryConds(int step)
 
                 bcVector[ic].push_back(*bouCond);
                 bcAddArray[ic].boundCond_count++;
-                count_boundCond++;
                 bytesCount[ic] += sizeof(BoundaryCondition);
             }
 
@@ -810,7 +807,6 @@ void MPIIOMigrationSimulationObserver::writeBoundaryConds(int step)
 
             indexContainerVector[ic].insert(indexContainerVector[ic].begin(), bcArr->indexContainer.begin(), bcArr->indexContainer.end());
             bcAddArray[ic].indexContainer_count = static_cast<int>(bcArr->indexContainer.size());
-            count_indexContainer += bcAddArray[ic].indexContainer_count;
             bytesCount[ic] += bcAddArray[ic].indexContainer_count * sizeof(int);
 
             allBytesCount += bytesCount[ic];
@@ -1505,8 +1501,8 @@ void MPIIOMigrationSimulationObserver::readBoundaryConds(int step)
 
             block1->getKernel()->setBCSet(bcProc);
 
-            delete bcArray;
-            delete intArray1;
+            delete[] bcArray;
+            delete[] intArray1;
 
             ic++;
         }
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/PressureDifferenceSimulationObserver.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/PressureDifferenceSimulationObserver.cpp
index 9b3c63f407b9fac00de6177a369fec2cb3e74a82..ac786be093d161a4da1450d5f7ffca8e4c7e5358 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/PressureDifferenceSimulationObserver.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/PressureDifferenceSimulationObserver.cpp
@@ -22,6 +22,8 @@ PressureDifferenceSimulationObserver::PressureDifferenceSimulationObserver(SPtr<
 
     : SimulationObserver(grid, s), path(path), h1(h1), h2(h2), comm(comm)
 {
+    using namespace vf::basics::constant;
+
     if (comm->getProcessID() == comm->getRoot()) {
         std::ofstream ostr;
         std::string fname = path;
@@ -64,7 +66,7 @@ PressureDifferenceSimulationObserver::PressureDifferenceSimulationObserver(SPtr<
         ostr << std::endl;
         ostr.close();
 
-        factor1 = (1.0 / 3.0) * rhoReal * (uReal / uLB) * (uReal / uLB);
+        factor1 = (c1o1 / c3o1) * rhoReal * (uReal / uLB) * (uReal / uLB);
         factor2 = rhoReal * (uReal / uLB) * (uReal / uLB);
     }
 }
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/QCriterionSimulationObserver.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/QCriterionSimulationObserver.cpp
index 010d9ff664e22519ceb169c549ecc05307655ed4..d0e50585a473b58780ba5e4372fc87e0524ca7a4 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/QCriterionSimulationObserver.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/QCriterionSimulationObserver.cpp
@@ -89,6 +89,8 @@ void QCriterionSimulationObserver::clearData()
 //////////////////////////////////////////////////////////////////////////
 void QCriterionSimulationObserver::addData(const SPtr<Block3D> block)
 {
+    using namespace vf::basics::constant;
+
     UbTupleDouble3 org = grid->getBlockWorldCoordinates(block);
     //	UbTupleDouble3 blockLengths = grid->getBlockLengths(block);
     UbTupleDouble3 nodeOffset = grid->getNodeOffset(block);
@@ -147,16 +149,16 @@ void QCriterionSimulationObserver::addData(const SPtr<Block3D> block)
                     getNeighborVelocities(0, 0, 1, ix1, ix2, ix3, block, vT, vB);
                     //////////////////////////////////
                     // derivatives
-                    real duxdy = (vN[xdir] - vS[xdir]) * 0.5;
-                    real duydx = (vE[ydir] - vW[ydir]) * 0.5;
-                    real duxdz = (vT[xdir] - vB[xdir]) * 0.5;
-                    real duzdx = (vE[zdir] - vW[zdir]) * 0.5;
-                    real duydz = (vT[ydir] - vB[ydir]) * 0.5;
-                    real duzdy = (vN[zdir] - vS[zdir]) * 0.5;
+                    real duxdy = (vN[xdir] - vS[xdir]) * c1o2;
+                    real duydx = (vE[ydir] - vW[ydir]) * c1o2;
+                    real duxdz = (vT[xdir] - vB[xdir]) * c1o2;
+                    real duzdx = (vE[zdir] - vW[zdir]) * c1o2;
+                    real duydz = (vT[ydir] - vB[ydir]) * c1o2;
+                    real duzdy = (vN[zdir] - vS[zdir]) * c1o2;
 
-                    real duxdx = (vE[xdir] - vW[xdir]) * 0.5;
-                    real duydy = (vN[ydir] - vS[ydir]) * 0.5;
-                    real duzdz = (vT[zdir] - vB[zdir]) * 0.5;
+                    real duxdx = (vE[xdir] - vW[xdir]) * c1o2;
+                    real duydy = (vN[ydir] - vS[ydir]) * c1o2;
+                    real duzdz = (vT[zdir] - vB[zdir]) * c1o2;
 
                     real scaleFactor =
                         (real)(1
@@ -203,7 +205,9 @@ void QCriterionSimulationObserver::addData(const SPtr<Block3D> block)
 void QCriterionSimulationObserver::getNeighborVelocities(int offx, int offy, int offz, int ix1, int ix2, int ix3,
                                                   const SPtr<Block3D> block, real *vE, real *vW)
 {
-    SPtr<ILBMKernel> kernel                 = block->getKernel();
+    using namespace vf::basics::constant;
+    
+    SPtr<ILBMKernel> kernel = block->getKernel();
     SPtr<BCArray3D> bcArray                 = kernel->getBCSet()->getBCArray();
     SPtr<DistributionArray3D> distributions = kernel->getDataSet()->getFdistributions();
 
@@ -214,13 +218,13 @@ void QCriterionSimulationObserver::getNeighborVelocities(int offx, int offy, int
     //	int minX3 = 0;
 
     int maxX1 = (int)(distributions->getNX1());
-    int maxX2 = (int)(distributions->getNX2());
-    int maxX3 = (int)(distributions->getNX3());
+    // int maxX2 = (int)(distributions->getNX2());
+    // int maxX3 = (int)(distributions->getNX3());
     if (maxX1 < 3)
         throw UbException(UB_EXARGS, "QCriterionSimulationObserver: NX1 too small for FD stencils!");
     maxX1 -= 2;
-    maxX2 -= 2;
-    maxX3 -= 2;
+    // maxX2 -= 2;
+    // maxX3 -= 2;
     bool checkInterpolation = true;
     bool neighNodeIsBC      = false;
     SPtr<BoundaryConditions> bcPtr;
@@ -306,9 +310,9 @@ void QCriterionSimulationObserver::getNeighborVelocities(int offx, int offy, int
             computeVelocity(fW2, vW2, compressible);
             computeVelocity(f0, v0, compressible);
             // second order non-symetric interpolation
-            vW[0] = v0[0] * 1.5 - vW[0] + 0.5 * vW2[0];
-            vW[1] = v0[1] * 1.5 - vW[1] + 0.5 * vW2[1];
-            vW[2] = v0[2] * 1.5 - vW[2] + 0.5 * vW2[2];
+            vW[0] = v0[0] * c3o2 - vW[0] + c1o2 * vW2[0];
+            vW[1] = v0[1] * c3o2 - vW[1] + c1o2 * vW2[1];
+            vW[2] = v0[2] * c3o2 - vW[2] + c1o2 * vW2[2];
             // throw UbException(UB_EXARGS,"Parallel or Non-Uniform Simulation -- not yet implemented");
         } else {
             SPtr<ILBMKernel> kernelW                 = blockNeighW->getKernel();
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/ShearStressSimulationObserver.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/ShearStressSimulationObserver.cpp
index 92c8f5f60344019cff472851104b86e5838302a8..fa566d21aaff03689be1d7b8dfb8848a76eaca07 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/ShearStressSimulationObserver.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/ShearStressSimulationObserver.cpp
@@ -8,7 +8,7 @@
 #include "D3Q27Interactor.h"
 #include "DataSet3D.h"
 #include "Grid3D.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "LBMKernel.h"
 #include "UbScheduler.h"
 
@@ -16,6 +16,8 @@ ShearStressSimulationObserver::ShearStressSimulationObserver(SPtr<Grid3D> grid,
                                                SPtr<UbScheduler> s, SPtr<UbScheduler> rs)
     : SimulationObserver(grid, s), Resetscheduler(rs), path(path), writer(writer)
 {
+    using namespace vf::basics::constant; 
+
     std::shared_ptr<vf::mpi::Communicator> comm = vf::mpi::Communicator::getInstance();
     normals.push_back(0);
     normals.push_back(0);
@@ -30,7 +32,7 @@ ShearStressSimulationObserver::ShearStressSimulationObserver(SPtr<Grid3D> grid,
         for (SPtr<Block3D> block : blockVector[level]) {
             UbTupleInt3 nx                                   = grid->getBlockNX();
             SPtr<ShearStressValuesArray3D> shearStressValues = SPtr<ShearStressValuesArray3D>(
-                new ShearStressValuesArray3D(14, val<1>(nx) + 1, val<2>(nx) + 1, val<3>(nx) + 1, 0.0));
+                new ShearStressValuesArray3D(14, val<1>(nx) + 1, val<2>(nx) + 1, val<3>(nx) + 1, c0o1));
             block->getKernel()->getDataSet()->setShearStressValues(shearStressValues);
         }
     }
@@ -126,6 +128,7 @@ void ShearStressSimulationObserver::calculateShearStress(real timeStep)
 {
     using namespace vf::lbm::dir;
     using namespace D3Q27System;
+    using namespace vf::basics::constant;
 
     real f[27];
     real vx, vy, vz, sxx, syy, szz, sxy, syz, sxz;
@@ -182,23 +185,23 @@ void ShearStressSimulationObserver::calculateShearStress(real timeStep)
                     vz = ((((f[DIR_PPP] - f[DIR_MMM]) + (f[DIR_PMP] - f[DIR_MPM])) + ((f[DIR_MPP] - f[DIR_PMM]) + (f[DIR_MMP] - f[DIR_PPM]))) +
                           (((f[DIR_0MP] - f[DIR_0PM]) + (f[DIR_0PP] - f[DIR_0MM])) + ((f[DIR_M0P] - f[DIR_P0M]) + (f[DIR_P0P] - f[DIR_M0M]))) + (f[DIR_00P] - f[DIR_00M]));
 
-                    sxy = 3.0 * collFactor / (collFactor - 1.0) *
+                    sxy = c3o1 * collFactor / (collFactor - c1o1) *
                           (((f[DIR_PPP] + f[DIR_MMM]) - (f[DIR_PMP] + f[DIR_MPM])) + (-(f[DIR_PMM] + f[DIR_MPP]) + (f[DIR_MMP] + f[DIR_PPM])) +
                            (((f[DIR_PP0] + f[DIR_MM0]) - (f[DIR_PM0] + f[DIR_MP0]))) - vx * vy);
 
-                    sxz = 3.0 * collFactor / (collFactor - 1.0) *
+                    sxz = c3o1 * collFactor / (collFactor - c1o1) *
                           (((f[DIR_PPP] + f[DIR_MMM]) + (f[DIR_PMP] + f[DIR_MPM])) + (-(f[DIR_PMM] + f[DIR_MPP]) - (f[DIR_MMP] + f[DIR_PPM])) +
                            ((f[DIR_P0P] + f[DIR_M0M]) - (f[DIR_P0M] + f[DIR_M0P])) - vx * vz);
 
-                    syz = 3.0 * collFactor / (collFactor - 1.0) *
+                    syz = c3o1 * collFactor / (collFactor - c1o1) *
                           (((f[DIR_PPP] + f[DIR_MMM]) - (f[DIR_PMP] + f[DIR_MPM])) + ((f[DIR_PMM] + f[DIR_MPP]) - (f[DIR_MMP] + f[DIR_PPM])) +
                            (-(f[DIR_0PM] + f[DIR_0MP]) + (f[DIR_0PP] + f[DIR_0MM])) - vy * vz);
 
-                    real dxxMyy = 3.0 / 2.0 * collFactor / (collFactor - 1.0) *
+                    real dxxMyy = c3o1 / c2o1 * collFactor / (collFactor - c1o1) *
                                      (((f[DIR_P0P] + f[DIR_M0M]) + (f[DIR_P0M] + f[DIR_M0P])) - ((f[DIR_0PM] + f[DIR_0MP]) + (f[DIR_0PP] + f[DIR_0MM])) +
                                       ((f[DIR_P00] + f[DIR_M00]) - (f[DIR_0P0] + f[DIR_0M0])) - vx * vx + vy * vy);
 
-                    real dxxMzz = 3.0 / 2.0 * collFactor / (collFactor - 1.0) *
+                    real dxxMzz = c3o1 / c2o1 * collFactor / (collFactor - c1o1) *
                                      ((((f[DIR_PP0] + f[DIR_MM0]) + (f[DIR_PM0] + f[DIR_MP0])) - ((f[DIR_0PM] + f[DIR_0MP]) + (f[DIR_0PP] + f[DIR_0MM]))) +
                                       ((f[DIR_P00] + f[DIR_M00]) - (f[DIR_00P] + f[DIR_00M])) - vx * vx + vz * vz);
 
@@ -206,25 +209,25 @@ void ShearStressSimulationObserver::calculateShearStress(real timeStep)
                     // f[NW]))-((f[TE] + f[BW])+(f[BE]+ f[TW])))
                     //    +((f[N] + f[S])-(f[T] + f[B])) -vy*vy +vz*vz);
 
-                    sxx = (dxxMyy + dxxMzz) / 3.0; // weil dxxPyyPzz=0
+                    sxx = (dxxMyy + dxxMzz) / c3o1; // weil dxxPyyPzz=0
 
-                    syy = (dxxMzz - 2 * dxxMyy) / 3.0;
+                    syy = (dxxMzz - c2o1 * dxxMyy) / c3o1;
 
-                    szz = (dxxMyy - 2 * dxxMzz) / 3.0;
+                    szz = (dxxMyy - c2o1 * dxxMzz) / c3o1;
 
                     //////////////////////////////////////////////////////////////////////////
                     // compute average values
                     //////////////////////////////////////////////////////////////////////////
-                    (*ssv)(AvVx, ix1, ix2, ix3) = ((*ssv)(AvVx, ix1, ix2, ix3) * timeStep + vx) / (timeStep + 1.0);
-                    (*ssv)(AvVy, ix1, ix2, ix3) = ((*ssv)(AvVy, ix1, ix2, ix3) * timeStep + vy) / (timeStep + 1.0);
-                    (*ssv)(AvVz, ix1, ix2, ix3) = ((*ssv)(AvVz, ix1, ix2, ix3) * timeStep + vz) / (timeStep + 1.0);
-
-                    (*ssv)(AvSxx, ix1, ix2, ix3) = ((*ssv)(AvSxx, ix1, ix2, ix3) * timeStep + sxx) / (timeStep + 1.0);
-                    (*ssv)(AvSyy, ix1, ix2, ix3) = ((*ssv)(AvSyy, ix1, ix2, ix3) * timeStep + syy) / (timeStep + 1.0);
-                    (*ssv)(AvSzz, ix1, ix2, ix3) = ((*ssv)(AvSzz, ix1, ix2, ix3) * timeStep + szz) / (timeStep + 1.0);
-                    (*ssv)(AvSxy, ix1, ix2, ix3) = ((*ssv)(AvSxy, ix1, ix2, ix3) * timeStep + sxy) / (timeStep + 1.0);
-                    (*ssv)(AvSyz, ix1, ix2, ix3) = ((*ssv)(AvSyz, ix1, ix2, ix3) * timeStep + syz) / (timeStep + 1.0);
-                    (*ssv)(AvSxz, ix1, ix2, ix3) = ((*ssv)(AvSxz, ix1, ix2, ix3) * timeStep + sxz) / (timeStep + 1.0);
+                    (*ssv)(AvVx, ix1, ix2, ix3) = ((*ssv)(AvVx, ix1, ix2, ix3) * timeStep + vx) / (timeStep + c1o1);
+                    (*ssv)(AvVy, ix1, ix2, ix3) = ((*ssv)(AvVy, ix1, ix2, ix3) * timeStep + vy) / (timeStep + c1o1);
+                    (*ssv)(AvVz, ix1, ix2, ix3) = ((*ssv)(AvVz, ix1, ix2, ix3) * timeStep + vz) / (timeStep + c1o1);
+
+                    (*ssv)(AvSxx, ix1, ix2, ix3) = ((*ssv)(AvSxx, ix1, ix2, ix3) * timeStep + sxx) / (timeStep + c1o1);
+                    (*ssv)(AvSyy, ix1, ix2, ix3) = ((*ssv)(AvSyy, ix1, ix2, ix3) * timeStep + syy) / (timeStep + c1o1);
+                    (*ssv)(AvSzz, ix1, ix2, ix3) = ((*ssv)(AvSzz, ix1, ix2, ix3) * timeStep + szz) / (timeStep + c1o1);
+                    (*ssv)(AvSxy, ix1, ix2, ix3) = ((*ssv)(AvSxy, ix1, ix2, ix3) * timeStep + sxy) / (timeStep + c1o1);
+                    (*ssv)(AvSyz, ix1, ix2, ix3) = ((*ssv)(AvSyz, ix1, ix2, ix3) * timeStep + syz) / (timeStep + c1o1);
+                    (*ssv)(AvSxz, ix1, ix2, ix3) = ((*ssv)(AvSxz, ix1, ix2, ix3) * timeStep + sxz) / (timeStep + c1o1);
                 }
             }
         }
@@ -233,6 +236,8 @@ void ShearStressSimulationObserver::calculateShearStress(real timeStep)
 //////////////////////////////////////////////////////////////////////////
 void ShearStressSimulationObserver::addData()
 {
+    using namespace vf::basics::constant;
+
     // Diese Daten werden geschrieben:
     datanames.resize(0);
     datanames.emplace_back("y^plus");
@@ -322,16 +327,16 @@ void ShearStressSimulationObserver::addData()
                     real nvty   = vty / normVt;
                     real nvtz   = vtz / normVt;
 
-                    real sx   = 0.5 * ((*ssv)(AvSxx, ix1, ix2, ix3) * nvtx + (*ssv)(AvSxy, ix1, ix2, ix3) * nvty +
+                    real sx   = c1o2 * ((*ssv)(AvSxx, ix1, ix2, ix3) * nvtx + (*ssv)(AvSxy, ix1, ix2, ix3) * nvty +
                                        (*ssv)(AvSxz, ix1, ix2, ix3) * nvtz);
-                    real sy   = 0.5 * ((*ssv)(AvSxy, ix1, ix2, ix3) * nvtx + (*ssv)(AvSyy, ix1, ix2, ix3) * nvty +
+                    real sy   = c1o2 * ((*ssv)(AvSxy, ix1, ix2, ix3) * nvtx + (*ssv)(AvSyy, ix1, ix2, ix3) * nvty +
                                        (*ssv)(AvSyz, ix1, ix2, ix3) * nvtz);
-                    real sz   = 0.5 * ((*ssv)(AvSxz, ix1, ix2, ix3) * nvtx + (*ssv)(AvSyz, ix1, ix2, ix3) * nvty +
+                    real sz   = c1o2 * ((*ssv)(AvSxz, ix1, ix2, ix3) * nvtx + (*ssv)(AvSyz, ix1, ix2, ix3) * nvty +
                                        (*ssv)(AvSzz, ix1, ix2, ix3) * nvtz);
                     real sabs = sqrt(sx * sx + sy * sy + sz * sz);
 
-                    real viscosity = (1.0 / 3.0) * (1.0 / collFactor - 0.5);
-                    real rho       = 1.0;
+                    real viscosity = (c1o1 / c3o1) * (c1o1 / collFactor - c1o2);
+                    real rho       = c1o1;
                     real utau      = sqrt(viscosity / rho * sabs);
 
                     // double q=(*av)(ix1,ix2,ix3,normalq) ;
@@ -355,6 +360,8 @@ void ShearStressSimulationObserver::reset(real step)
 //////////////////////////////////////////////////////////////////////////
 void ShearStressSimulationObserver::resetData(real /*step*/)
 {
+    using namespace vf::basics::constant;
+
     for (int level = minInitLevel; level <= maxInitLevel; level++) {
         for (const auto &block : blockVector[level]) {
             if (block) {
@@ -383,16 +390,16 @@ void ShearStressSimulationObserver::resetData(real /*step*/)
                                 //////////////////////////////////////////////////////////////////////////
                                 // compute average values
                                 //////////////////////////////////////////////////////////////////////////
-                                (*ssv)(AvVx, ix1, ix2, ix3) = 0.0;
-                                (*ssv)(AvVy, ix1, ix2, ix3) = 0.0;
-                                (*ssv)(AvVz, ix1, ix2, ix3) = 0.0;
-
-                                (*ssv)(AvSxx, ix1, ix2, ix3) = 0.0;
-                                (*ssv)(AvSyy, ix1, ix2, ix3) = 0.0;
-                                (*ssv)(AvSzz, ix1, ix2, ix3) = 0.0;
-                                (*ssv)(AvSxy, ix1, ix2, ix3) = 0.0;
-                                (*ssv)(AvSyz, ix1, ix2, ix3) = 0.0;
-                                (*ssv)(AvSxz, ix1, ix2, ix3) = 0.0;
+                                (*ssv)(AvVx, ix1, ix2, ix3) = c0o1;
+                                (*ssv)(AvVy, ix1, ix2, ix3) = c0o1;
+                                (*ssv)(AvVz, ix1, ix2, ix3) = c0o1;
+
+                                (*ssv)(AvSxx, ix1, ix2, ix3) = c0o1;
+                                (*ssv)(AvSyy, ix1, ix2, ix3) = c0o1;
+                                (*ssv)(AvSzz, ix1, ix2, ix3) = c0o1;
+                                (*ssv)(AvSxy, ix1, ix2, ix3) = c0o1;
+                                (*ssv)(AvSyz, ix1, ix2, ix3) = c0o1;
+                                (*ssv)(AvSxz, ix1, ix2, ix3) = c0o1;
                                 //////////////////////////////////////////////////////////////////////////
                             }
                         }
@@ -409,10 +416,11 @@ void ShearStressSimulationObserver::findPlane(int ix1, int ix2, int ix3, SPtr<Gr
                                        real &B, real &C, real &D, real &ii)
 {
     using namespace vf::lbm::dir;
+    using namespace vf::basics::constant;
 
-    real x1plane = 0.0, y1plane = 0.0, z1plane = 0.0;
-    real x2plane = 0.0, y2plane = 0.0, z2plane = 0.0;
-    real x3plane = 0.0, y3plane = 0.0, z3plane = 0.0;
+    real x1plane = c0o1, y1plane = c0o1, z1plane = c0o1;
+    real x2plane = c0o1, y2plane = c0o1, z2plane = c0o1;
+    real x3plane = c0o1, y3plane = c0o1, z3plane = c0o1;
     SPtr<BoundaryConditions> bcPtr;
     real dx                               = grid->getDeltaX(block);
     SPtr<ILBMKernel> kernel                 = block->getKernel();
@@ -421,139 +429,139 @@ void ShearStressSimulationObserver::findPlane(int ix1, int ix2, int ix3, SPtr<Gr
     bcPtr                                   = bcArray->getBC(ix1, ix2, ix3);
     int x, y, z;
 
-    if (InterpolationProcessor::iCellHasSolid(bcArray, ix1, ix2, ix3)) {
+    if (Interpolator::iCellHasSolid(bcArray, ix1, ix2, ix3)) {
         x = ix1;
         y = ix2;
         z = ix3;
-    } else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1, ix2 - 1, ix3)) {
+    } else if (Interpolator::iCellHasSolid(bcArray, ix1, ix2 - 1, ix3)) {
         x = ix1 + 0;
         y = ix2 - 1;
         z = ix3 + 0;
     } // S
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1, ix2, ix3 - 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1, ix2, ix3 - 1)) {
         x = ix1 + 0;
         y = ix2 + 0;
         z = ix3 - 1;
     } // B
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 - 1, ix2, ix3)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 - 1, ix2, ix3)) {
         x = ix1 - 1;
         y = ix2 + 0;
         z = ix3 + 0;
     } // w
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1, ix2 - 1, ix3 - 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1, ix2 - 1, ix3 - 1)) {
         x = ix1 + 0;
         y = ix2 - 1;
         z = ix3 - 1;
     } // BS
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 - 1, ix2, ix3 - 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 - 1, ix2, ix3 - 1)) {
         x = ix1 - 1;
         y = ix2 + 0;
         z = ix3 - 1;
     } // BW
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 - 1, ix2 - 1, ix3)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 - 1, ix2 - 1, ix3)) {
         x = ix1 - 1;
         y = ix2 - 1;
         z = ix3 + 0;
     } // SW
 
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 - 1, ix2 - 1, ix3 - 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 - 1, ix2 - 1, ix3 - 1)) {
         x = ix1 - 1;
         y = ix2 - 1;
         z = ix3 - 1;
     } // BSW
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 1, ix2, ix3)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 1, ix2, ix3)) {
         x = ix1 + 1;
         y = ix2 + 0;
         z = ix3 + 0;
     } // E
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1, ix2 + 1, ix3)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1, ix2 + 1, ix3)) {
         x = ix1 + 0;
         y = ix2 + 1;
         z = ix3 + 0;
     } // N
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1, ix2, ix3 + 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1, ix2, ix3 + 1)) {
         x = ix1 + 0;
         y = ix2 + 0;
         z = ix3 + 1;
     } // T
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 1, ix2 + 1, ix3)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 1, ix2 + 1, ix3)) {
         x = ix1 + 1;
         y = ix2 + 1;
         z = ix3 + 0;
     } // NE
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 1, ix2, ix3 + 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 1, ix2, ix3 + 1)) {
         x = ix1 + 1;
         y = ix2 + 0;
         z = ix3 + 1;
     } // TE
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1, ix2 + 1, ix3 + 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1, ix2 + 1, ix3 + 1)) {
         x = ix1 + 0;
         y = ix2 + 1;
         z = ix3 + 1;
     } // TN
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 1, ix2 + 1, ix3 + 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 1, ix2 + 1, ix3 + 1)) {
         x = ix1 + 1;
         y = ix2 + 1;
         z = ix3 + 1;
     } // TNE
 
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 1, ix2 - 1, ix3)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 1, ix2 - 1, ix3)) {
         x = ix1 + 1;
         y = ix2 - 1;
         z = ix3 + 0;
     } // SE
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 - 1, ix2 + 1, ix3)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 - 1, ix2 + 1, ix3)) {
         x = ix1 - 1;
         y = ix2 + 1;
         z = ix3 + 0;
     } // NW
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 1, ix2, ix3 - 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 1, ix2, ix3 - 1)) {
         x = ix1 + 1;
         y = ix2 + 0;
         z = ix3 - 1;
     } // BE
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 - 1, ix2, ix3 + 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 - 1, ix2, ix3 + 1)) {
         x = ix1 - 1;
         y = ix2 + 0;
         z = ix3 + 1;
     } // TW
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 0, ix2 + 1, ix3 - 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 0, ix2 + 1, ix3 - 1)) {
         x = ix1 + 0;
         y = ix2 + 1;
         z = ix3 - 1;
     } // BN
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 0, ix2 - 1, ix3 + 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 0, ix2 - 1, ix3 + 1)) {
         x = ix1 + 0;
         y = ix2 - 1;
         z = ix3 + 1;
     } // TS
 
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 - 1, ix2 + 1, ix3 + 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 - 1, ix2 + 1, ix3 + 1)) {
         x = ix1 - 1;
         y = ix2 + 1;
         z = ix3 + 1;
     } // TNW
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 1, ix2 - 1, ix3 + 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 1, ix2 - 1, ix3 + 1)) {
         x = ix1 + 1;
         y = ix2 - 1;
         z = ix3 + 1;
     } // TSE
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 - 1, ix2 - 1, ix3 + 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 - 1, ix2 - 1, ix3 + 1)) {
         x = ix1 - 1;
         y = ix2 - 1;
         z = ix3 + 1;
     } // TSW
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 1, ix2 + 1, ix3 - 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 1, ix2 + 1, ix3 - 1)) {
         x = ix1 + 1;
         y = ix2 + 1;
         z = ix3 - 1;
     } // BNE
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 - 1, ix2 + 1, ix3 - 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 - 1, ix2 + 1, ix3 - 1)) {
         x = ix1 - 1;
         y = ix2 + 1;
         z = ix3 - 1;
     } // BNW
-    else if (InterpolationProcessor::iCellHasSolid(bcArray, ix1 + 1, ix2 - 1, ix3 - 1)) {
+    else if (Interpolator::iCellHasSolid(bcArray, ix1 + 1, ix2 - 1, ix3 - 1)) {
         x = ix1 + 1;
         y = ix2 - 1;
         z = ix3 - 1;
@@ -594,7 +602,7 @@ void ShearStressSimulationObserver::findPlane(int ix1, int ix2, int ix3, SPtr<Gr
         }
     }
 
-    if (InterpolationProcessor::iCellHasSolid(bcArray, x, y, z)) {
+    if (Interpolator::iCellHasSolid(bcArray, x, y, z)) {
         for (int i = x; i <= x + 1; i++) {
             for (int j = y; j <= y + 1; j++) {
                 for (int k = z; k <= z + 1; k++) {
@@ -839,6 +847,7 @@ bool ShearStressSimulationObserver::checkUndefindedNodes(SPtr<BCArray3D> bcArray
 void ShearStressSimulationObserver::initDistance()
 {
     using namespace vf::lbm::dir;
+    using namespace vf::basics::constant;
 
     for (const auto &interactor : interactors) {
         //      typedef std::map<SPtr<Block3D>, std::set< std::vector<int> > > TransNodeIndicesMap;
@@ -906,7 +915,7 @@ void ShearStressSimulationObserver::initDistance()
                         continue;
 
                     //////get normal and distance//////
-                    real A, B, C, D, ii = 0.0;
+                    real A, B, C, D, ii = c0o1;
                     findPlane(ix1, ix2, ix3, grid, block, A, B, C, D, ii);
                     Vector3D pointplane1 = grid->getNodeCoordinates(block, ix1, ix2, ix3);
                     real ix1ph         = pointplane1[0];
diff --git a/src/cpu/VirtualFluidsCore/SimulationObservers/TimeAveragedValuesSimulationObserver.cpp b/src/cpu/VirtualFluidsCore/SimulationObservers/TimeAveragedValuesSimulationObserver.cpp
index ebd65f625600a1c68f48d00c33a79976ea6d1a5a..e71e0a1f211ef7703010f24ec5bac99b78233110 100644
--- a/src/cpu/VirtualFluidsCore/SimulationObservers/TimeAveragedValuesSimulationObserver.cpp
+++ b/src/cpu/VirtualFluidsCore/SimulationObservers/TimeAveragedValuesSimulationObserver.cpp
@@ -354,6 +354,8 @@ void TimeAveragedValuesSimulationObserver::addData(const SPtr<Block3D> block)
 //////////////////////////////////////////////////////////////////////////
 void TimeAveragedValuesSimulationObserver::calculateAverageValues(real timeSteps)
 {
+    using namespace vf::basics::constant;
+
     for (int level = minInitLevel; level <= maxInitLevel; level++) {
         int i;
         const int block_size = (int) blockVector[level].size();
@@ -433,25 +435,25 @@ void TimeAveragedValuesSimulationObserver::calculateAverageValues(real timeSteps
                                 if ((options & Triplecorrelations) == Triplecorrelations) {
                                     // mean triple-correlations
                                     (*at)(Vxxx, ix1, ix2, ix3) =
-                                        (*at)(Vxxx, ix1, ix2, ix3) / timeSteps - 3.0 * uxx * ux + 2.0 * ux * ux * ux;
+                                        (*at)(Vxxx, ix1, ix2, ix3) / timeSteps - c3o1 * uxx * ux + c2o1 * ux * ux * ux;
                                     (*at)(Vxxy, ix1, ix2, ix3) = (*at)(Vxxy, ix1, ix2, ix3) / timeSteps -
-                                                                 2.0 * uxy * ux - uxx * uy + 2.0 * ux * ux * uy;
+                                                                 c2o1 * uxy * ux - uxx * uy + c2o1 * ux * ux * uy;
                                     (*at)(Vxxz, ix1, ix2, ix3) = (*at)(Vxxz, ix1, ix2, ix3) / timeSteps -
-                                                                 2.0 * uxz * ux - uxx * uz + 2.0 * ux * ux * uz;
+                                                                 c2o1 * uxz * ux - uxx * uz + c2o1 * ux * ux * uz;
                                     (*at)(Vyyy, ix1, ix2, ix3) =
-                                        (*at)(Vyyy, ix1, ix2, ix3) / timeSteps - 3.0 * uyy * uy + 2.0 * uy * uy * uy;
+                                        (*at)(Vyyy, ix1, ix2, ix3) / timeSteps - c3o1 * uyy * uy + c2o1 * uy * uy * uy;
                                     (*at)(Vyyx, ix1, ix2, ix3) = (*at)(Vyyx, ix1, ix2, ix3) / timeSteps -
-                                                                 2.0 * uxy * uy - uyy * ux + 2.0 * uy * uy * ux;
+                                                                 c2o1 * uxy * uy - uyy * ux + c2o1 * uy * uy * ux;
                                     (*at)(Vyyz, ix1, ix2, ix3) = (*at)(Vyyz, ix1, ix2, ix3) / timeSteps -
-                                                                 2.0 * uyz * uy - uyy * uz + 2.0 * uy * uy * uz;
+                                                                 c2o1 * uyz * uy - uyy * uz + c2o1 * uy * uy * uz;
                                     (*at)(Vzzz, ix1, ix2, ix3) =
-                                        (*at)(Vzzz, ix1, ix2, ix3) / timeSteps - 3.0 * uzz * uz + 2.0 * uz * uz * uz;
+                                        (*at)(Vzzz, ix1, ix2, ix3) / timeSteps - c3o1 * uzz * uz + c2o1 * uz * uz * uz;
                                     (*at)(Vzzx, ix1, ix2, ix3) = (*at)(Vzzx, ix1, ix2, ix3) / timeSteps -
-                                                                 2.0 * uxz * uz - uzz * ux + 2.0 * uz * uz * ux;
+                                                                 c2o1 * uxz * uz - uzz * ux + c2o1 * uz * uz * ux;
                                     (*at)(Vzzy, ix1, ix2, ix3) = (*at)(Vzzy, ix1, ix2, ix3) / timeSteps -
-                                                                 2.0 * uyz * uz - uzz * uy + 2.0 * uz * uz * uy;
+                                                                 c2o1 * uyz * uz - uzz * uy + c2o1 * uz * uz * uy;
                                     (*at)(Vxyz, ix1, ix2, ix3) = (*at)(Vxyz, ix1, ix2, ix3) / timeSteps - uxy * uz -
-                                                                 uxz * uy - uyz * ux + 2.0 * ux * uy * uz;
+                                                                 uxz * uy - uyz * ux + c2o1 * ux * uy * uz;
                                 }
                                 //////////////////////////////////////////////////////////////////////////
                             }
@@ -577,6 +579,7 @@ void TimeAveragedValuesSimulationObserver::calculateSubtotal(real step)
 void TimeAveragedValuesSimulationObserver::planarAverage(real step)
 {
     std::ofstream ostr;
+    using namespace vf::basics::constant;
 
     if (root) {
         int istep         = int(step);
@@ -642,7 +645,7 @@ void TimeAveragedValuesSimulationObserver::planarAverage(real step)
             if (root) {
                 real numberOfFluidsNodes = intValHelp.getNumberOfFluidsNodes();
                 if (numberOfFluidsNodes > 0) {
-                    ostr << j + 0.5 * dx << std::setprecision(15);
+                    ostr << j + c1o2 * dx << std::setprecision(15);
 
                     // mean density
                     if ((options & Density) == Density) {
diff --git a/src/cpu/VirtualFluidsCore/Utilities/ChangeRandomQs.hpp b/src/cpu/VirtualFluidsCore/Utilities/ChangeRandomQs.hpp
index dbfb8907dacdad96849812a1cf5b01ccb52e1483..0c0f84b27f55d194b155688cdcae29c3e8397d83 100644
--- a/src/cpu/VirtualFluidsCore/Utilities/ChangeRandomQs.hpp
+++ b/src/cpu/VirtualFluidsCore/Utilities/ChangeRandomQs.hpp
@@ -27,10 +27,10 @@ namespace Utilities
                   if (bc->hasNoSlipBoundaryFlag(fdir))
                   {
                      const int invDir = D3Q27System::INVDIR[fdir];
-                     real q = (real) bc->getQ(invDir);
+                     float q = bc->getQ(invDir);
                      //double r = (double)UbRandom::rand(-50, 50);
-                     real r = (real)UbRandom::rand(-10, 10);
-                     real q_temp = q + q/r;
+                     float r = (float)UbRandom::rand(-10, 10);
+                     float q_temp = q + q/r;
                      if (q_temp < 0.0)
                      {
                         q_temp = 0.0001f;
diff --git a/src/cpu/VirtualFluidsCore/Visitors/Block3DVisitor.h b/src/cpu/VirtualFluidsCore/Visitors/Block3DVisitor.h
index 0c3adfb893bef12351c686e88bf907ecf6e12d99..2996ceeece9710079e898d02b0cceff447479d39 100644
--- a/src/cpu/VirtualFluidsCore/Visitors/Block3DVisitor.h
+++ b/src/cpu/VirtualFluidsCore/Visitors/Block3DVisitor.h
@@ -34,7 +34,7 @@
 #ifndef Block3DVisitor_h
 #define Block3DVisitor_h
 
-#include <PointerDefinitions.h>
+#include <basics/PointerDefinitions.h>
 
 class Block3D;
 class Grid3D;
diff --git a/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp b/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
index 2e24a2e26d1709b5c1af33d2210f269ca59f2e40..68ebae1d664d33832a6e760daf0835abbb87c75c 100644
--- a/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
+++ b/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsBlockVisitor.cpp
@@ -43,10 +43,12 @@
 
 InitDistributionsBlockVisitor::InitDistributionsBlockVisitor() : Block3DVisitor(0, D3Q27System::MAXLEVEL)
 {
-    this->setVx1(0.0);
-    this->setVx2(0.0);
-    this->setVx3(0.0);
-    this->setRho(0.0);
+    using namespace vf::basics::constant;
+    
+    this->setVx1(c0o1);
+    this->setVx2(c0o1);
+    this->setVx3(c0o1);
+    this->setRho(c0o1);
 }
 //////////////////////////////////////////////////////////////////////////
 void InitDistributionsBlockVisitor::setVx1(const mu::Parser &parser)
@@ -125,6 +127,7 @@ void InitDistributionsBlockVisitor::visit(const SPtr<Grid3D> grid, SPtr<Block3D>
 {
    using namespace D3Q27System;
    using namespace vf::lbm::dir;
+   using namespace vf::basics::constant;
 
    if(!block) UB_THROW( UbException(UB_EXARGS,"block is not exist") );
 
@@ -214,38 +217,38 @@ void InitDistributionsBlockVisitor::visit(const SPtr<Grid3D> grid, SPtr<Block3D>
                real vx2Minusx3 = muVx2.Eval();
                real vx3Minusx3 = muVx3.Eval();
 
-               real ax=(vx1Plusx1-vx1Minusx1)/(2.0*deltaX)*dx;
-               real bx=(vx2Plusx1-vx2Minusx1)/(2.0*deltaX)*dx;
-               real cx=(vx3Plusx1-vx3Minusx1)/(2.0*deltaX)*dx;
+               real ax=(vx1Plusx1-vx1Minusx1)/(c2o1*deltaX)*dx;
+               real bx=(vx2Plusx1-vx2Minusx1)/(c2o1*deltaX)*dx;
+               real cx=(vx3Plusx1-vx3Minusx1)/(c2o1*deltaX)*dx;
 
-               real ay=(vx1Plusx2-vx1Minusx2)/(2.0*deltaX)*dx;
-               real by=(vx2Plusx2-vx2Minusx2)/(2.0*deltaX)*dx;
-               real cy=(vx3Plusx2-vx3Minusx2)/(2.0*deltaX)*dx;
+               real ay=(vx1Plusx2-vx1Minusx2)/(c2o1*deltaX)*dx;
+               real by=(vx2Plusx2-vx2Minusx2)/(c2o1*deltaX)*dx;
+               real cy=(vx3Plusx2-vx3Minusx2)/(c2o1*deltaX)*dx;
 
-               real az=(vx1Plusx3-vx1Minusx3)/(2.0*deltaX)*dx;
-               real bz=(vx2Plusx3-vx2Minusx3)/(2.0*deltaX)*dx;
-               real cz=(vx3Plusx3-vx3Minusx3)/(2.0*deltaX)*dx;
-               real eps_new=1.0;
-               real op = 1.;
+               real az=(vx1Plusx3-vx1Minusx3)/(c2o1*deltaX)*dx;
+               real bz=(vx2Plusx3-vx2Minusx3)/(c2o1*deltaX)*dx;
+               real cz=(vx3Plusx3-vx3Minusx3)/(c2o1*deltaX)*dx;
+               real eps_new=c1o1;
+               real op = c1o1;
 
                real feq[27];
 
                calcFeqsFct(feq,rho,vx1,vx2,vx3);
 
-               real f_E    = eps_new *((5.*ax*o + 5.*by*o + 5.*cz*o - 8.*ax*op + 4.*by*op + 4.*cz*op)/(54.*o*op));
-               real f_N    = f_E + eps_new *((2.*(ax - by))/(9.*o));
-               real f_T    = f_E + eps_new *((2.*(ax - cz))/(9.*o));
-               real f_NE   = eps_new *(-(5.*cz*o + 3.*(ay + bx)*op - 2.*cz*op + ax*(5.*o + op) + by*(5.*o + op))/(54.*o*op));
-               real f_SE   = f_NE + eps_new *((  ay + bx )/(9.*o));
-               real f_TE   = eps_new *(-(5.*cz*o + by*(5.*o - 2.*op) + 3.*(az + cx)*op + cz*op + ax*(5.*o + op))/(54.*o*op));
-               real f_BE   = f_TE + eps_new *((  az + cx )/(9.*o));
-               real f_TN   = eps_new *(-(5.*ax*o + 5.*by*o + 5.*cz*o - 2.*ax*op + by*op + 3.*bz*op + 3.*cy*op + cz*op)/(54.*o*op));
-               real f_BN   = f_TN + eps_new *((  bz + cy )/(9.*o));
-               real f_ZERO = eps_new *((5.*(ax + by + cz))/(9.*op));
-               real f_TNE  = eps_new *(-(ay + az + bx + bz + cx + cy)/(72.*o));
-               real f_TSW  = - eps_new *((ay + bx)/(36.*o)) - f_TNE;
-               real f_TSE  = - eps_new *((az + cx)/(36.*o)) - f_TNE;
-               real f_TNW  = - eps_new *((bz + cy)/(36.*o)) - f_TNE;
+               real f_E    = eps_new *((c5o1*ax*o + c5o1*by*o + c5o1*cz*o - c8o1*ax*op + c4o1*by*op + c4o1*cz*op)/(c54o1*o*op));
+               real f_N    = f_E + eps_new *((c2o1*(ax - by))/(c9o1*o));
+               real f_T    = f_E + eps_new *((c2o1*(ax - cz))/(c9o1*o));
+               real f_NE   = eps_new *(-(c5o1*cz*o + c3o1*(ay + bx)*op - c2o1*cz*op + ax*(c5o1*o + op) + by*(c5o1*o + op))/(c54o1*o*op));
+               real f_SE   = f_NE + eps_new *((  ay + bx )/(c9o1*o));
+               real f_TE   = eps_new *(-(c5o1*cz*o + by*(c5o1*o - c2o1*op) + c3o1*(az + cx)*op + cz*op + ax*(c5o1*o + op))/(c54o1*o*op));
+               real f_BE   = f_TE + eps_new *((  az + cx )/(c9o1*o));
+               real f_TN   = eps_new *(-(c5o1*ax*o + c5o1*by*o + c5o1*cz*o - c2o1*ax*op + by*op + c3o1*bz*op + c3o1*cy*op + cz*op)/(c54o1*o*op));
+               real f_BN   = f_TN + eps_new *((  bz + cy )/(c9o1*o));
+               real f_ZERO = eps_new *((c5o1*(ax + by + cz))/(c9o1*op));
+               real f_TNE  = eps_new *(-(ay + az + bx + bz + cx + cy)/(c72o1*o));
+               real f_TSW  = - eps_new *((ay + bx)/(c36o1*o)) - f_TNE;
+               real f_TSE  = - eps_new *((az + cx)/(c36o1*o)) - f_TNE;
+               real f_TNW  = - eps_new *((bz + cy)/(c36o1*o)) - f_TNE;
 
 
                f[DIR_P00]    = f_E    + feq[DIR_P00];
@@ -298,7 +301,9 @@ void InitDistributionsBlockVisitor::visit(const SPtr<Grid3D> grid, SPtr<Block3D>
 //////////////////////////////////////////////////////////////////////////
 void InitDistributionsBlockVisitor::checkFunction(mu::Parser fct)
 {
-    real x1 = 1.0, x2 = 1.0, x3 = 1.0;
+    using namespace vf::basics::constant;
+    
+    real x1 = c1o1, x2 = c1o1, x3 = c1o1;
     fct.DefineVar("x1", &x1);
     fct.DefineVar("x2", &x2);
     fct.DefineVar("x3", &x3);
diff --git a/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp b/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp
index 660363e22e7c315a40df596aa95137f5589fff72..e6ab0193cdbc417c28fa90fa83fa897570048ae3 100644
--- a/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp
+++ b/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.cpp
@@ -8,7 +8,7 @@
 #include "DataSet3D.h"
 #include "Grid3D.h"
 #include "D3Q27System.h"
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 #include "LBMKernel.h"
 #include <CbArray2D.h>
 #include <basics/utilities/UbFileInputASCII.h>
@@ -163,6 +163,8 @@ void InitDistributionsWithInterpolationGridVisitor::copyRemoteBlock(SPtr<Block3D
 void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlockCoarseToFine(SPtr<Block3D> oldBlock,
                                                                                       SPtr<Block3D> newBlock)
 {
+    using namespace vf::basics::constant;
+    
     D3Q27ICell icellC;
     D3Q27ICell icellF;
     real xoff, yoff, zoff;
@@ -225,14 +227,14 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlockCoarseT
                         iProcessor->interpolateCoarseToFine(icellC, icellF, xoff, yoff, zoff);
                     } else {
                         for (int i = 0; i < 27; i++) {
-                            icellF.BSW[i] = 0.0;
-                            icellF.BSE[i] = 0.0;
-                            icellF.BNW[i] = 0.0;
-                            icellF.BNE[i] = 0.0;
-                            icellF.TSW[i] = 0.0;
-                            icellF.TSE[i] = 0.0;
-                            icellF.TNW[i] = 0.0;
-                            icellF.TNE[i] = 0.0;
+                            icellF.BSW[i] = c0o1;
+                            icellF.BSE[i] = c0o1;
+                            icellF.BNW[i] = c0o1;
+                            icellF.BNE[i] = c0o1;
+                            icellF.TSW[i] = c0o1;
+                            icellF.TSE[i] = c0o1;
+                            icellF.TNW[i] = c0o1;
+                            icellF.TNE[i] = c0o1;
                         }
                         //                     std::string err = "For "+oldBlock->toString()+
                         //   " x1="+UbSystem::toString(val<1>(oldGridIndexMin))+
@@ -254,6 +256,8 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlockCoarseT
 void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockCoarseToFine(SPtr<Block3D> oldBlock,
                                                                                        SPtr<Block3D> newBlock)
 {
+    using namespace vf::basics::constant;
+    
     int newGridRank  = newGrid->getRank();
     int oldBlockRank = oldBlock->getRank();
     int newBlockRank = newBlock->getRank();
@@ -363,14 +367,14 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockCoarse
                             iProcessor->interpolateCoarseToFine(icellC, icellF, xoff, yoff, zoff);
                         } else {
                             for (int i = 0; i < 27; i++) {
-                                icellF.BSW[i] = 0.0;
-                                icellF.BSE[i] = 0.0;
-                                icellF.BNW[i] = 0.0;
-                                icellF.BNE[i] = 0.0;
-                                icellF.TSW[i] = 0.0;
-                                icellF.TSE[i] = 0.0;
-                                icellF.TNW[i] = 0.0;
-                                icellF.TNE[i] = 0.0;
+                                icellF.BSW[i] = c0o1;
+                                icellF.BSE[i] = c0o1;
+                                icellF.BNW[i] = c0o1;
+                                icellF.BNE[i] = c0o1;
+                                icellF.TSW[i] = c0o1;
+                                icellF.TSE[i] = c0o1;
+                                icellF.TNW[i] = c0o1;
+                                icellF.TNE[i] = c0o1;
                             }
                             //                     std::string err = "For "+oldBlock->toString()+
                             //   " x1="+UbSystem::toString(val<1>(oldGridIndexMin))+
@@ -393,6 +397,8 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockCoarse
 void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlockFineToCoarse(SPtr<Block3D> oldBlock,
                                                                                       SPtr<Block3D> newBlock)
 {
+    using namespace vf::basics::constant;
+    
     real icellC[27];
     D3Q27ICell icellF;
     real xoff, yoff, zoff;
@@ -456,14 +462,14 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlockFineToC
                         iProcessor->interpolateFineToCoarse(icellF, icellC, xoff, yoff, zoff);
                     } else {
                         for (int i = 0; i < 27; i++) {
-                            icellF.BSW[i] = 0.0;
-                            icellF.BSE[i] = 0.0;
-                            icellF.BNW[i] = 0.0;
-                            icellF.BNE[i] = 0.0;
-                            icellF.TSW[i] = 0.0;
-                            icellF.TSE[i] = 0.0;
-                            icellF.TNW[i] = 0.0;
-                            icellF.TNE[i] = 0.0;
+                            icellF.BSW[i] = c0o1;
+                            icellF.BSE[i] = c0o1;
+                            icellF.BNW[i] = c0o1;
+                            icellF.BNE[i] = c0o1;
+                            icellF.TSW[i] = c0o1;
+                            icellF.TSE[i] = c0o1;
+                            icellF.TNW[i] = c0o1;
+                            icellF.TNE[i] = c0o1;
                         }
                         //                     std::string err = "For "+oldBlock->toString()+
                         //   " x1="+UbSystem::toString(val<1>(oldGridIndexMin))+
@@ -485,6 +491,8 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateLocalBlockFineToC
 void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockFineToCoarse(SPtr<Block3D> oldBlock,
                                                                                        SPtr<Block3D> newBlock)
 {
+    using namespace vf::basics::constant;
+    
     int newGridRank  = newGrid->getRank();
     int oldBlockRank = oldBlock->getRank();
     int newBlockRank = newBlock->getRank();
@@ -594,14 +602,14 @@ void InitDistributionsWithInterpolationGridVisitor::interpolateRemoteBlockFineTo
                             iProcessor->interpolateFineToCoarse(icellF, icellC, xoff, yoff, zoff);
                         } else {
                             for (int i = 0; i < 27; i++) {
-                                icellF.BSW[i] = 0.0;
-                                icellF.BSE[i] = 0.0;
-                                icellF.BNW[i] = 0.0;
-                                icellF.BNE[i] = 0.0;
-                                icellF.TSW[i] = 0.0;
-                                icellF.TSE[i] = 0.0;
-                                icellF.TNW[i] = 0.0;
-                                icellF.TNE[i] = 0.0;
+                                icellF.BSW[i] = c0o1;
+                                icellF.BSE[i] = c0o1;
+                                icellF.BNW[i] = c0o1;
+                                icellF.BNE[i] = c0o1;
+                                icellF.TSW[i] = c0o1;
+                                icellF.TSE[i] = c0o1;
+                                icellF.TNW[i] = c0o1;
+                                icellF.TNE[i] = c0o1;
                             }
                             //                     std::string err = "For "+oldBlock->toString()+
                             //   " x1="+UbSystem::toString(val<1>(oldGridIndexMin))+
diff --git a/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h b/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h
index a143ab6b0b40a8b35023a4916ffcbd20ae4b726c..eab801e448b4c797c7260274af66ea50a4677def 100644
--- a/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h
+++ b/src/cpu/VirtualFluidsCore/Visitors/InitDistributionsWithInterpolationGridVisitor.h
@@ -8,12 +8,12 @@
 
 class Grid3D;
 class Block3D;
-class InterpolationProcessor;
+class Interpolator;
 
 class InitDistributionsWithInterpolationGridVisitor : public Grid3DVisitor
 {
 public:
-    InitDistributionsWithInterpolationGridVisitor(SPtr<Grid3D> oldGrid, SPtr<InterpolationProcessor> iProcessor,
+    InitDistributionsWithInterpolationGridVisitor(SPtr<Grid3D> oldGrid, SPtr<Interpolator> iProcessor,
                                                   real nu);
     ~InitDistributionsWithInterpolationGridVisitor() override;
     void visit(SPtr<Grid3D> grid) override;
@@ -30,7 +30,7 @@ private:
     SPtr<Grid3D> oldGrid;
     real nu;
 
-    SPtr<InterpolationProcessor> iProcessor;
+    SPtr<Interpolator> iProcessor;
 };
 
 #endif // InitDistributionsWithVelocityProfileBlockVisitor_h__
diff --git a/src/cpu/VirtualFluidsCore/Visitors/InitThixotropyBlockVisitor.cpp b/src/cpu/VirtualFluidsCore/Visitors/InitThixotropyBlockVisitor.cpp
index be0c694bc733ff3b9ebd808d533757f98eefe73c..79c354e5f28724279447a4751ba81c3b6eba0958 100644
--- a/src/cpu/VirtualFluidsCore/Visitors/InitThixotropyBlockVisitor.cpp
+++ b/src/cpu/VirtualFluidsCore/Visitors/InitThixotropyBlockVisitor.cpp
@@ -1,4 +1,4 @@
-//=======================================================================================
+ //=======================================================================================
 // ____          ____    __    ______     __________   __      __       __        __
 // \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
 //  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
@@ -44,6 +44,8 @@
 InitThixotropyBlockVisitor::InitThixotropyBlockVisitor()
    : Block3DVisitor(0, D3Q27System::MAXLEVEL)
 {
+    using namespace vf::basics::constant;
+
    //this->setVx1(0.0);
    //this->setVx2(0.0);
    //this->setVx3(0.0);
@@ -52,7 +54,7 @@ InitThixotropyBlockVisitor::InitThixotropyBlockVisitor()
    //this->setf2(0.0);
    //this->setf3(0.0);
    //this->setConcentration(0.0);
-   this->setLambda(0.0);
+   this->setLambda(c0o1);
 }
 //////////////////////////////////////////////////////////////////////////
 //InitThixotropyBlockVisitor::InitThixotropyBlockVisitor(LBMReal lambda /*LBMReal nu, LBMReal D, LBMReal rho, LBMReal vx1, LBMReal vx2, LBMReal vx3, LBMReal c, LBMReal f1, LBMReal f2, LBMReal f3*/)
@@ -218,6 +220,7 @@ void InitThixotropyBlockVisitor::setLambda(real lambda)
 void InitThixotropyBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block)
 {
    using namespace D3Q27System;
+   using namespace vf::basics::constant;
 
    if(!block) UB_THROW( UbException(UB_EXARGS,"block is not exist") );
 
@@ -283,7 +286,7 @@ void InitThixotropyBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block)
 
                real lambda = muLambda.Eval();
                
-               calcFeqsFct(h,lambda,0.0,0.0,0.0);
+               calcFeqsFct(h,lambda,c0o1,c0o1,c0o1);
                
                distributions->setDistribution(h, ix1, ix2, ix3);
                distributions->setDistributionInv(h, ix1, ix2, ix3);
diff --git a/src/cpu/VirtualFluidsCore/Visitors/SetInterpolationConnectorsBlockVisitor.cpp b/src/cpu/VirtualFluidsCore/Visitors/SetInterpolationConnectorsBlockVisitor.cpp
index 7ff7d20b9fcd85b6939f3184fcde86c6fdaae77d..362e8c92751e1275bfdaa7d7daf1567f117ecdf4 100644
--- a/src/cpu/VirtualFluidsCore/Visitors/SetInterpolationConnectorsBlockVisitor.cpp
+++ b/src/cpu/VirtualFluidsCore/Visitors/SetInterpolationConnectorsBlockVisitor.cpp
@@ -40,9 +40,9 @@
 #include <basics/transmitter/TbTransmitterLocal.h>
 
 #include <mpi/Communicator.h>
-#include "InterpolationProcessor.h"
+#include "Interpolator.h"
 
-SetInterpolationConnectorsBlockVisitor::SetInterpolationConnectorsBlockVisitor(std::shared_ptr<vf::mpi::Communicator> comm, real nue, SPtr<InterpolationProcessor> iProcessor) :
+SetInterpolationConnectorsBlockVisitor::SetInterpolationConnectorsBlockVisitor(std::shared_ptr<vf::mpi::Communicator> comm, real nue, SPtr<Interpolator> iProcessor) :
 Block3DVisitor(0, D3Q27System::MAXLEVEL), 
 	comm(comm),
 	nue(nue),
diff --git a/src/cpu/VirtualFluidsCore/Visitors/SetInterpolationConnectorsBlockVisitor.h b/src/cpu/VirtualFluidsCore/Visitors/SetInterpolationConnectorsBlockVisitor.h
index c30d87ecaa042a30d931e29ba185fdd5230e2a68..b1f6f99e1c4eff543f87dfcd70e7b45bf27701d5 100644
--- a/src/cpu/VirtualFluidsCore/Visitors/SetInterpolationConnectorsBlockVisitor.h
+++ b/src/cpu/VirtualFluidsCore/Visitors/SetInterpolationConnectorsBlockVisitor.h
@@ -44,13 +44,13 @@
 class Grid3D;
 class Block3D;
 namespace vf::mpi {class Communicator;}
-class InterpolationProcessor;
+class Interpolator;
 
 //! \brief  A class sets connectors between blocks.
 class SetInterpolationConnectorsBlockVisitor : public Block3DVisitor
 {
 public:
-    SetInterpolationConnectorsBlockVisitor(std::shared_ptr<vf::mpi::Communicator> comm, real nue, SPtr<InterpolationProcessor> iProcessor);
+    SetInterpolationConnectorsBlockVisitor(std::shared_ptr<vf::mpi::Communicator> comm, real nue, SPtr<Interpolator> iProcessor);
     ~SetInterpolationConnectorsBlockVisitor() override;
     void visit(SPtr<Grid3D> grid, SPtr<Block3D> block) override;
     //////////////////////////////////////////////////////////////////////////
@@ -66,7 +66,7 @@ protected:
     std::shared_ptr<vf::mpi::Communicator> comm;
     int gridRank;
     real nue;
-    SPtr<InterpolationProcessor> iProcessor;
+    SPtr<Interpolator> iProcessor;
 };
 
 #endif // SetInterpolationConnectorsBlockVisitor_H
diff --git a/src/cpu/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp b/src/cpu/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp
index fed80000c562b8aafdefd83ff2791781a8907f7a..1111429442829adca999bf6c587819419c8bd9fb 100644
--- a/src/cpu/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp
+++ b/src/cpu/VirtualFluidsCore/Visitors/SetKernelBlockVisitor.cpp
@@ -124,6 +124,8 @@ void SetKernelBlockVisitor::throwExceptionIfNotEnoughMemory(const SPtr<Grid3D> &
 
 real SetKernelBlockVisitor::getRequiredPhysicalMemory(const SPtr<Grid3D> &grid) const
 {
+    using namespace vf::basics::constant;
+
     unsigned long long numberOfNodesPerBlockWithGhostLayer;
     auto numberOfBlocks = (unsigned long long)grid->getNumberOfBlocks();
     auto blockNx        = grid->getBlockNX();
@@ -133,7 +135,7 @@ real SetKernelBlockVisitor::getRequiredPhysicalMemory(const SPtr<Grid3D> &grid)
                                           (val<2>(blockNx) + ghostLayer) * (val<3>(blockNx) + ghostLayer);
 
     auto needMemAll =
-        real(numberOfNodesPerBlockWithGhostLayer * (27 * sizeof(real) + sizeof(int) + sizeof(float) * 4));
+        real(numberOfNodesPerBlockWithGhostLayer * (c27o1 * sizeof(real) + sizeof(int) + sizeof(float) * c4o1));
 
     return needMemAll / real(numberOfProcesses);
 }
diff --git a/src/cpu/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.h b/src/cpu/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.h
index 329662ec8aeb6405c8f8f4b06645c9d1500a59e6..17fa5b2ebb2b7230955e9ce4209a3cb341369326 100644
--- a/src/cpu/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.h
+++ b/src/cpu/VirtualFluidsCore/Visitors/SetUndefinedNodesBlockVisitor.h
@@ -1,7 +1,7 @@
 #ifndef SetUndefinedNodesBlockVisitor_h
 #define SetUndefinedNodesBlockVisitor_h
 
-#include <PointerDefinitions.h>
+#include <basics/PointerDefinitions.h>
 
 #include "Block3DVisitor.h"
 
diff --git a/src/cpu/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp b/src/cpu/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp
index 4cdcfb80bb4aa3119f1e2ca4dfcd19c2abf381dd..520c7cfa30f582438b188643d8f913fd6ce2bd0b 100644
--- a/src/cpu/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp
+++ b/src/cpu/VirtualFluidsCore/Visitors/SpongeLayerBlockVisitor.cpp
@@ -24,6 +24,7 @@ SpongeLayerBlockVisitor::~SpongeLayerBlockVisitor() = default;
 void SpongeLayerBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block)
 {
     using namespace vf::lbm::dir;
+    using namespace vf::basics::constant;
 
     if (!boundingBox) {
         UB_THROW(UbException(UB_EXARGS, "The bounding box isn't set!"));
@@ -78,22 +79,22 @@ void SpongeLayerBlockVisitor::visit(SPtr<Grid3D> grid, SPtr<Block3D> block)
                 int ibX1      = block->getX1();
                 int ibMax     = val<1>(ixMax) - val<1>(ixMin) + 1;
                 real index  = (real)(ibX1 - val<1>(ixMin) + 1);
-                newCollFactor = oldCollFactor - (oldCollFactor - 1.0) / (real)(ibMax)*index;
+                newCollFactor = oldCollFactor - (oldCollFactor - c1o1) / (real)(ibMax)*index;
             } else if (dir == DIR_M00) {
                 int ibX1      = block->getX1();
                 int ibMax     = val<1>(ixMax) - val<1>(ixMin) + 1;
                 real index  = (real)(ibX1 - val<1>(ixMin) + 1);
-                newCollFactor = (oldCollFactor - 1.0) / (real)(ibMax)*index;
+                newCollFactor = (oldCollFactor - c1o1) / (real)(ibMax)*index;
             } else if (dir == DIR_00P) {
                 int ibX3      = block->getX3();
                 int ibMax     = val<3>(ixMax) - val<3>(ixMin) + 1;
                 real index  = (real)(ibX3 - val<3>(ixMin) + 1);
-                newCollFactor = oldCollFactor - (oldCollFactor - 1.0) / (real)(ibMax)*index;
+                newCollFactor = oldCollFactor - (oldCollFactor - c1o1) / (real)(ibMax)*index;
             } else if (dir == DIR_00M) {
                 int ibX3      = block->getX3();
                 int ibMax     = val<3>(ixMax) - val<3>(ixMin) + 1;
                 real index  = (real)(ibX3 - val<3>(ixMin) + 1);
-                newCollFactor = (oldCollFactor - 1.0) / (real)(ibMax)*index;
+                newCollFactor = (oldCollFactor - c1o1) / (real)(ibMax)*index;
             } else
                 UB_THROW(UbException(UB_EXARGS, "Problem: no orthogonal sponge layer!"));
 
diff --git a/src/cpu/simulationconfig/Simulation.cpp b/src/cpu/simulationconfig/Simulation.cpp
index ec8773515ce49bdb8c0680152924605203ba9405..67c4e469d41ea24f1029f09e1beb78a597974e4c 100644
--- a/src/cpu/simulationconfig/Simulation.cpp
+++ b/src/cpu/simulationconfig/Simulation.cpp
@@ -26,7 +26,7 @@
 #include <Simulation/Simulation.h>
 #include <Simulation/Grid3D.h>
 #include <Interactors/InteractorsHelper.h>
-#include <LBM/CompressibleOffsetMomentsInterpolationProcessor.h>
+#include <LBM/Interpolation/CompressibleOffsetMomentsInterpolator.h>
 #include <LBM/LBMKernel.h>
 #include <LBM/LBMUnitConverter.h>
 #include <mpi/MPICommunicator.h>
diff --git a/src/cuda/DeviceInfo.cpp b/src/cuda/DeviceInfo.cpp
index 20ea2c4f6ba098b17e444f55625a6791e46141e5..81fea1cf21418ef98217293985f8c1101f8635be 100644
--- a/src/cuda/DeviceInfo.cpp
+++ b/src/cuda/DeviceInfo.cpp
@@ -15,7 +15,7 @@ void verifyNumberOfDevices(int deviceId)
     int device_count = 0;
     cudaError_t errorId = cudaGetDeviceCount(&device_count);
     if(errorId != cudaSuccess) {
-        VF_LOG_CRITICAL("Error while accessing the device count: {}", cudaGetErrorString(errorId));
+        VF_LOG_CRITICAL("Device {}: Error while accessing the device count: {}", deviceId, cudaGetErrorString(errorId));
     }
     if (deviceId > device_count) {
         throw std::runtime_error("chosen gpudevice >=  device_count ... exiting\n");
@@ -28,13 +28,13 @@ void verifyComputeCapability(int deviceId)
     cudaError_t errorId = cudaGetDeviceProperties(&deviceProp, deviceId);
 
     if(errorId != cudaSuccess){
-        VF_LOG_CRITICAL("Error while accessing the device properties occurs: {}", cudaGetErrorString(errorId));
+        VF_LOG_CRITICAL("Device {}: Error while accessing the device properties occurs: {}", deviceId, cudaGetErrorString(errorId));
     }
 
     VF_LOG_INFO("[compute capability] = [{}.{}]\n", deviceProp.major, deviceProp.minor);
 
     if (deviceProp.major > 999) {
-        throw std::runtime_error("warning, CUDA Device Emulation (CPU) detected, exiting\n");
+        throw std::runtime_error("Warning, CUDA Device Emulation (CPU) detected, exiting\n");
     }
 }
 
@@ -43,13 +43,13 @@ void setCudaDevice(int deviceId)
     // choose a cuda device for kernel execution
     cudaError_t errorId = cudaSetDevice(deviceId);
     if (errorId != cudaSuccess) {
-        VF_LOG_CRITICAL("Error while setting the device to {}: {}", deviceId, cudaGetErrorString(errorId));
+        VF_LOG_CRITICAL("Device {}: Error while setting the device to: {}", deviceId, cudaGetErrorString(errorId));
     } else {
         int device;
         // double check that device was properly selected
         errorId = cudaGetDevice(&device);
         if(errorId != cudaSuccess) {
-            VF_LOG_CRITICAL("Error while getting the device: {}", cudaGetErrorString(errorId));
+            VF_LOG_CRITICAL("Device {}: Error while getting the device: {}", deviceId, cudaGetErrorString(errorId));
         }
     }
 }
@@ -70,7 +70,7 @@ void printCudaInformation(int deviceId)
     cudaError_t errorId = cudaGetDeviceProperties(&prop, deviceId);
 
     if(errorId != cudaSuccess){
-        VF_LOG_CRITICAL("Error while accessing the device properties occurs: {}", cudaGetErrorString(errorId));
+        VF_LOG_CRITICAL("Device {}: Error while accessing the device properties occurs: {}", deviceId, cudaGetErrorString(errorId));
     }
 
     printf(" --- General Information for device %d ---\n", deviceId);
diff --git a/src/gpu/GridGenerator/TransientBCSetter/TransientBCSetter.cpp b/src/gpu/GridGenerator/TransientBCSetter/TransientBCSetter.cpp
index 571796d503a1a73b3eccf631a347884c7522b533..15efa9d3204cc37d4c4ccd8778ea13769ef655b8 100644
--- a/src/gpu/GridGenerator/TransientBCSetter/TransientBCSetter.cpp
+++ b/src/gpu/GridGenerator/TransientBCSetter/TransientBCSetter.cpp
@@ -49,16 +49,16 @@ std::vector<T> readStringToVector(std::string s)
 
 std::string readElement(std::string line)
 {
-    size_t elemStart = line.find("<")+1;
+    const size_t elemStart = line.find('<')+1;
     // size_t elemEnd = line.find("/>", elemStart);
-    size_t nameLen = line.find(" ", elemStart)-elemStart;
+    const size_t nameLen = line.find(' ', elemStart)-elemStart;
     return line.substr(elemStart, nameLen);
 }
 
 std::string readAttribute(std::string line, std::string attributeName)
 {
-    size_t attributeStart = line.find(attributeName)+attributeName.size() + 2; // add 2 for '="'
-    size_t attributeLen = line.find("\"", attributeStart)-attributeStart;
+    const size_t attributeStart = line.find(attributeName)+attributeName.size() + 2; // add 2 for '="'
+    const size_t attributeLen = line.find("\"", attributeStart)-attributeStart;
     return line.substr(attributeStart, attributeLen);
 }
 
@@ -94,7 +94,7 @@ void VTKFile::readHeader()
     getline(file, line); // </ImageData
     getline(file, line); // AppendedData
 
-    int offset = int(file.tellg())+sizeof(char)+4; // skip underscore and bytesPerVal
+    const int offset = int(file.tellg())+sizeof(char)+4; // skip underscore and bytesPerVal
 
     for(auto& quantity: this->quantities)
     {
@@ -118,7 +118,7 @@ void VTKFile::readHeader()
 
 }
 
-bool VTKFile::markNANs(std::vector<uint> readIndices)
+bool VTKFile::markNANs(const std::vector<uint>& readIndices) const
 {
     std::ifstream buf(fileName.c_str(), std::ios::in | std::ios::binary);
 
@@ -126,7 +126,7 @@ bool VTKFile::markNANs(std::vector<uint> readIndices)
     tmp.reserve(readIndices.size());
     buf.seekg(this->quantities[0].offset);
     buf.read((char*) tmp.data(), sizeof(double)*readIndices.size());
-    auto firstNAN = std::find_if(tmp.begin(), tmp.end(), [](auto it){ return isnan(it); });
+    const auto firstNAN = std::find_if(tmp.begin(), tmp.end(), [](auto it){ return isnan(it); });
     
     return firstNAN != tmp.end();
 }
@@ -161,7 +161,7 @@ void VTKFile::getData(real *data, uint numberOfNodes, const std::vector<uint> &r
 {
     if(!this->loaded) loadFile();
 
-    size_t nPoints = writeIndices.size();
+    const size_t nPoints = writeIndices.size();
 
     for(size_t j=0; j<this->quantities.size(); j++)
     {
@@ -177,7 +177,7 @@ void VTKFile::printFileInfo()
 {
     printf("file %s with \n nx %i ny %i nz %i \n origin %f %f %f \n spacing %f %f %f \n", 
             fileName.c_str(), nx, ny, nz, minX, minY, minZ, deltaX, deltaY, deltaZ);
-    for(auto quantity: this->quantities)
+    for(const auto& quantity: this->quantities)
     {
         printf("\t quantity %s offset %i \n", quantity.name.c_str(), quantity.offset);
     }
@@ -199,8 +199,8 @@ void VTKFileCollection::findFiles()
             std::vector<VTKFile> filesWithThisId;
             while (!foundLastPart)
             {
-                std::string fname = makeFileName((int)files.size(), (int)filesOnThisLevel.size(), (int)filesWithThisId.size());
-                std::ifstream f(fname);
+                const std::string fname = makeFileName((int)files.size(), (int)filesOnThisLevel.size(), (int)filesWithThisId.size());
+                const std::ifstream f(fname);
                 if(f.good())
                     filesWithThisId.emplace_back(fname);
                 else
@@ -223,7 +223,7 @@ void VTKFileCollection::findFiles()
     }
 
     if(files.empty())
-        VF_LOG_CRITICAL("VTKFileCollection found no files!"); 
+        throw std::runtime_error("VTKFileCollection found no files!");
 }
     
 void TransientBCInputFileReader::getNeighbors(uint* neighbor0PP, uint* neighbor0PM, uint* neighbor0MP, uint* neighbor0MM)
@@ -260,8 +260,8 @@ void VTKReader::fillArrays(std::vector<real>& coordsY, std::vector<real>& coords
 {
     this->nPoints = (uint)coordsY.size();
     this->initializeIndexVectors();
-    real max_diff = 1e-4; // maximum distance between point on grid and precursor plane to count as exact match
-    real eps = 1e-7; // small number to avoid division by zero
+    const real max_diff = 1e-4; // maximum distance between point on grid and precursor plane to count as exact match
+    const real eps = 1e-7; // small number to avoid division by zero
     bool perfect_match = true;
 
     this->weights0PP.reserve(this->nPoints);
@@ -277,11 +277,11 @@ void VTKReader::fillArrays(std::vector<real>& coordsY, std::vector<real>& coords
     for(uint i=0; i<nPoints; i++)
     {
 
-        real posY = coordsY[i];
-        real posZ = coordsZ[i];
+        const real posY = coordsY[i];
+        const real posZ = coordsZ[i];
         bool found0PP = false, found0PM = false, found0MP = false, found0MM = false, foundAll = false;
 
-        uint level = this->readLevel;
+        const uint level = this->readLevel;
 
         for(int fileId=0; fileId<(int)this->fileCollection->files[level].size(); fileId++)
         {
@@ -290,7 +290,7 @@ void VTKReader::fillArrays(std::vector<real>& coordsY, std::vector<real>& coords
 
             // y in simulation is x in precursor/file, z in simulation is y in precursor/file 
             // simulation -> file: N -> E, S -> W, T -> N, B -> S
-            int idx = file.findNeighborMMM(posY, posZ, 0.f);                            //!> index of nearest WSB neighbor on precursor file
+            const int idx = file.findNeighborMMM(posY, posZ, 0.f);                            //!> index of nearest WSB neighbor on precursor file
             
             if(idx!=-1)
             {
@@ -301,7 +301,7 @@ void VTKReader::fillArrays(std::vector<real>& coordsY, std::vector<real>& coords
                     this->weights0PM.emplace_back(0.f);
                     this->weights0MP.emplace_back(0.f);
                     this->weights0MM.emplace_back(0.f);
-                    uint writeIdx = this->getWriteIndex(level, fileId, idx);            //!> writeIdx: index on host/device array where precursor value will be written to after loading from file
+                    const uint writeIdx = this->getWriteIndex(level, fileId, idx);            //!> writeIdx: index on host/device array where precursor value will be written to after loading from file
                     this->planeNeighbor0PP.push_back(writeIdx);                          //!> neighbor lists mapping where BC kernel should read from on host/device array
                     this->planeNeighbor0PM.push_back(writeIdx);
                     this->planeNeighbor0MP.push_back(writeIdx);
@@ -319,8 +319,8 @@ void VTKReader::fillArrays(std::vector<real>& coordsY, std::vector<real>& coords
                 if(!found0MM)
                 {
                     found0MM = true;
-                    real dy = file.getX(idx)-posY;
-                    real dz = file.getY(idx)-posZ;
+                    const real dy = file.getX(idx)-posY;
+                    const real dz = file.getY(idx)-posZ;
                     this->weights0MM.emplace_back(1.f/(dy*dy+dz*dz+eps));
                     this->planeNeighbor0MM.emplace_back(getWriteIndex(level, fileId, idx));
                 }
@@ -329,12 +329,12 @@ void VTKReader::fillArrays(std::vector<real>& coordsY, std::vector<real>& coords
             
             if(!found0PP) //NT in simulation is EN in precursor
             {
-                int index = file.findNeighborPPM(posY, posZ, 0.f);
+                const int index = file.findNeighborPPM(posY, posZ, 0.f);
                 if(index!=-1)
                 {
                     found0PP = true;
-                    real dy = file.getX(index)-posY;
-                    real dz = file.getY(index)-posZ;
+                    const real dy = file.getX(index)-posY;
+                    const real dz = file.getY(index)-posZ;
                     this->weights0PP.emplace_back(1.f/(dy*dy+dz*dz+eps));
                     this->planeNeighbor0PP.emplace_back(getWriteIndex(level, fileId, index));
                 }
@@ -342,12 +342,12 @@ void VTKReader::fillArrays(std::vector<real>& coordsY, std::vector<real>& coords
 
             if(!found0PM) //NB in simulation is ES in precursor
             {
-                int index = file.findNeighborPMM(posY, posZ, 0.f);
+                const int index = file.findNeighborPMM(posY, posZ, 0.f);
                 if(index!=-1)
                 {
                     found0PM = true;
-                    real dy = file.getX(index)-posY;
-                    real dz = file.getY(index)-posZ;
+                    const real dy = file.getX(index)-posY;
+                    const real dz = file.getY(index)-posZ;
                     this->weights0PM.emplace_back(1.f/(dy*dy+dz*dz+eps));
                     this->planeNeighbor0PP.emplace_back(getWriteIndex(level, fileId, index));
                 }
@@ -355,12 +355,12 @@ void VTKReader::fillArrays(std::vector<real>& coordsY, std::vector<real>& coords
 
             if(!found0MP) //ST in simulation is WN in precursor
             {
-                int index = file.findNeighborMPM(posY, posZ, 0.f);
+                const int index = file.findNeighborMPM(posY, posZ, 0.f);
                 if(index!=-1)
                 {
                     found0MP = true;
-                    real dy = file.getX(index)-posY;
-                    real dz = file.getY(index)-posZ;
+                    const real dy = file.getX(index)-posY;
+                    const real dz = file.getY(index)-posZ;
                     this->weights0MP.emplace_back(1.f/(dy*dy+dz*dz+eps));
                     this->planeNeighbor0MP.emplace_back(getWriteIndex(level, fileId, index));
                 }
@@ -391,8 +391,8 @@ void VTKReader::fillArrays(std::vector<real>& coordsY, std::vector<real>& coords
 
 uint VTKReader::getWriteIndex(int level, int id, int linearIndex)
 {
-    auto it = std::find(this->writeIndices[level][id].begin(), this->writeIndices[level][id].end(), linearIndex);
-    uint idx = it-this->writeIndices[level][id].begin();
+    const auto it = std::find(this->writeIndices[level][id].begin(), this->writeIndices[level][id].end(), linearIndex);
+    const uint idx = it-this->writeIndices[level][id].begin();
     if(it==this->writeIndices[level][id].end())                         
     {
         this->writeIndices[level][id].push_back(this->nPointsRead);     //!> index on host/device array where value from file will be written to
@@ -407,17 +407,16 @@ void VTKReader::getNextData(real* data, uint numberOfNodes, real time)
 {
     // for(size_t level=0; level<this->fileCollection->files.size(); level++)
     // {
-        uint level = this->readLevel;
+        const uint level = this->readLevel;
         for(size_t id=0; id<this->fileCollection->files[level].size(); id++)
         {
             size_t numberOfFiles = this->nFile[level][id];
 
-
             if(!this->fileCollection->files[level][id][numberOfFiles].inZBounds(time))
             {
                 numberOfFiles++;
 
-                VF_LOG_INFO("PrecursorBC on level {}: switching to file no. {}\n", level, numberOfFiles);
+                VF_LOG_INFO("PrecursorBC on level {}: switching to file no. {}", level, numberOfFiles);
                 if(numberOfFiles == this->fileCollection->files[level][id].size())
                     throw std::runtime_error("Not enough Precursor Files to read");
 
@@ -433,10 +432,9 @@ void VTKReader::getNextData(real* data, uint numberOfNodes, real time)
                 }
             }
         
-
             VTKFile* file = &this->fileCollection->files[level][id][numberOfFiles];
 
-            int off = file->getClosestIdxZ(time)*file->getNumberOfPointsInXYPlane();
+            const int off = file->getClosestIdxZ(time)*file->getNumberOfPointsInXYPlane();
             file->getData(data, numberOfNodes, this->readIndices[level][id], this->writeIndices[level][id], off, this->writingOffset);
             this->nFile[level][id] = numberOfFiles;
         }
diff --git a/src/gpu/GridGenerator/TransientBCSetter/TransientBCSetter.h b/src/gpu/GridGenerator/TransientBCSetter/TransientBCSetter.h
index bdf29745a0a60473d0454c33dcb10a193ca10780..5b9ea91a831da4d9bf189418e0e3eaaf8abd7357 100644
--- a/src/gpu/GridGenerator/TransientBCSetter/TransientBCSetter.h
+++ b/src/gpu/GridGenerator/TransientBCSetter/TransientBCSetter.h
@@ -41,7 +41,7 @@ public:
     };
 
     void getData(real* data, uint numberOfNodes, const std::vector<uint>& readIndices, const std::vector<uint>& writeIndices, uint offsetRead, uint offsetWrite);
-    bool markNANs(std::vector<uint> readIndices);
+    bool markNANs(const std::vector<uint>& readIndices) const;
     bool inBoundingBox(real posX, real posY, real posZ){return  inXBounds(posX) && inYBounds(posY) && inZBounds(posZ); };
     bool inXBounds(real posX){ return posX<=maxX && posX>=minX; };
     bool inYBounds(real posY){ return posY<=maxY && posY>=minY; };
@@ -183,7 +183,7 @@ public:
     void getNextData(real* data, uint numberOfNodes, real time) override;
     void fillArrays(std::vector<real>& coordsY, std::vector<real>& coordsZ) override;
 private:  
-    uint getWriteIndex(int level, int id, int linearIdx);
+    uint getWriteIndex(int level, int id, int linearIndex);
     void initializeIndexVectors();
 
 private:
diff --git a/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.cpp b/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.cpp
index f66b216525253d26d0402c08ec89131130245ca0..6d12a19cc097c0b8e98c59a938380be97dc0b15c 100644
--- a/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.cpp
+++ b/src/gpu/GridGenerator/geometries/TriangularMesh/TriangularMeshStrategy.cpp
@@ -124,10 +124,6 @@ void RayCastingDiscretizationStrategy::doDiscretize(TriangularMesh* triangularMe
             }
         }
 
-
-
-        int counter = 0;
-
         // Test line intersection
         for (z = minZ; z <= maxZ; z += grid->getDelta())
         {
@@ -135,7 +131,6 @@ void RayCastingDiscretizationStrategy::doDiscretize(TriangularMesh* triangularMe
             {
                 for (x = minX; x <= maxX; x += grid->getDelta())
                 {
-                    counter++;
                     if (mesh->intersectLine((x - grid->getDelta()), y, z, x, y, z)) 
                         break;
                     grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
@@ -152,7 +147,6 @@ void RayCastingDiscretizationStrategy::doDiscretize(TriangularMesh* triangularMe
                 {
                     if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
                     {
-                        counter++;
                         if (mesh->intersectLine((x + grid->getDelta()), y, z, x, y, z))
                             break;
                         grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
@@ -170,7 +164,6 @@ void RayCastingDiscretizationStrategy::doDiscretize(TriangularMesh* triangularMe
                 {
                     if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
                     {
-                        counter++;
                         if (mesh->intersectLine(x, (y - grid->getDelta()), z, x, y, z)) 
                             break;
                         grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
@@ -188,7 +181,6 @@ void RayCastingDiscretizationStrategy::doDiscretize(TriangularMesh* triangularMe
                 {
                     if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
                     {
-                        counter++;
                         if (mesh->intersectLine(x, (y + grid->getDelta()), z, x, y, z))
                             break;
                         grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
@@ -206,7 +198,6 @@ void RayCastingDiscretizationStrategy::doDiscretize(TriangularMesh* triangularMe
                 {
                     if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
                     {
-                        counter++;
                         if (mesh->intersectLine(x, y, (z - grid->getDelta()), x, y, z)) 
                             break;
                         grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
@@ -224,7 +215,6 @@ void RayCastingDiscretizationStrategy::doDiscretize(TriangularMesh* triangularMe
                 {
                     if (!grid->isNode(grid->transCoordToIndex(x, y, z), OuterType))
                     {
-                        counter++;
                         if (mesh->intersectLine(x, y, (z + grid->getDelta()), x, y, z)) 
                             break;
                         grid->setNodeTo(grid->transCoordToIndex(x, y, z), OuterType);
diff --git a/src/gpu/GridGenerator/io/STLReaderWriter/STLReader.cpp b/src/gpu/GridGenerator/io/STLReaderWriter/STLReader.cpp
index d73adc73eeffce56397829c115def5bfd1d8bc59..669d7fb258759266b06a5cc214befdb3f1a6ec29 100644
--- a/src/gpu/GridGenerator/io/STLReaderWriter/STLReader.cpp
+++ b/src/gpu/GridGenerator/io/STLReaderWriter/STLReader.cpp
@@ -217,7 +217,7 @@ std::vector<Triangle> STLReader::readBinarySTL(const std::string& name)
 
     char nTri[4];
     sizef                  = fread(nTri, sizeof(char), 4, file);
-    unsigned long nTriLong = *((unsigned long*)nTri);
+    unsigned int nTriLong = *((unsigned int*)nTri);
     VF_LOG_INFO("Number of Triangles: {}" , nTriLong);
     std::vector<Triangle> triangles;
 
@@ -309,7 +309,7 @@ std::vector<Triangle> STLReader::readBinarySTL(const BoundingBox &box, const std
 
 
     sizef    = fread(nTri, sizeof(char), 4, file);
-    nTriLong = *((unsigned long*)nTri);
+    nTriLong = *((unsigned int*)nTri);
 
     VF_LOG_INFO("Number of Triangles complete geometry: {}", nTriLong);
     std::vector<Triangle> triangles;
diff --git a/src/gpu/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp b/src/gpu/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp
index eb7e6b22e160de4fedb5832be807dabf36531c9c..d3a467b0511f7f4b40d06b4c6d9b57ff09b9694a 100644
--- a/src/gpu/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp
+++ b/src/gpu/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.cpp
@@ -479,8 +479,8 @@ void SimulationFileWriter::addShortQsToVector(int index, std::vector<std::vector
         }
     }
     if (qKey > 0) {
-        real transportKey = *((real*)&qKey);
-        qNode.push_back(transportKey);
+        float transportKey = *((float*)&qKey);
+        qNode.push_back((real)transportKey);
         qNode.push_back((real)index);
         qs[GEOMQS].push_back(qNode);
     }
@@ -522,8 +522,8 @@ void SimulationFileWriter::fillRBForNode(int index, int direction, int direction
         qNode.push_back(0.5f);
     }
     if (qKey > 0) {
-        real transportKey = *((real*)&qKey);
-        qNode.push_back(transportKey);
+        float transportKey = *((float*)&qKey);
+        qNode.push_back((real)transportKey);
         qNode.push_back((real)index);
         qs[rb].push_back(qNode);
     }
diff --git a/src/gpu/VirtualFluids_GPU/Calculation/Cp.cpp b/src/gpu/VirtualFluids_GPU/Calculation/Cp.cpp
index 3956bcbee4478e7c780559ef2dc74b2bd1fc79f7..2bb2bd943f6f24a8b904f949a43e75426e497ba1 100644
--- a/src/gpu/VirtualFluids_GPU/Calculation/Cp.cpp
+++ b/src/gpu/VirtualFluids_GPU/Calculation/Cp.cpp
@@ -463,7 +463,6 @@ void printGeoFile(Parameter* para, bool fileFormat)
     }
     else //Binary:
     {
-        int tempX = 0;
         //////////////////////////////////////////////////////////////////////////
         std::ofstream ostr;
         ostr.open(fname, std::ios::out | std::ios::binary);
@@ -491,10 +490,8 @@ void printGeoFile(Parameter* para, bool fileFormat)
                 {
                     tempCoord = (para->getParH((int)lev)->coordinateX[para->getParH((int)lev)->cpTopIndex[i]] * para->getScaleLBMtoSI().at(0) + para->getTranslateLBMtoSI().at(0));
                     writeFloatToFile(tempCoord, ostr);
-                    tempX++;
                 }
             }
-            //std::cout << "tempX in geo: " << tempX << endl;
         }
         //////////////////////////////////////////////////////////////////////////
         // Y
diff --git a/src/gpu/VirtualFluids_GPU/Calculation/ForceCalculations.cpp b/src/gpu/VirtualFluids_GPU/Calculation/ForceCalculations.cpp
index f220c9a811486d14977ac9e55527c9e3e60c2478..c498721e56ff3aea1eab6258b26bfd2c4d95e33a 100644
--- a/src/gpu/VirtualFluids_GPU/Calculation/ForceCalculations.cpp
+++ b/src/gpu/VirtualFluids_GPU/Calculation/ForceCalculations.cpp
@@ -1,4 +1,4 @@
-#include "Calculation/ForceCalculations.h"
+#include "ForceCalculations.h"
 
 //////////////////////////////////////////////////////////////////////////
 #include "GPU/GPU_Interface.h"
@@ -35,18 +35,12 @@ ForceCalculations::ForceCalculations(Parameter* para)
 	isPID = true;
 }
 
-ForceCalculations::~ForceCalculations()
-{
-}
-
-
-
 void ForceCalculations::calcPIDControllerForForce(Parameter* para, CudaMemoryManager* cudaMemoryManager)
  {
 	 //////////////////////////////////////////////////////////////////////////
-	 double tempVeloX = 0.0, tempVeloY = 0.0, tempVeloZ = 0.0;
-	 double veloAverageX = 0.0; //, veloAverageY = 0.0, veloAverageZ = 0.0;
-	 double levelVeloAverageX = 0.0, levelVeloAverageY = 0.0, levelVeloAverageZ = 0.0;
+	 double tempVeloX = 0.0;
+	 double veloAverageX = 0.0;
+	 double levelVeloAverageX = 0.0;
 	 int counter = 0;
 	 //////////////////////////////////////////////////////////////////////////
 	 for (int lev = para->getCoarse(); lev <= para->getFine(); lev++)
@@ -72,21 +66,14 @@ void ForceCalculations::calcPIDControllerForForce(Parameter* para, CudaMemoryMan
 			 getLastCudaError("CalcMacSP27 execution failed");
 			 //////////////////////////////////////////////////////////////////
 			 cudaMemoryManager->cudaCopyPrint(lev);
-//			 para->cudaCopyForceVelo(i,numberOfElements);
 			 //////////////////////////////////////////////////////////////////
 			 for (size_t pos = 0; pos < numberOfElements; pos++)
 			 {
 				 tempVeloX += (double)para->getParH(lev)->velocityX[pos];
-				 tempVeloY += (double)para->getParH(lev)->velocityY[pos];
-				 tempVeloZ += (double)para->getParH(lev)->velocityZ[pos];
 			 }
 			 tempVeloX /= (double)numberOfElements;
-			 tempVeloY /= (double)numberOfElements;
-			 tempVeloZ /= (double)numberOfElements;
 			 //////////////////////////////////////////////////////////////////
 			 levelVeloAverageX += tempVeloX;
-			 levelVeloAverageY += tempVeloY;
-			 levelVeloAverageZ += tempVeloZ;
 			 //////////////////////////////////////////////////////////////////
 			 counter++;
 			 //////////////////////////////////////////////////////////////////
@@ -94,8 +81,6 @@ void ForceCalculations::calcPIDControllerForForce(Parameter* para, CudaMemoryMan
 	 }
 	 //////////////////////////////////////////////////////////////////////////
 	 veloAverageX = levelVeloAverageX / (double)counter;
-	 //veloAverageY = levelVeloAverageY / (double)counter;
-	 //veloAverageZ = levelVeloAverageZ / (double)counter;
 	 //////////////////////////////////////////////////////////////////////////
 	 if (isPID)
 	 {
diff --git a/src/gpu/VirtualFluids_GPU/Calculation/ForceCalculations.h b/src/gpu/VirtualFluids_GPU/Calculation/ForceCalculations.h
index 4506d23abd7068697a089c926d684406af789aef..867e1327d1a6e2fefaa049f9e3d8e3dd6eb19666 100644
--- a/src/gpu/VirtualFluids_GPU/Calculation/ForceCalculations.h
+++ b/src/gpu/VirtualFluids_GPU/Calculation/ForceCalculations.h
@@ -13,7 +13,6 @@ class ForceCalculations
 {
 public:
 	ForceCalculations(Parameter* para);
-	~ForceCalculations();
 	void calcPIDControllerForForce(Parameter* para, CudaMemoryManager* cudaMemoryManager);
 	void printForcing(Parameter* para);
 
@@ -34,9 +33,4 @@ private:
 	bool isPID;
 };
 
-
-//void calcVeloForce(Parameter* para);
-//void allocVeloForForcing(Parameter* para);
-//void printForcing(Parameter* para);
-
 #endif /* FORCE_CALCULATIONS_H */
diff --git a/src/gpu/VirtualFluids_GPU/Communication/CommunicationRoutineMocks.h b/src/gpu/VirtualFluids_GPU/Communication/CommunicationRoutineMocks.h
new file mode 100644
index 0000000000000000000000000000000000000000..d05e5b6a3fdb75f9073d9f376980612f040c4038
--- /dev/null
+++ b/src/gpu/VirtualFluids_GPU/Communication/CommunicationRoutineMocks.h
@@ -0,0 +1,21 @@
+#ifndef VF_GPU_COMMUNICATIONROUTINEMOCKS_H
+#define VF_GPU_COMMUNICATIONROUTINEMOCKS_H
+
+#include "CommunicationRoutine.h"
+
+namespace vf::gpu::test 
+{
+
+class CommunicationRoutineTestDouble : public vf::gpu::CommunicationRoutine
+{
+public:
+    void receive_send(uint *buffer_receive, int size_buffer_recv, int neighbor_rank_recv, uint *buffer_send,
+                              int size_buffer_send, int neighbor_rank_send) const override { } 
+    int getPID() const override { return 0; }
+};
+
+}
+
+
+
+#endif
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.cpp b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.cpp
index 3b511264e9c7edc80bbe367cac4a9b6d8725674b..9b2d1c4f5fa742b46ecd9ad3a9f8e86b499909fb 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.cpp
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.cpp
@@ -9,7 +9,7 @@
 #include <GPU/CudaMemoryManager.h>
 
 
-std::shared_ptr<GridProvider> GridProvider::makeGridGenerator(std::shared_ptr<GridBuilder> builder, std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager, vf::gpu::Communicator& communicator)
+std::shared_ptr<GridProvider> GridProvider::makeGridGenerator(std::shared_ptr<GridBuilder> builder, std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager, vf::gpu::CommunicationRoutine& communicator)
 {
     return std::shared_ptr<GridProvider>(new GridGenerator(builder, para, cudaMemoryManager, communicator));
 }
@@ -35,7 +35,7 @@ void GridProvider::setNumberOfTaggedFluidNodes(uint numberOfNodes, CollisionTemp
     para->getParD(level)->numberOfTaggedFluidNodes[tag] = numberOfNodes;
 }
 
-void GridProvider::setInitalNodeValues(uint numberOfNodes, int level) const
+void GridProvider::setInitialNodeValues(uint numberOfNodes, int level) const
 {
     for (uint pos = 1; pos <= numberOfNodes; pos++)
     {
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.h b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.h
index 007db1e0d8e27b3810aa38c089bae8069bbe5813..ee6c93a5f718a2e6907e178bf7b751fbaed824dd 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.h
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridProvider.h
@@ -11,7 +11,7 @@
 #include "gpu/GridGenerator/io/SimulationFileWriter/SimulationFileWriter.h"
 namespace vf::gpu
 {
-class Communicator;
+class CommunicationRoutine;
 }
 
 class Parameter;
@@ -21,7 +21,7 @@ class CudaMemoryManager;
 class VIRTUALFLUIDS_GPU_EXPORT GridProvider
 {
 public:
-    static std::shared_ptr<GridProvider> makeGridGenerator(std::shared_ptr<GridBuilder> builder, std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager, vf::gpu::Communicator& communicator);
+    static std::shared_ptr<GridProvider> makeGridGenerator(std::shared_ptr<GridBuilder> builder, std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager, vf::gpu::CommunicationRoutine& communicator);
     static std::shared_ptr<GridProvider> makeGridReader(FILEFORMAT format, std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager);
 
     virtual void allocArrays_CoordNeighborGeo() = 0;
@@ -48,7 +48,7 @@ public:
 protected:
     void setNumberOfNodes(uint numberOfNodes, int level) const;
     void setNumberOfTaggedFluidNodes(uint numberOfNodes, CollisionTemplate tag, int level) const;
-    virtual void setInitalNodeValues(uint numberOfNodes, int level) const;
+    virtual void setInitialNodeValues(uint numberOfNodes, int level) const;
 
     void setPressSizePerLevel(int level, int sizePerLevel) const;
     void setVelocitySizePerLevel(int level, int sizePerLevel) const;
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderFiles/GridReader.cpp b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderFiles/GridReader.cpp
index c126b2f79e02272a0bd86bfe0f76fe5efe09a5a7..000e97e9a14e51d140dfa30cb325d2a04cd83f50 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderFiles/GridReader.cpp
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderFiles/GridReader.cpp
@@ -94,7 +94,7 @@ void GridReader::allocArrays_CoordNeighborGeo()
         neighWSB->initalNeighbors(para->getParH(level)->neighborInverse, level);
         geoV.initalNeighbors(     para->getParH(level)->typeOfGridNode,          level);
         rearrangeGeometry(para.get(), level);
-		setInitalNodeValues(numberOfNodesPerLevel, level);
+		setInitialNodeValues(numberOfNodesPerLevel, level);
 
         cudaMemoryManager->cudaCopyNeighborWSB(level);
         cudaMemoryManager->cudaCopySP(level);
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
index 15bb8a43375bda7a90ef61548c1c68bafa9d1af5..e3c86317c3bf7e4ece5720ac8117e5f418b22fa4 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.cpp
@@ -4,6 +4,7 @@
 #include "Parameter/Parameter.h"
 #include "GridGenerator/grid/GridBuilder/GridBuilder.h"
 #include "GPU/CudaMemoryManager.h"
+#include "Parameter/CudaStreamManager.h"
 #include "IndexRearrangementForStreams.h"
 #include "InterpolationCellGrouper.h"
 
@@ -14,14 +15,14 @@
 #include "GridGenerator/TransientBCSetter/TransientBCSetter.h"
 
 #include "utilities/communication.h"
-#include "Communication/Communicator.h"
+#include "Communication/CommunicationRoutine.h"
 
 #include <logger/Logger.h>
 
 using namespace vf::lbm::dir;
 
 GridGenerator::GridGenerator(std::shared_ptr<GridBuilder> builder, std::shared_ptr<Parameter> para,
-                             std::shared_ptr<CudaMemoryManager> cudaMemoryManager, vf::gpu::Communicator &communicator)
+                             std::shared_ptr<CudaMemoryManager> cudaMemoryManager, vf::gpu::CommunicationRoutine &communicator)
     : mpiProcessID(communicator.getPID()), builder(builder)
 {
     this->para = para;
@@ -31,7 +32,7 @@ GridGenerator::GridGenerator(std::shared_ptr<GridBuilder> builder, std::shared_p
         std::make_unique<InterpolationCellGrouper>(para->getParHallLevels(), para->getParDallLevels(), builder);
 }
 
-GridGenerator::~GridGenerator() {}
+GridGenerator::~GridGenerator() = default;
 
 void GridGenerator::setIndexRearrangementForStreams(std::unique_ptr<IndexRearrangementForStreams> &&indexRearrangement)
 {
@@ -92,7 +93,7 @@ void GridGenerator::allocArrays_CoordNeighborGeo()
             para->getParH(level)->typeOfGridNode,
             level);
 
-        setInitalNodeValues(numberOfNodesPerLevel, level);
+        setInitialNodeValues(numberOfNodesPerLevel, level);
 
         cudaMemoryManager->cudaCopyNeighborWSB(level);
         cudaMemoryManager->cudaCopySP(level);
@@ -364,6 +365,8 @@ void GridGenerator::allocArrays_BoundaryValues()
 
             cudaMemoryManager->cudaCopyPrecursorBC(level);
             cudaMemoryManager->cudaAllocPrecursorData(level);
+            para->getParD(level)->precursorBC.streamIndex = para->getStreamManager()->registerAndLaunchStream(CudaStreamIndex::Precursor);
+            
 
             // read first timestep of precursor into next and copy to next on device
             for(auto reader : para->getParH(level)->transientBCInputFileReader)
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h
index 157eb5c37660f4de5f5d547b7bac2bbc5c749fc8..b03de24ec452e37c45280c90497e95fd782ef26c 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGenerator.h
@@ -45,6 +45,10 @@ class Parameter;
 class GridBuilder;
 class IndexRearrangementForStreams;
 class InterpolationCellGrouper;
+namespace vf::gpu
+{
+class CommunicationRoutine;
+}
 
 //! \class GridGenerator derived class of GridProvider
 //! \brief mapping the grid of grid generator to data structure for simulation
@@ -63,7 +67,7 @@ private:
     const uint mpiProcessID;
 
 public:
-    VIRTUALFLUIDS_GPU_EXPORT GridGenerator(std::shared_ptr<GridBuilder> builder, std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager, vf::gpu::Communicator& communicator);
+    VIRTUALFLUIDS_GPU_EXPORT GridGenerator(std::shared_ptr<GridBuilder> builder, std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager, vf::gpu::CommunicationRoutine& communicator);
     ~GridGenerator() override;
     //! \brief overwrites the default IndexRearrangementForStreams
     void setIndexRearrangementForStreams(std::unique_ptr<IndexRearrangementForStreams>&& indexRearrangement);
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGeneratorTest.cpp b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGeneratorTest.cpp
index 1d3fb8220c9085b07708809e05814c960d52e61d..8685ea9db2d570b1aa6773659d954ac57333e366 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGeneratorTest.cpp
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/GridGeneratorTest.cpp
@@ -1,6 +1,7 @@
 #include "GridGenerator.h"
 #include <gmock/gmock.h>
 
+#include "Communication/CommunicationRoutine.h"
 #include "Communication/MpiCommunicator.h"
 #include "DataTypes.h"
 #include "GPU/CudaMemoryManager.h"
@@ -10,6 +11,8 @@
 #include "gpu/GridGenerator/grid/GridImp.h"
 #include "gpu/GridGenerator/utilities/communication.h"
 
+#include "Communication/CommunicationRoutineMocks.h"
+
 namespace GridGeneratorTest
 {
 
@@ -69,7 +72,7 @@ class IndexRearrangementForStreamsDouble : public IndexRearrangementForStreams
 {
 public:
     IndexRearrangementForStreamsDouble(std::shared_ptr<Parameter> para, std::shared_ptr<GridBuilder> builder,
-                                       vf::gpu::Communicator &communicator)
+                                       vf::gpu::CommunicationRoutine &communicator)
         : IndexRearrangementForStreams(para, builder, communicator){};
 
     void initCommunicationArraysForCommAfterFinetoCoarseX(uint level, int indexOfProcessNeighbor,
@@ -113,7 +116,7 @@ private:
         para->setNumprocs(2);
 
         builder = std::make_shared<LevelGridBuilderStub>(nullptr);
-        vf::gpu::Communicator &communicator = vf::gpu::MpiCommunicator::getInstance();
+        vf::gpu::test::CommunicationRoutineTestDouble communicator;
 
         gridGenerator = std::make_shared<GridGenerator>(builder, para, std::make_shared<CudaMemoryManagerDouble>(para),
                                                         communicator);
diff --git a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cpp b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cpp
index 081986add72b21314d0095c7da9df047e860f0d2..a8bc58488e6ebad6b38ae894e1c9c194e64c43c8 100644
--- a/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cpp
+++ b/src/gpu/VirtualFluids_GPU/DataStructureInitializer/GridReaderGenerator/IndexRearrangementForStreamsTest.cpp
@@ -13,7 +13,8 @@
 #include "gpu/GridGenerator/grid/GridBuilder/LevelGridBuilder.h"
 #include "gpu/GridGenerator/grid/GridImp.h"
 #include "gpu/GridGenerator/utilities/communication.h"
-#include "gpu/VirtualFluids_GPU/Communication/MpiCommunicator.cpp"
+
+#include "Communication/CommunicationRoutineMocks.h"
 
 namespace indexRearrangementTests
 {
@@ -148,8 +149,10 @@ private:
         para->initProcessNeighborsAfterFtoCX(sendIndices.level);
 
         testSubject = std::make_unique<IndexRearrangementForStreams>(
-            IndexRearrangementForStreams(para, builder, vf::gpu::MpiCommunicator::getInstance()));
+            IndexRearrangementForStreams(para, builder, communicator));
     };
+
+    vf::gpu::test::CommunicationRoutineTestDouble communicator;
 };
 
 TEST_F(IndexRearrangementForStreamsTest_reorderSendIndices, reorderSendIndicesForCommAfterFtoCX)
@@ -608,8 +611,10 @@ private:
         para = testingVF::createParameterForLevel(ri.level);
 
         testSubject = std::make_unique<IndexRearrangementForStreams>(
-            IndexRearrangementForStreams(para, builder, vf::gpu::MpiCommunicator::getInstance()));
+            IndexRearrangementForStreams(para, builder, communicator));
     };
+
+    vf::gpu::test::CommunicationRoutineTestDouble communicator;
 };
 
 TEST_F(IndexRearrangementForStreamsTest_reorderRecvIndicesX, noSendIndicesForCommunicationAfterScalingFineToCoarse_receiveIndicesAreUnchanged)
diff --git a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp
index 14e090ff3f02eaec87a9f709fc0e0ac8df711189..64943d19ff54bfaa174d0728a96c517f6605d565 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp
+++ b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.cpp
@@ -1740,11 +1740,11 @@ void CudaMemoryManager::cudaCopyPrecursorBC(int lev)
 }
 void CudaMemoryManager::cudaCopyPrecursorData(int lev)
 {
-    auto prec = &parameter->getParH(lev)->precursorBC;
-    auto precStream = parameter->getStreamManager()->getStream(CudaStreamIndex::Precursor);
-    size_t memSize = prec->numberOfPrecursorNodes*sizeof(real)*prec->numberOfQuantities;
-    checkCudaErrors( cudaStreamSynchronize(precStream) );
-    checkCudaErrors( cudaMemcpyAsync(parameter->getParD(lev)->precursorBC.next, prec->next, memSize, cudaMemcpyHostToDevice, precStream) );
+    auto precurser = &parameter->getParH(lev)->precursorBC;
+    auto precurserStream = parameter->getStreamManager()->getStream(CudaStreamIndex::Precursor, precurser->streamIndex);
+    size_t memSize = precurser->numberOfPrecursorNodes*sizeof(real)*precurser->numberOfQuantities;
+    checkCudaErrors( cudaStreamSynchronize(precurserStream) );
+    checkCudaErrors( cudaMemcpyAsync(parameter->getParD(lev)->precursorBC.next, precurser->next, memSize, cudaMemcpyHostToDevice, precurserStream) );
 }
 
 
@@ -3399,14 +3399,17 @@ void CudaMemoryManager::cudaAllocProbeIndices(Probe* probe, int level)
     checkCudaErrors( cudaMalloc    ((void**) &probe->getProbeStruct(level)->pointIndicesD, tmp) );
     setMemsizeGPU(1.f*tmp, false);
 }
+
 void CudaMemoryManager::cudaCopyProbeIndicesHtoD(Probe* probe, int level)
 {
     checkCudaErrors( cudaMemcpy(probe->getProbeStruct(level)->pointIndicesD, probe->getProbeStruct(level)->pointIndicesH, sizeof(int)*probe->getProbeStruct(level)->nIndices, cudaMemcpyHostToDevice) );
 }
+
 void CudaMemoryManager::cudaCopyProbeIndicesDtoH(Probe* probe, int level)
 {
     checkCudaErrors( cudaMemcpy(probe->getProbeStruct(level)->pointIndicesH, probe->getProbeStruct(level)->pointIndicesD, sizeof(int)*probe->getProbeStruct(level)->nIndices, cudaMemcpyDeviceToHost) );
 }
+
 void CudaMemoryManager::cudaFreeProbeIndices(Probe* probe, int level)
 {
     checkCudaErrors( cudaFreeHost(probe->getProbeStruct(level)->pointIndicesH) );
@@ -3415,25 +3418,28 @@ void CudaMemoryManager::cudaFreeProbeIndices(Probe* probe, int level)
 
 void CudaMemoryManager::cudaAllocProbeQuantityArray(Probe* probe, int level)
 {
-    size_t tmp = sizeof(real)*probe->getProbeStruct(level)->nArrays*probe->getProbeStruct(level)->nPoints;
+    auto probeStruct = probe->getProbeStruct(level);
+    size_t tmp = sizeof(real)*probeStruct->nArrays*probeStruct->nPoints*probeStruct->nTimesteps;
 
-    checkCudaErrors( cudaMallocHost((void**) &probe->getProbeStruct(level)->quantitiesArrayH, tmp) );
+    checkCudaErrors( cudaMallocHost((void**) &probeStruct->quantitiesArrayH, tmp) );
     if(probe->getHasDeviceQuantityArray())
     {
-        checkCudaErrors( cudaMalloc    ((void**) &probe->getProbeStruct(level)->quantitiesArrayD, tmp) );
+        checkCudaErrors( cudaMalloc    ((void**) &probeStruct->quantitiesArrayD, tmp) );
         setMemsizeGPU(1.f*tmp, false);
     }
 }
 
 void CudaMemoryManager::cudaCopyProbeQuantityArrayHtoD(Probe* probe, int level)
 {
-    checkCudaErrors( cudaMemcpy(probe->getProbeStruct(level)->quantitiesArrayD, probe->getProbeStruct(level)->quantitiesArrayH, probe->getProbeStruct(level)->nArrays*sizeof(real)*probe->getProbeStruct(level)->nPoints, cudaMemcpyHostToDevice) );
+    auto probeStruct = probe->getProbeStruct(level);
+    size_t tmp = sizeof(real)*probeStruct->nArrays*probeStruct->nPoints*probeStruct->nTimesteps;
+    checkCudaErrors( cudaMemcpy(probeStruct->quantitiesArrayD, probeStruct->quantitiesArrayH, tmp, cudaMemcpyHostToDevice) );
 }
 void CudaMemoryManager::cudaCopyProbeQuantityArrayDtoH(Probe* probe, int level)
 {
     auto probeStruct = probe->getProbeStruct(level);
-
-    checkCudaErrors( cudaMemcpy(probeStruct->quantitiesArrayH, probeStruct->quantitiesArrayD, probeStruct->nArrays*sizeof(real)*probeStruct->nPoints, cudaMemcpyDeviceToHost) );
+    size_t tmp = sizeof(real)*probeStruct->nArrays*probeStruct->nPoints*probeStruct->nTimesteps;
+    checkCudaErrors( cudaMemcpy(probeStruct->quantitiesArrayH, probeStruct->quantitiesArrayD, tmp, cudaMemcpyDeviceToHost) );
 }
 
 void CudaMemoryManager::cudaFreeProbeQuantityArray(Probe* probe, int level)
diff --git a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h
index e2f2e8658b6ef7a9453546454dd8e1f643574e17..1d01c227e780ec564b9eb1506f1a0183769d64b9 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h
+++ b/src/gpu/VirtualFluids_GPU/GPU/CudaMemoryManager.h
@@ -14,7 +14,15 @@
 #include <helper_cuda.h>
 
 #include <curand.h>
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
+#pragma clang diagnostic ignored "-Wunused-but-set-parameter"
+#endif
 #include <curand_kernel.h>
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
 
 class Parameter;
 class PorousMedia;
diff --git a/src/gpu/VirtualFluids_GPU/GPU/GPU_Interface.h b/src/gpu/VirtualFluids_GPU/GPU/GPU_Interface.h
index 78e6bf8ecf0588eaf6e216916505ec0cbab6c215..b449bcca404b54469b52f7b383f0615632c4d06d 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/GPU_Interface.h
+++ b/src/gpu/VirtualFluids_GPU/GPU/GPU_Interface.h
@@ -10,9 +10,19 @@
 
 #include "LBM/LB.h"
 
+#include <cuda.h>
 #include <cuda_runtime.h>
 #include <curand.h>
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
+#pragma clang diagnostic ignored "-Wunused-but-set-parameter"
+#endif
 #include <curand_kernel.h>
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
 
 struct LBMSimulationParameter;
 class Parameter;
diff --git a/src/gpu/VirtualFluids_GPU/GPU/GridScaling/scaleCF_compressible.cu b/src/gpu/VirtualFluids_GPU/GPU/GridScaling/scaleCF_compressible.cu
index ec1c8207bdd38666f4222270be81b91960142e62..528bbfc7a9584b2c5dedb17098324cbeab9ee1f6 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/GridScaling/scaleCF_compressible.cu
+++ b/src/gpu/VirtualFluids_GPU/GPU/GridScaling/scaleCF_compressible.cu
@@ -36,862 +36,27 @@
 #include "LBM/GPUHelperFunctions/ChimeraTransformation.h"
 #include "LBM/GPUHelperFunctions/ScalingUtilities.h"
 
-using namespace vf::basics::constant;
-using namespace vf::lbm::dir;
-using namespace vf::gpu;
+#include <lbm/refinement/InterpolationCF.h>
+#include <lbm/refinement/Coefficients.h>
 
-//////////////////////////////////////////////////////////////////////////
-//! \brief Calculate the interpolated distributions on the fine destination nodes
-//! \details Used in scaling from coarse to fine
-//! The function is executed in the following steps:
-//!
-__device__ __inline__ void interpolateDistributions(
-    const real& x, const real& y, const real& z,
-    real& m_000, 
-    real& m_100, real& m_010, real& m_001,
-    real& m_011, real& m_101, real& m_110, real& m_200, real& m_020, real& m_002,
-    real& m_111, real& m_210, real& m_012, real& m_201, real& m_021, real& m_120, real& m_102,
-    real& m_022, real& m_202, real& m_220, real& m_211, real& m_121, real& m_112,
-    real& m_122, real& m_212, real& m_221,
-    real& m_222,
-    const real& a_000, const real& a_100, const real& a_010, const real& a_001, const real& a_200, const real& a_020, const real& a_002, const real& a_110, const real&  a_101, const real& a_011, const real& a_111,
-    const real& b_000, const real& b_100, const real& b_010, const real& b_001, const real& b_200, const real& b_020, const real& b_002, const real& b_110, const real&  b_101, const real& b_011, const real& b_111,
-    const real& c_000, const real& c_100, const real& c_010, const real& c_001, const real& c_200, const real& c_020, const real& c_002, const real& c_110, const real&  c_101, const real& c_011, const real& c_111,
-    const real& d_000, const real& d_100, const real& d_010, const real& d_001, const real& d_110, const real& d_101, const real& d_011, const real& d_111,
-    const real& LaplaceRho, const real& eps_new, const real& omegaF, 
-    const real& kxxMyyAverage, const real& kxxMzzAverage, const real& kyzAverage, const real& kxzAverage, const real& kxyAverage
-)
-{
-    real useNEQ = c1o1;//zero;//one;   //.... one = on ..... zero = off 
-
-    //////////////////////////////////////////////////////////////////////////
-    // - Reset all moments to zero
-    //
-    m_111 = c0o1;
-    m_211 = c0o1;
-    m_011 = c0o1;
-    m_121 = c0o1;
-    m_101 = c0o1;
-    m_112 = c0o1;
-    m_110 = c0o1;
-    m_221 = c0o1;
-    m_001 = c0o1;
-    m_201 = c0o1;
-    m_021 = c0o1;
-    m_212 = c0o1;
-    m_010 = c0o1;
-    m_210 = c0o1;
-    m_012 = c0o1;
-    m_122 = c0o1;
-    m_100 = c0o1;
-    m_120 = c0o1;
-    m_102 = c0o1;
-    m_222 = c0o1;
-    m_022 = c0o1;
-    m_202 = c0o1;
-    m_002 = c0o1;
-    m_220 = c0o1;
-    m_020 = c0o1;
-    m_200 = c0o1;
-    m_000 = c0o1;
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - Set macroscopic values on destination node (zeroth and first order moments)
-    //!
-    real press = d_000 + x * d_100 + y * d_010 + z * d_001 +
-                 x * y * d_110 + x * z * d_101 + y * z * d_011 + x * y * z * d_111 + c3o1 * x * x * LaplaceRho;
-    real vvx   = a_000 + x * a_100 + y * a_010 + z * a_001 +
-                 x * x * a_200 + y * y * a_020 + z * z * a_002 +
-                 x * y * a_110 + x * z * a_101 + y * z * a_011 + x * y * z * a_111;
-    real vvy   = b_000 + x * b_100 + y * b_010 + z * b_001 +
-                 x * x * b_200 + y * y * b_020 + z * z * b_002 +
-                 x * y * b_110 + x * z * b_101 + y * z * b_011 + x * y * z * b_111;
-    real vvz   = c_000 + x * c_100 + y * c_010 + z * c_001 +
-                 x * x * c_200 + y * y * c_020 + z * z * c_002 +
-                 x * y * c_110 + x * z * c_101 + y * z * c_011 + x * y * z * c_111;
-
-    m_000 = press; // m_000 is press, if drho is interpolated directly
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - Set moments (second to sixth order) on destination node
-    //!
-    // linear combinations for second order moments
-    real mxxPyyPzz = m_000;
-
-    real mxxMyy = -c2o3 * (a_100 - b_010 + kxxMyyAverage + c2o1 * a_200 * x - b_110 * x + a_110 * y
-                  -c2o1 * b_020 * y + a_101 * z - b_011 * z - b_111 * x * z + a_111 * y * z) * eps_new/ omegaF * (c1o1 + press);
-    real mxxMzz = -c2o3 * (a_100 - c_001 + kxxMzzAverage + c2o1 * a_200 * x - c_101 * x + a_110 * y
-                  -c_011 * y - c_111 * x * y + a_101 * z - c2o1 * c_002 * z + a_111 * y * z) * eps_new/ omegaF * (c1o1 + press);
-
-    m_011 = -c1o3 * (b_001 + c_010 + kyzAverage + b_101 * x + c_110 * x + b_011 * y + c2o1 * c_020 * y
-            + b_111 * x * y + c2o1 * b_002 * z + c_011 * z + c_111 * x * z) * eps_new / omegaF * (c1o1 + press);
-    m_101 = -c1o3 * (a_001 + c_100 + kxzAverage + a_101 * x + c2o1 * c_200 * x + a_011 * y + c_110 * y
-            + a_111 * x * y + c2o1 * a_002 * z + c_101 * z + c_111 * y * z) * eps_new / omegaF * (c1o1 + press);
-    m_110 = -c1o3 * (a_010 + b_100 + kxyAverage + a_110 * x + c2o1 * b_200 * x + c2o1 * a_020 * y
-            + b_110 * y + a_011 * z + b_101 * z + a_111 * x * z + b_111 * y * z) * eps_new / omegaF * (c1o1 + press);
-
-    m_200 = c1o3 * (        mxxMyy +        mxxMzz + mxxPyyPzz) * useNEQ;
-    m_020 = c1o3 * (-c2o1 * mxxMyy +        mxxMzz + mxxPyyPzz) * useNEQ;
-    m_002 = c1o3 * (        mxxMyy - c2o1 * mxxMzz + mxxPyyPzz) * useNEQ;
-
-    // linear combinations for third order moments
-    m_111 = c0o1;
-
-    real mxxyPyzz = c0o1;
-    real mxxyMyzz = c0o1;
-    real mxxzPyyz = c0o1;
-    real mxxzMyyz = c0o1;
-    real mxyyPxzz = c0o1;
-    real mxyyMxzz = c0o1;
-
-    m_210 = ( mxxyMyzz + mxxyPyzz) * c1o2;
-    m_012 = (-mxxyMyzz + mxxyPyzz) * c1o2;
-    m_201 = ( mxxzMyyz + mxxzPyyz) * c1o2;
-    m_021 = (-mxxzMyyz + mxxzPyyz) * c1o2;
-    m_120 = ( mxyyMxzz + mxyyPxzz) * c1o2;
-    m_102 = (-mxyyMxzz + mxyyPxzz) * c1o2;
-
-    // fourth order moments
-    m_022 = m_000 * c1o9;
-    m_202 = m_022;
-    m_220 = m_022;
-
-    // fifth order moments
-
-    // sixth order moment
-    m_222 = m_000 * c1o27;
-
-    real vx_sq = vvx * vvx;
-    real vy_sq = vvy * vvy;
-    real vz_sq = vvz * vvz;
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    //! - Chimera transform from central moments to well conditioned distributions as defined in Appendix J in
-    //! <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> see also Eq. (88)-(96) in <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>
-    //!
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    // X - Dir
-    backwardInverseChimeraWithK(m_000, m_100, m_200, vvx, vx_sq, c1o1, c1o1);
-    backwardChimera(            m_010, m_110, m_210, vvx, vx_sq);
-    backwardInverseChimeraWithK(m_020, m_120, m_220, vvx, vx_sq, c3o1, c1o3);
-    backwardChimera(            m_001, m_101, m_201, vvx, vx_sq);
-    backwardChimera(            m_011, m_111, m_211, vvx, vx_sq);
-    backwardChimera(            m_021, m_121, m_221, vvx, vx_sq);
-    backwardInverseChimeraWithK(m_002, m_102, m_202, vvx, vx_sq, c3o1, c1o3);
-    backwardChimera(            m_012, m_112, m_212, vvx, vx_sq);
-    backwardInverseChimeraWithK(m_022, m_122, m_222, vvx, vx_sq, c9o1, c1o9);
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    // Y - Dir
-    backwardInverseChimeraWithK(m_000, m_010, m_020, vvy, vy_sq, c6o1, c1o6);
-    backwardChimera(            m_001, m_011, m_021, vvy, vy_sq);
-    backwardInverseChimeraWithK(m_002, m_012, m_022, vvy, vy_sq, c18o1, c1o18);
-    backwardInverseChimeraWithK(m_100, m_110, m_120, vvy, vy_sq, c3o2, c2o3);
-    backwardChimera(            m_101, m_111, m_121, vvy, vy_sq);
-    backwardInverseChimeraWithK(m_102, m_112, m_122, vvy, vy_sq, c9o2, c2o9);
-    backwardInverseChimeraWithK(m_200, m_210, m_220, vvy, vy_sq, c6o1, c1o6);
-    backwardChimera(            m_201, m_211, m_221, vvy, vy_sq);
-    backwardInverseChimeraWithK(m_202, m_212, m_222, vvy, vy_sq, c18o1, c1o18);
 
-    ////////////////////////////////////////////////////////////////////////////////////
-    // Z - Dir
-    backwardInverseChimeraWithK(m_000, m_001, m_002, vvz, vz_sq, c36o1, c1o36);
-    backwardInverseChimeraWithK(m_010, m_011, m_012, vvz, vz_sq, c9o1,  c1o9);
-    backwardInverseChimeraWithK(m_020, m_021, m_022, vvz, vz_sq, c36o1, c1o36);
-    backwardInverseChimeraWithK(m_100, m_101, m_102, vvz, vz_sq, c9o1,  c1o9);
-    backwardInverseChimeraWithK(m_110, m_111, m_112, vvz, vz_sq, c9o4,  c4o9);
-    backwardInverseChimeraWithK(m_120, m_121, m_122, vvz, vz_sq, c9o1,  c1o9);
-    backwardInverseChimeraWithK(m_200, m_201, m_202, vvz, vz_sq, c36o1, c1o36);
-    backwardInverseChimeraWithK(m_210, m_211, m_212, vvz, vz_sq, c9o1,  c1o9);
-    backwardInverseChimeraWithK(m_220, m_221, m_222, vvz, vz_sq, c36o1, c1o36);
-}
-
-//////////////////////////////////////////////////////////////////////////
-//! \brief Interpolate from coarse to fine nodes
-//! \details This scaling function is designed for the Cumulant K17 Kernel chimera collision kernel.
-//!
-//! The function is executed in the following steps:
-//!
 
-// based on scaleCF_RhoSq_comp_27
-template<bool hasTurbulentViscosity> __global__ void scaleCF_compressible(
-    real* distributionsCoarse, 
+template <bool hasTurbulentViscosity> __device__ void interpolate(
+    vf::lbm::Coefficients& coefficients,
+    const unsigned int nodeIndex,
     real* distributionsFine, 
-    unsigned int* neighborXcoarse,
-    unsigned int* neighborYcoarse,
-    unsigned int* neighborZcoarse,
     unsigned int* neighborXfine,
     unsigned int* neighborYfine,
     unsigned int* neighborZfine,
-    unsigned long long numberOfLBnodesCoarse, 
-    unsigned long long numberOfLBnodesFine, 
-    bool isEvenTimestep,
-    unsigned int* indicesCoarseMMM, 
-    unsigned int* indicesFineMMM, 
-    unsigned int numberOfInterfaceNodes, 
-    real omegaCoarse, 
-    real omegaFine, 
-    real* turbulentViscosityCoarse,
-    real* turbulentViscosityFine,
-    ICellNeigh neighborCoarseToFine)
+    unsigned long long numberOfLBnodesFine,
+    unsigned int* indicesFineMMM,
+    real omegaFine,
+    real* turbulentViscosityFine)
 {
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - Get the node index coordinates from threadId_100, blockId_100, blockDim and gridDim.
-    //!
-    const unsigned nodeIndex = getNodeIndex();
-
-    //////////////////////////////////////////////////////////////////////////
-    //! - Return for non-interface node
-    if (nodeIndex >= numberOfInterfaceNodes)
-        return;
-
-    //////////////////////////////////////////////////////////////////////////
-    //! - 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 distFine, distCoarse;
-    getPointersToDistributions(distFine, distributionsFine, numberOfLBnodesFine, true);
-    getPointersToDistributions(distCoarse, distributionsCoarse, numberOfLBnodesCoarse, isEvenTimestep);
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - declare local variables for source nodes
-    //!
-    real eps_new = c1o2; // ratio of grid resolutions
-    real omegaC  = omegaCoarse;
-    real omegaF  = omegaFine;
-
-    // zeroth and first order moments at the source nodes
-    real drho_PPP, vx1_PPP, vx2_PPP, vx3_PPP;
-    real drho_MPP, vx1_MPP, vx2_MPP, vx3_MPP;
-    real drho_PMP, vx1_PMP, vx2_PMP, vx3_PMP;
-    real drho_MMP, vx1_MMP, vx2_MMP, vx3_MMP;
-    real drho_PPM, vx1_PPM, vx2_PPM, vx3_PPM;
-    real drho_MPM, vx1_MPM, vx2_MPM, vx3_MPM;
-    real drho_PMM, vx1_PMM, vx2_PMM, vx3_PMM;
-    real drho_MMM, vx1_MMM, vx2_MMM, vx3_MMM;
-
-    // second order moments at the source nodes
-    real kxyFromfcNEQ_PPP, kyzFromfcNEQ_PPP, kxzFromfcNEQ_PPP, kxxMyyFromfcNEQ_PPP, kxxMzzFromfcNEQ_PPP;
-    real kxyFromfcNEQ_MPP, kyzFromfcNEQ_MPP, kxzFromfcNEQ_MPP, kxxMyyFromfcNEQ_MPP, kxxMzzFromfcNEQ_MPP;
-    real kxyFromfcNEQ_PMP, kyzFromfcNEQ_PMP, kxzFromfcNEQ_PMP, kxxMyyFromfcNEQ_PMP, kxxMzzFromfcNEQ_PMP;
-    real kxyFromfcNEQ_MMP, kyzFromfcNEQ_MMP, kxzFromfcNEQ_MMP, kxxMyyFromfcNEQ_MMP, kxxMzzFromfcNEQ_MMP;
-    real kxyFromfcNEQ_PPM, kyzFromfcNEQ_PPM, kxzFromfcNEQ_PPM, kxxMyyFromfcNEQ_PPM, kxxMzzFromfcNEQ_PPM;
-    real kxyFromfcNEQ_MPM, kyzFromfcNEQ_MPM, kxzFromfcNEQ_MPM, kxxMyyFromfcNEQ_MPM, kxxMzzFromfcNEQ_MPM;
-    real kxyFromfcNEQ_PMM, kyzFromfcNEQ_PMM, kxzFromfcNEQ_PMM, kxxMyyFromfcNEQ_PMM, kxxMzzFromfcNEQ_PMM;
-    real kxyFromfcNEQ_MMM, kyzFromfcNEQ_MMM, kxzFromfcNEQ_MMM, kxxMyyFromfcNEQ_MMM, kxxMzzFromfcNEQ_MMM;
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - Calculate moments for each source node 
-    //!
-    ////////////////////////////////////////////////////////////////////////////////
-    // source node BSW = MMM
-    ////////////////////////////////////////////////////////////////////////////////
-    // index of the base node and its neighbors
-    unsigned int k_base_000 = indicesCoarseMMM[nodeIndex];
-    unsigned int k_base_M00 = neighborXcoarse [k_base_000];
-    unsigned int k_base_0M0 = neighborYcoarse [k_base_000];
-    unsigned int k_base_00M = neighborZcoarse [k_base_000];
-    unsigned int k_base_MM0 = neighborYcoarse [k_base_M00];
-    unsigned int k_base_M0M = neighborZcoarse [k_base_M00];
-    unsigned int k_base_0MM = neighborZcoarse [k_base_0M0];
-    unsigned int k_base_MMM = neighborZcoarse [k_base_MM0];
-    ////////////////////////////////////////////////////////////////////////////////
-    // Set neighbor indices
-    unsigned int k_000 = k_base_000;
-    unsigned int k_M00 = k_base_M00;
-    unsigned int k_0M0 = k_base_0M0;
-    unsigned int k_00M = k_base_00M;
-    unsigned int k_MM0 = k_base_MM0;
-    unsigned int k_M0M = k_base_M0M;
-    unsigned int k_0MM = k_base_0MM;
-    unsigned int k_MMM = k_base_MMM;
-
-    if(hasTurbulentViscosity) omegaC = omegaCoarse / (c1o1 + c3o1*omegaCoarse*turbulentViscosityCoarse[k_000]);
-
-    calculateMomentsOnSourceNodes( distCoarse, omegaC,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_MMM, vx1_MMM, vx2_MMM, vx3_MMM,
-        kxyFromfcNEQ_MMM, kyzFromfcNEQ_MMM, kxzFromfcNEQ_MMM, kxxMyyFromfcNEQ_MMM, kxxMzzFromfcNEQ_MMM);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node TSW = MMP
-    //////////////////////////////////////////////////////////////////////////
-    // Set neighbor indices - has to be recalculated for the new source node
-    k_000 = k_00M;
-    k_M00 = k_M0M;
-    k_0M0 = k_0MM;
-    k_00M = neighborZcoarse[k_00M];
-    k_MM0 = k_MMM;
-    k_M0M = neighborZcoarse[k_M0M];
-    k_0MM = neighborZcoarse[k_0MM];
-    k_MMM = neighborZcoarse[k_MMM];
-
-    if(hasTurbulentViscosity) omegaC = omegaCoarse / (c1o1 + c3o1*omegaCoarse*turbulentViscosityCoarse[k_000]);
-
-    calculateMomentsOnSourceNodes( distCoarse, omegaC,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_MMP, vx1_MMP, vx2_MMP, vx3_MMP,
-        kxyFromfcNEQ_MMP, kyzFromfcNEQ_MMP, kxzFromfcNEQ_MMP, kxxMyyFromfcNEQ_MMP, kxxMzzFromfcNEQ_MMP);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node TSE = PMP
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_000 = k_M00;
-    k_M00 = neighborXcoarse[k_M00];
-    k_0M0 = k_MM0;
-    k_00M = k_M0M;
-    k_MM0 = neighborXcoarse[k_MM0];
-    k_M0M = neighborXcoarse[k_M0M];
-    k_0MM = k_MMM;
-    k_MMM = neighborXcoarse[k_MMM];
-
-    if(hasTurbulentViscosity) omegaC = omegaCoarse / (c1o1 + c3o1*omegaCoarse*turbulentViscosityCoarse[k_000]);
-
-    calculateMomentsOnSourceNodes( distCoarse, omegaC,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_PMP, vx1_PMP, vx2_PMP, vx3_PMP,
-        kxyFromfcNEQ_PMP, kyzFromfcNEQ_PMP, kxzFromfcNEQ_PMP, kxxMyyFromfcNEQ_PMP, kxxMzzFromfcNEQ_PMP);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node BSE = PMM 
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_00M = k_000;
-    k_M0M = k_M00;
-    k_0MM = k_0M0;
-    k_MMM = k_MM0;
-    k_000 = k_base_M00;
-    k_M00 = neighborXcoarse[k_base_M00];
-    k_0M0 = k_base_MM0;
-    k_MM0 = neighborXcoarse[k_base_MM0];
-
-    if(hasTurbulentViscosity) omegaC = omegaCoarse / (c1o1 + c3o1*omegaCoarse*turbulentViscosityCoarse[k_000]);
-
-    calculateMomentsOnSourceNodes( distCoarse, omegaC,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_PMM, vx1_PMM, vx2_PMM, vx3_PMM,
-        kxyFromfcNEQ_PMM, kyzFromfcNEQ_PMM, kxzFromfcNEQ_PMM, kxxMyyFromfcNEQ_PMM, kxxMzzFromfcNEQ_PMM);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node BNW = MPM
-    //////////////////////////////////////////////////////////////////////////
-    // index of the base node and its neighbors --> indices of all source nodes
-    k_base_000 = k_base_0M0;
-    k_base_M00 = k_base_MM0;
-    k_base_0M0 = neighborYcoarse[k_base_0M0];
-    k_base_00M = k_base_0MM;
-    k_base_MM0 = neighborYcoarse[k_base_MM0];
-    k_base_M0M = k_base_MMM;
-    k_base_0MM = neighborYcoarse[k_base_0MM];
-    k_base_MMM = neighborYcoarse[k_base_MMM];
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_000 = k_base_000;
-    k_M00 = k_base_M00;
-    k_0M0 = k_base_0M0;
-    k_00M = k_base_00M;
-    k_MM0 = k_base_MM0;
-    k_M0M = k_base_M0M;
-    k_0MM = k_base_0MM;
-    k_MMM = k_base_MMM;
-
-    if(hasTurbulentViscosity) omegaC = omegaCoarse / (c1o1 + c3o1*omegaCoarse*turbulentViscosityCoarse[k_000]);
-
-    calculateMomentsOnSourceNodes( distCoarse, omegaC,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_MPM, vx1_MPM, vx2_MPM, vx3_MPM,
-        kxyFromfcNEQ_MPM, kyzFromfcNEQ_MPM, kxzFromfcNEQ_MPM, kxxMyyFromfcNEQ_MPM, kxxMzzFromfcNEQ_MPM);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node TNW = MPP
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_000 = k_00M;
-    k_M00 = k_M0M;
-    k_0M0 = k_0MM;
-    k_00M = neighborZcoarse[k_00M];
-    k_MM0 = k_MMM;
-    k_M0M = neighborZcoarse[k_M0M];
-    k_0MM = neighborZcoarse[k_0MM];
-    k_MMM = neighborZcoarse[k_MMM];
-
-    if(hasTurbulentViscosity) omegaC = omegaCoarse / (c1o1 + c3o1*omegaCoarse*turbulentViscosityCoarse[k_000]);
-    
-    calculateMomentsOnSourceNodes( distCoarse, omegaC,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_MPP, vx1_MPP, vx2_MPP, vx3_MPP,
-        kxyFromfcNEQ_MPP, kyzFromfcNEQ_MPP, kxzFromfcNEQ_MPP, kxxMyyFromfcNEQ_MPP, kxxMzzFromfcNEQ_MPP);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node TNE = PPP
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    // index
-    k_000 = k_M00;
-    k_M00 = neighborXcoarse[k_M00];
-    k_0M0 = k_MM0;
-    k_00M = k_M0M;
-    k_MM0 = neighborXcoarse[k_MM0];
-    k_M0M = neighborXcoarse[k_M0M];
-    k_0MM = k_MMM;
-    k_MMM = neighborXcoarse[k_MMM];
-
-    if(hasTurbulentViscosity) omegaC = omegaCoarse / (c1o1 + c3o1*omegaCoarse*turbulentViscosityCoarse[k_000]);
-
-    calculateMomentsOnSourceNodes( distCoarse, omegaC,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_PPP, vx1_PPP, vx2_PPP, vx3_PPP,
-        kxyFromfcNEQ_PPP, kyzFromfcNEQ_PPP, kxzFromfcNEQ_PPP, kxxMyyFromfcNEQ_PPP, kxxMzzFromfcNEQ_PPP);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node BNE = PPM
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_00M = k_000;
-    k_M0M = k_M00;
-    k_0MM = k_0M0;
-    k_MMM = k_MM0;
-    k_000 = k_base_M00;
-    k_M00 = neighborXcoarse[k_base_M00];
-    k_0M0 = k_base_MM0;
-    k_MM0 = neighborXcoarse[k_base_MM0];
-
-    if(hasTurbulentViscosity) omegaC = omegaCoarse / (c1o1 + c3o1*omegaCoarse*turbulentViscosityCoarse[k_000]);
-    
-    calculateMomentsOnSourceNodes( distCoarse, omegaC,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_PPM, vx1_PPM, vx2_PPM, vx3_PPM,
-        kxyFromfcNEQ_PPM, kyzFromfcNEQ_PPM, kxzFromfcNEQ_PPM, kxxMyyFromfcNEQ_PPM, kxxMzzFromfcNEQ_PPM);
-
-    //////////////////////////////////////////////////////////////////////////
-    //! - Calculate coefficients for polynomial interpolation
-    //!
-    // example: a_110: derivation in x and y direction
-    real a_000, a_100, a_010, a_001, a_200, a_020, a_002, a_110, a_101, a_011, a_111;
-    real b_000, b_100, b_010, b_001, b_200, b_020, b_002, b_110, b_101, b_011, b_111;
-    real c_000, c_100, c_010, c_001, c_200, c_020, c_002, c_110, c_101, c_011, c_111;
-    real d_000, d_100, d_010, d_001, d_110, d_101, d_011, d_111;
-
-    // a_000 = (-kxxMyyFromfcNEQ_PPM - kxxMyyFromfcNEQ_PPP + kxxMyyFromfcNEQ_MPM + kxxMyyFromfcNEQ_MPP -
-    //         kxxMyyFromfcNEQ_PMM - kxxMyyFromfcNEQ_PMP + kxxMyyFromfcNEQ_MMM + kxxMyyFromfcNEQ_MMP -
-    //         kxxMzzFromfcNEQ_PPM - kxxMzzFromfcNEQ_PPP + kxxMzzFromfcNEQ_MPM + kxxMzzFromfcNEQ_MPP -
-    //         kxxMzzFromfcNEQ_PMM - kxxMzzFromfcNEQ_PMP + kxxMzzFromfcNEQ_MMM + kxxMzzFromfcNEQ_MMP -
-    //         c2o1 * kxyFromfcNEQ_PPM - c2o1 * kxyFromfcNEQ_PPP - c2o1 * kxyFromfcNEQ_MPM - c2o1 * kxyFromfcNEQ_MPP +
-    //         c2o1 * kxyFromfcNEQ_PMM + c2o1 * kxyFromfcNEQ_PMP + c2o1 * kxyFromfcNEQ_MMM + c2o1 * kxyFromfcNEQ_MMP +
-    //         c2o1 * kxzFromfcNEQ_PPM - c2o1 * kxzFromfcNEQ_PPP + c2o1 * kxzFromfcNEQ_MPM - c2o1 * kxzFromfcNEQ_MPP +
-    //         c2o1 * kxzFromfcNEQ_PMM - c2o1 * kxzFromfcNEQ_PMP + c2o1 * kxzFromfcNEQ_MMM - c2o1 * kxzFromfcNEQ_MMP +
-    //         c8o1 * vx1_PPM + c8o1 * vx1_PPP + c8o1 * vx1_MPM + c8o1 * vx1_MPP + c8o1 * vx1_PMM + c8o1 * vx1_PMP +
-    //         c8o1 * vx1_MMM + c8o1 * vx1_MMP + c2o1 * vx2_PPM + c2o1 * vx2_PPP - c2o1 * vx2_MPM - c2o1 * vx2_MPP -
-    //         c2o1 * vx2_PMM - c2o1 * vx2_PMP + c2o1 * vx2_MMM + c2o1 * vx2_MMP - c2o1 * vx3_PPM + c2o1 * vx3_PPP +
-    //         c2o1 * vx3_MPM - c2o1 * vx3_MPP - c2o1 * vx3_PMM + c2o1 * vx3_PMP + c2o1 * vx3_MMM - c2o1 * vx3_MMP) /
-    //         c64o1;
-    a_000 =
-        c1o64 * (c2o1 * (((kxyFromfcNEQ_MMM - kxyFromfcNEQ_PPP) + (kxyFromfcNEQ_MMP - kxyFromfcNEQ_PPM)) +
-                         ((kxyFromfcNEQ_PMM - kxyFromfcNEQ_MPP) + (kxyFromfcNEQ_PMP - kxyFromfcNEQ_MPM)) +
-                         ((kxzFromfcNEQ_MMM - kxzFromfcNEQ_PPP) + (kxzFromfcNEQ_PPM - kxzFromfcNEQ_MMP)) +
-                         ((kxzFromfcNEQ_PMM - kxzFromfcNEQ_MPP) + (kxzFromfcNEQ_MPM - kxzFromfcNEQ_PMP)) +
-                         ((vx2_PPP + vx2_MMM) + (vx2_PPM + vx2_MMP)) - ((vx2_MPP + vx2_PMM) + (vx2_MPM + vx2_PMP)) +
-                         ((vx3_PPP + vx3_MMM) - (vx3_PPM + vx3_MMP)) + ((vx3_PMP + vx3_MPM) - (vx3_MPP + vx3_PMM))) +
-                 c8o1 * (((vx1_PPP + vx1_MMM) + (vx1_PPM + vx1_MMP)) + ((vx1_MPP + vx1_PMM) + (vx1_PMP + vx1_MPM))) +
-                 ((kxxMyyFromfcNEQ_MMM - kxxMyyFromfcNEQ_PPP) + (kxxMyyFromfcNEQ_MMP - kxxMyyFromfcNEQ_PPM)) +
-                 ((kxxMyyFromfcNEQ_MPP - kxxMyyFromfcNEQ_PMM) + (kxxMyyFromfcNEQ_MPM - kxxMyyFromfcNEQ_PMP)) +
-                 ((kxxMzzFromfcNEQ_MMM - kxxMzzFromfcNEQ_PPP) + (kxxMzzFromfcNEQ_MMP - kxxMzzFromfcNEQ_PPM)) +
-                 ((kxxMzzFromfcNEQ_MPP - kxxMzzFromfcNEQ_PMM) + (kxxMzzFromfcNEQ_MPM - kxxMzzFromfcNEQ_PMP)));
-
-    // b_000 = (c2o1 * kxxMyyFromfcNEQ_PPM + c2o1 * kxxMyyFromfcNEQ_PPP + c2o1 * kxxMyyFromfcNEQ_MPM +
-    //         c2o1 * kxxMyyFromfcNEQ_MPP - c2o1 * kxxMyyFromfcNEQ_PMM - c2o1 * kxxMyyFromfcNEQ_PMP -
-    //         c2o1 * kxxMyyFromfcNEQ_MMM - c2o1 * kxxMyyFromfcNEQ_MMP - kxxMzzFromfcNEQ_PPM - kxxMzzFromfcNEQ_PPP -
-    //         kxxMzzFromfcNEQ_MPM - kxxMzzFromfcNEQ_MPP + kxxMzzFromfcNEQ_PMM + kxxMzzFromfcNEQ_PMP +
-    //         kxxMzzFromfcNEQ_MMM + kxxMzzFromfcNEQ_MMP - c2o1 * kxyFromfcNEQ_PPM - c2o1 * kxyFromfcNEQ_PPP +
-    //         c2o1 * kxyFromfcNEQ_MPM + c2o1 * kxyFromfcNEQ_MPP - c2o1 * kxyFromfcNEQ_PMM - c2o1 * kxyFromfcNEQ_PMP +
-    //         c2o1 * kxyFromfcNEQ_MMM + c2o1 * kxyFromfcNEQ_MMP + c2o1 * kyzFromfcNEQ_PPM - c2o1 * kyzFromfcNEQ_PPP +
-    //         c2o1 * kyzFromfcNEQ_MPM - c2o1 * kyzFromfcNEQ_MPP + c2o1 * kyzFromfcNEQ_PMM - c2o1 * kyzFromfcNEQ_PMP +
-    //         c2o1 * kyzFromfcNEQ_MMM - c2o1 * kyzFromfcNEQ_MMP + c2o1 * vx1_PPM + c2o1 * vx1_PPP - c2o1 * vx1_MPM -
-    //         c2o1 * vx1_MPP - c2o1 * vx1_PMM - c2o1 * vx1_PMP + c2o1 * vx1_MMM + c2o1 * vx1_MMP + c8o1 * vx2_PPM +
-    //         c8o1 * vx2_PPP + c8o1 * vx2_MPM + c8o1 * vx2_MPP + c8o1 * vx2_PMM + c8o1 * vx2_PMP + c8o1 * vx2_MMM +
-    //         c8o1 * vx2_MMP - c2o1 * vx3_PPM + c2o1 * vx3_PPP - c2o1 * vx3_MPM + c2o1 * vx3_MPP + c2o1 * vx3_PMM -
-    //         c2o1 * vx3_PMP + c2o1 * vx3_MMM - c2o1 * vx3_MMP) /
-    //         c64o1;
-    b_000 =
-        c1o64 * (c2o1 * (((kxxMyyFromfcNEQ_PPP - kxxMyyFromfcNEQ_MMM) + (kxxMyyFromfcNEQ_PPM - kxxMyyFromfcNEQ_MMP)) +
-                         ((kxxMyyFromfcNEQ_MPP - kxxMyyFromfcNEQ_PMM) + (kxxMyyFromfcNEQ_MPM - kxxMyyFromfcNEQ_PMP)) +
-                         ((kxyFromfcNEQ_MMM - kxyFromfcNEQ_PPP) + (kxyFromfcNEQ_MMP - kxyFromfcNEQ_PPM)) +
-                         ((kxyFromfcNEQ_MPP - kxyFromfcNEQ_PMM) + (kxyFromfcNEQ_MPM - kxyFromfcNEQ_PMP)) +
-                         ((kyzFromfcNEQ_MMM - kyzFromfcNEQ_PPP) + (kyzFromfcNEQ_PPM - kyzFromfcNEQ_MMP)) +
-                         ((kyzFromfcNEQ_PMM - kyzFromfcNEQ_MPP) + (kyzFromfcNEQ_MPM - kyzFromfcNEQ_PMP)) +
-                         ((vx1_PPP + vx1_MMM) + (vx1_PPM + vx1_MMP)) - ((vx1_MPM + vx1_MPP) + (vx1_PMM + vx1_PMP)) +
-                         ((vx3_PPP + vx3_MMM) - (vx3_PPM + vx3_MMP)) + ((vx3_MPP + vx3_PMM) - (vx3_MPM + vx3_PMP))) +
-                 c8o1 * (((vx2_PPP + vx2_MMM) + (vx2_PPM + vx2_MMP)) + ((vx2_MPP + vx2_PMM) + (vx2_MPM + vx2_PMP))) +
-                 ((kxxMzzFromfcNEQ_MMM - kxxMzzFromfcNEQ_PPP) + (kxxMzzFromfcNEQ_MMP - kxxMzzFromfcNEQ_PPM)) +
-                 ((kxxMzzFromfcNEQ_PMM - kxxMzzFromfcNEQ_MPP) + (kxxMzzFromfcNEQ_PMP - kxxMzzFromfcNEQ_MPM)));
-
-    // c_000 = (kxxMyyFromfcNEQ_PPM - kxxMyyFromfcNEQ_PPP + kxxMyyFromfcNEQ_MPM - kxxMyyFromfcNEQ_MPP +
-    //         kxxMyyFromfcNEQ_PMM - kxxMyyFromfcNEQ_PMP + kxxMyyFromfcNEQ_MMM - kxxMyyFromfcNEQ_MMP -
-    //         c2o1 * kxxMzzFromfcNEQ_PPM + c2o1 * kxxMzzFromfcNEQ_PPP - c2o1 * kxxMzzFromfcNEQ_MPM +
-    //         c2o1 * kxxMzzFromfcNEQ_MPP - c2o1 * kxxMzzFromfcNEQ_PMM + c2o1 * kxxMzzFromfcNEQ_PMP -
-    //         c2o1 * kxxMzzFromfcNEQ_MMM + c2o1 * kxxMzzFromfcNEQ_MMP - c2o1 * kxzFromfcNEQ_PPM -
-    //         c2o1 * kxzFromfcNEQ_PPP + c2o1 * kxzFromfcNEQ_MPM + c2o1 * kxzFromfcNEQ_MPP - c2o1 * kxzFromfcNEQ_PMM -
-    //         c2o1 * kxzFromfcNEQ_PMP + c2o1 * kxzFromfcNEQ_MMM + c2o1 * kxzFromfcNEQ_MMP - c2o1 * kyzFromfcNEQ_PPM -
-    //         c2o1 * kyzFromfcNEQ_PPP - c2o1 * kyzFromfcNEQ_MPM - c2o1 * kyzFromfcNEQ_MPP + c2o1 * kyzFromfcNEQ_PMM +
-    //         c2o1 * kyzFromfcNEQ_PMP + c2o1 * kyzFromfcNEQ_MMM + c2o1 * kyzFromfcNEQ_MMP - c2o1 * vx1_PPM +
-    //         c2o1 * vx1_PPP + c2o1 * vx1_MPM - c2o1 * vx1_MPP - c2o1 * vx1_PMM + c2o1 * vx1_PMP + c2o1 * vx1_MMM -
-    //         c2o1 * vx1_MMP - c2o1 * vx2_PPM + c2o1 * vx2_PPP - c2o1 * vx2_MPM + c2o1 * vx2_MPP + c2o1 * vx2_PMM -
-    //         c2o1 * vx2_PMP + c2o1 * vx2_MMM - c2o1 * vx2_MMP + c8o1 * vx3_PPM + c8o1 * vx3_PPP + c8o1 * vx3_MPM +
-    //         c8o1 * vx3_MPP + c8o1 * vx3_PMM + c8o1 * vx3_PMP + c8o1 * vx3_MMM + c8o1 * vx3_MMP) /
-    //         c64o1;
-    c_000 =
-        c1o64 * (c2o1 * (((kxxMzzFromfcNEQ_PPP - kxxMzzFromfcNEQ_MMM) + (kxxMzzFromfcNEQ_MMP - kxxMzzFromfcNEQ_PPM)) +
-                         ((kxxMzzFromfcNEQ_MPP - kxxMzzFromfcNEQ_PMM) + (kxxMzzFromfcNEQ_PMP - kxxMzzFromfcNEQ_MPM)) +
-                         ((kxzFromfcNEQ_MMM - kxzFromfcNEQ_PPP) + (kxzFromfcNEQ_MMP - kxzFromfcNEQ_PPM)) +
-                         ((kxzFromfcNEQ_MPP - kxzFromfcNEQ_PMM) + (kxzFromfcNEQ_MPM - kxzFromfcNEQ_PMP)) +
-                         ((kyzFromfcNEQ_MMM - kyzFromfcNEQ_PPP) + (kyzFromfcNEQ_MMP - kyzFromfcNEQ_PPM)) +
-                         ((kyzFromfcNEQ_PMM - kyzFromfcNEQ_MPP) + (kyzFromfcNEQ_PMP - kyzFromfcNEQ_MPM)) +
-                         ((vx1_PPP + vx1_MMM) - (vx1_MMP + vx1_PPM)) + ((vx1_MPM + vx1_PMP) - (vx1_MPP + vx1_PMM)) +
-                         ((vx2_PPP + vx2_MMM) - (vx2_MMP + vx2_PPM)) + ((vx2_MPP + vx2_PMM) - (vx2_MPM + vx2_PMP))) +
-                 c8o1 * (((vx3_PPP + vx3_MMM) + (vx3_PPM + vx3_MMP)) + ((vx3_PMM + vx3_MPP) + (vx3_PMP + vx3_MPM))) +
-                 ((kxxMyyFromfcNEQ_MMM - kxxMyyFromfcNEQ_PPP) + (kxxMyyFromfcNEQ_PPM - kxxMyyFromfcNEQ_MMP)) +
-                 ((kxxMyyFromfcNEQ_PMM - kxxMyyFromfcNEQ_MPP) + (kxxMyyFromfcNEQ_MPM - kxxMyyFromfcNEQ_PMP)));
-
-    // a_100  = (vx1_PPM + vx1_PPP - vx1_MPM - vx1_MPP + vx1_PMM + vx1_PMP - vx1_MMM - vx1_MMP) / c4o1;
-    a_100 = c1o4 * (((vx1_PPP - vx1_MMM) + (vx1_PPM - vx1_MMP)) + ((vx1_PMM - vx1_MPP) + (vx1_PMP - vx1_MPM)));
-
-    // b_100  = (vx2_PPM + vx2_PPP - vx2_MPM - vx2_MPP + vx2_PMM + vx2_PMP - vx2_MMM - vx2_MMP) / c4o1;
-    b_100 = c1o4 * (((vx2_PPP - vx2_MMM) + (vx2_PPM - vx2_MMP)) + ((vx2_PMM - vx2_MPP) + (vx2_PMP - vx2_MPM)));
-
-    // c_100  = (vx3_PPM + vx3_PPP - vx3_MPM - vx3_MPP + vx3_PMM + vx3_PMP - vx3_MMM - vx3_MMP) / c4o1;
-    c_100 = c1o4 * (((vx3_PPP - vx3_MMM) + (vx3_PPM - vx3_MMP)) + ((vx3_PMM - vx3_MPP) + (vx3_PMP - vx3_MPM)));
-
-    // a_200 = (kxxMyyFromfcNEQ_PPM + kxxMyyFromfcNEQ_PPP - kxxMyyFromfcNEQ_MPM - kxxMyyFromfcNEQ_MPP +
-    //         kxxMyyFromfcNEQ_PMM + kxxMyyFromfcNEQ_PMP - kxxMyyFromfcNEQ_MMM - kxxMyyFromfcNEQ_MMP +
-    //         kxxMzzFromfcNEQ_PPM + kxxMzzFromfcNEQ_PPP - kxxMzzFromfcNEQ_MPM - kxxMzzFromfcNEQ_MPP +
-    //         kxxMzzFromfcNEQ_PMM + kxxMzzFromfcNEQ_PMP - kxxMzzFromfcNEQ_MMM - kxxMzzFromfcNEQ_MMP + c2o1 * vx2_PPM +
-    //         c2o1 * vx2_PPP - c2o1 * vx2_MPM - c2o1 * vx2_MPP - c2o1 * vx2_PMM - c2o1 * vx2_PMP + c2o1 * vx2_MMM +
-    //         c2o1 * vx2_MMP - c2o1 * vx3_PPM + c2o1 * vx3_PPP + c2o1 * vx3_MPM - c2o1 * vx3_MPP - c2o1 * vx3_PMM +
-    //         c2o1 * vx3_PMP + c2o1 * vx3_MMM - c2o1 * vx3_MMP) /
-    //         c16o1;
-    a_200 =
-        c1o16 * (c2o1 * (((vx2_PPP + vx2_MMM) + (vx2_PPM - vx2_MPP)) + ((vx2_MMP - vx2_PMM) - (vx2_MPM + vx2_PMP)) +
-                         ((vx3_PPP + vx3_MMM) - (vx3_PPM + vx3_MPP)) + ((vx3_MPM + vx3_PMP) - (vx3_MMP + vx3_PMM))) +
-                 ((kxxMyyFromfcNEQ_PPP - kxxMyyFromfcNEQ_MMM) + (kxxMyyFromfcNEQ_PPM - kxxMyyFromfcNEQ_MMP)) +
-                 ((kxxMyyFromfcNEQ_PMM - kxxMyyFromfcNEQ_MPP) + (kxxMyyFromfcNEQ_PMP - kxxMyyFromfcNEQ_MPM)) +
-                 ((kxxMzzFromfcNEQ_PPP - kxxMzzFromfcNEQ_MMM) + (kxxMzzFromfcNEQ_PPM - kxxMzzFromfcNEQ_MMP)) +
-                 ((kxxMzzFromfcNEQ_PMM - kxxMzzFromfcNEQ_MPP) + (kxxMzzFromfcNEQ_PMP - kxxMzzFromfcNEQ_MPM)));
-
-    // b_200 = (kxyFromfcNEQ_PPM + kxyFromfcNEQ_PPP - kxyFromfcNEQ_MPM - kxyFromfcNEQ_MPP + kxyFromfcNEQ_PMM +
-    //         kxyFromfcNEQ_PMP - kxyFromfcNEQ_MMM - kxyFromfcNEQ_MMP - c2o1 * vx1_PPM - c2o1 * vx1_PPP +
-    //         c2o1 * vx1_MPM + c2o1 * vx1_MPP + c2o1 * vx1_PMM + c2o1 * vx1_PMP - c2o1 * vx1_MMM - c2o1 * vx1_MMP) /
-    //         c8o1;
-    b_200 =
-        c1o8 * (c2o1 * (-((vx1_PPP + vx1_MMM) + (vx1_PPM + vx1_MMP)) + ((vx1_MPP + vx1_PMM) + (vx1_MPM + vx1_PMP))) +
-                ((kxyFromfcNEQ_PPP - kxyFromfcNEQ_MMM) + (kxyFromfcNEQ_PPM - kxyFromfcNEQ_MMP)) +
-                ((kxyFromfcNEQ_PMM - kxyFromfcNEQ_MPP) + (kxyFromfcNEQ_PMP - kxyFromfcNEQ_MPM)));
-
-    // c_200 = (kxzFromfcNEQ_PPM + kxzFromfcNEQ_PPP - kxzFromfcNEQ_MPM - kxzFromfcNEQ_MPP + kxzFromfcNEQ_PMM +
-    //          kxzFromfcNEQ_PMP - kxzFromfcNEQ_MMM - kxzFromfcNEQ_MMP + c2o1 * vx1_PPM - c2o1 * vx1_PPP - c2o1 *
-    //          vx1_MPM + c2o1 * vx1_MPP + c2o1 * vx1_PMM - c2o1 * vx1_PMP - c2o1 * vx1_MMM + c2o1 * vx1_MMP) /
-    //         c8o1;
-    c_200 = c1o8 * (c2o1 * (((vx1_PPM + vx1_MMP) - (vx1_PPP + vx1_MMM)) + ((vx1_MPP + vx1_PMM) - (vx1_MPM + vx1_PMP))) +
-                    ((kxzFromfcNEQ_PPP - kxzFromfcNEQ_MMM) + (kxzFromfcNEQ_PPM - kxzFromfcNEQ_MMP)) +
-                    ((kxzFromfcNEQ_PMM - kxzFromfcNEQ_MPP) + (kxzFromfcNEQ_PMP - kxzFromfcNEQ_MPM)));
-
-    // a_010 = (vx1_PPM + vx1_PPP + vx1_MPM + vx1_MPP - vx1_PMM - vx1_PMP - vx1_MMM - vx1_MMP) / c4o1;
-    a_010 = c1o4 * (((vx1_PPP - vx1_MMM) + (vx1_PPM - vx1_MMP)) + ((vx1_MPP - vx1_PMM) + (vx1_MPM - vx1_PMP)));
-
-    // b_010 = (vx2_PPM + vx2_PPP + vx2_MPM + vx2_MPP - vx2_PMM - vx2_PMP - vx2_MMM - vx2_MMP) / c4o1;
-    b_010 = c1o4 * (((vx2_PPP - vx2_MMM) + (vx2_PPM - vx2_MMP)) + ((vx2_MPP - vx2_PMM) + (vx2_MPM - vx2_PMP)));
-
-    // c_010 = (vx3_PPM + vx3_PPP + vx3_MPM + vx3_MPP - vx3_PMM - vx3_PMP - vx3_MMM - vx3_MMP) / c4o1;
-    c_010 = c1o4 * (((vx3_PPP - vx3_MMM) + (vx3_PPM - vx3_MMP)) + ((vx3_MPP - vx3_PMM) + (vx3_MPM - vx3_PMP)));
-
-    // a_020 = (kxyFromfcNEQ_PPM + kxyFromfcNEQ_PPP + kxyFromfcNEQ_MPM + kxyFromfcNEQ_MPP - kxyFromfcNEQ_PMM -
-    //         kxyFromfcNEQ_PMP - kxyFromfcNEQ_MMM - kxyFromfcNEQ_MMP - c2o1 * vx2_PPM - c2o1 * vx2_PPP +
-    //         c2o1 * vx2_MPM + c2o1 * vx2_MPP + c2o1 * vx2_PMM + c2o1 * vx2_PMP - c2o1 * vx2_MMM - c2o1 * vx2_MMP) /
-    //         c8o1;
-    a_020 =
-        c1o8 * (c2o1 * (-((vx2_PPP + vx2_MMM) + (vx2_MMP + vx2_PPM)) + ((vx2_MPP + vx2_PMM) + (vx2_MPM + vx2_PMP))) +
-                ((kxyFromfcNEQ_PPP - kxyFromfcNEQ_MMM) + (kxyFromfcNEQ_PPM - kxyFromfcNEQ_MMP)) +
-                ((kxyFromfcNEQ_MPP - kxyFromfcNEQ_PMM) + (kxyFromfcNEQ_MPM - kxyFromfcNEQ_PMP)));
-
-    // b_020 = (-c2o1 * kxxMyyFromfcNEQ_PPM - c2o1 * kxxMyyFromfcNEQ_PPP - c2o1 * kxxMyyFromfcNEQ_MPM -
-    //         c2o1 * kxxMyyFromfcNEQ_MPP + c2o1 * kxxMyyFromfcNEQ_PMM + c2o1 * kxxMyyFromfcNEQ_PMP +
-    //         c2o1 * kxxMyyFromfcNEQ_MMM + c2o1 * kxxMyyFromfcNEQ_MMP + kxxMzzFromfcNEQ_PPM + kxxMzzFromfcNEQ_PPP +
-    //         kxxMzzFromfcNEQ_MPM + kxxMzzFromfcNEQ_MPP - kxxMzzFromfcNEQ_PMM - kxxMzzFromfcNEQ_PMP -
-    //         kxxMzzFromfcNEQ_MMM - kxxMzzFromfcNEQ_MMP + c2o1 * vx1_PPM + c2o1 * vx1_PPP - c2o1 * vx1_MPM -
-    //         c2o1 * vx1_MPP - c2o1 * vx1_PMM - c2o1 * vx1_PMP + c2o1 * vx1_MMM + c2o1 * vx1_MMP - c2o1 * vx3_PPM +
-    //         c2o1 * vx3_PPP - c2o1 * vx3_MPM + c2o1 * vx3_MPP + c2o1 * vx3_PMM - c2o1 * vx3_PMP + c2o1 * vx3_MMM -
-    //         c2o1 * vx3_MMP) /
-    //         c16o1;
-    b_020 =
-        c1o16 * (c2o1 * (((kxxMyyFromfcNEQ_MMM - kxxMyyFromfcNEQ_PPP) + (kxxMyyFromfcNEQ_MMP - kxxMyyFromfcNEQ_PPM)) +
-                         ((kxxMyyFromfcNEQ_PMM - kxxMyyFromfcNEQ_MPP) + (kxxMyyFromfcNEQ_PMP - kxxMyyFromfcNEQ_MPM)) +
-                         ((vx1_PPP + vx1_MMM) + (vx1_PPM + vx1_MMP)) - ((vx1_MPP + vx1_PMM) + (vx1_PMP + vx1_MPM)) +
-                         ((vx3_PPP + vx3_MMM) - (vx3_PPM + vx3_MMP)) + ((vx3_MPP + vx3_PMM) - (vx3_MPM + vx3_PMP))) +
-                 ((kxxMzzFromfcNEQ_PPP - kxxMzzFromfcNEQ_MMM) + (kxxMzzFromfcNEQ_PPM - kxxMzzFromfcNEQ_MMP)) +
-                 ((kxxMzzFromfcNEQ_MPP - kxxMzzFromfcNEQ_PMM) + (kxxMzzFromfcNEQ_MPM - kxxMzzFromfcNEQ_PMP)));
-
-    // c_020 = (kyzFromfcNEQ_PPM + kyzFromfcNEQ_PPP + kyzFromfcNEQ_MPM + kyzFromfcNEQ_MPP - kyzFromfcNEQ_PMM -
-    //          kyzFromfcNEQ_PMP - kyzFromfcNEQ_MMM - kyzFromfcNEQ_MMP + c2o1 * vx2_PPM - c2o1 * vx2_PPP + c2o1 *
-    //          vx2_MPM - c2o1 * vx2_MPP - c2o1 * vx2_PMM + c2o1 * vx2_PMP - c2o1 * vx2_MMM + c2o1 * vx2_MMP) /
-    //         c8o1;
-    c_020 = c1o8 * (c2o1 * (((vx2_MMP + vx2_PPM) - (vx2_PPP + vx2_MMM)) + ((vx2_PMP + vx2_MPM) - (vx2_MPP + vx2_PMM))) +
-                    ((kyzFromfcNEQ_PPP - kyzFromfcNEQ_MMM) + (kyzFromfcNEQ_PPM - kyzFromfcNEQ_MMP)) +
-                    ((kyzFromfcNEQ_MPP - kyzFromfcNEQ_PMM) + (kyzFromfcNEQ_MPM - kyzFromfcNEQ_PMP)));
-
-    // a_001  = (-vx1_PPM + vx1_PPP - vx1_MPM + vx1_MPP - vx1_PMM + vx1_PMP - vx1_MMM + vx1_MMP) / c4o1;
-    a_001 = c1o4 * (((vx1_PPP - vx1_MMM) + (vx1_MMP - vx1_PPM)) + ((vx1_MPP - vx1_PMM) + (vx1_PMP - vx1_MPM)));
-
-    // b_001  = (-vx2_PPM + vx2_PPP - vx2_MPM + vx2_MPP - vx2_PMM + vx2_PMP - vx2_MMM + vx2_MMP) / c4o1;
-    b_001 = c1o4 * (((vx2_PPP - vx2_MMM) + (vx2_MMP - vx2_PPM)) + ((vx2_MPP - vx2_PMM) + (vx2_PMP - vx2_MPM)));
-
-    // c_001  = (-vx3_PPM + vx3_PPP - vx3_MPM + vx3_MPP - vx3_PMM + vx3_PMP - vx3_MMM + vx3_MMP) / c4o1;
-    c_001 = c1o4 * (((vx3_PPP - vx3_MMM) + (vx3_MMP - vx3_PPM)) + ((vx3_MPP - vx3_PMM) + (vx3_PMP - vx3_MPM)));
-
-    // a_002 = (-kxzFromfcNEQ_PPM + kxzFromfcNEQ_PPP - kxzFromfcNEQ_MPM + kxzFromfcNEQ_MPP - kxzFromfcNEQ_PMM +
-    //         kxzFromfcNEQ_PMP - kxzFromfcNEQ_MMM + kxzFromfcNEQ_MMP + c2o1 * vx3_PPM - c2o1 * vx3_PPP -
-    //         c2o1 * vx3_MPM + c2o1 * vx3_MPP + c2o1 * vx3_PMM - c2o1 * vx3_PMP - c2o1 * vx3_MMM + c2o1 * vx3_MMP) /
-    //         c8o1;
-    a_002 = c1o8 * (c2o1 * (((vx3_PPM + vx3_MMP) - (vx3_PPP + vx3_MMM)) + ((vx3_MPP + vx3_PMM) - (vx3_PMP + vx3_MPM))) +
-                    ((kxzFromfcNEQ_PPP - kxzFromfcNEQ_MMM) + (kxzFromfcNEQ_MMP - kxzFromfcNEQ_PPM)) +
-                    ((kxzFromfcNEQ_PMP - kxzFromfcNEQ_MPM) + (kxzFromfcNEQ_MPP - kxzFromfcNEQ_PMM)));
-
-    // b_002 = (-kyzFromfcNEQ_PPM + kyzFromfcNEQ_PPP - kyzFromfcNEQ_MPM + kyzFromfcNEQ_MPP - kyzFromfcNEQ_PMM +
-    //          kyzFromfcNEQ_PMP - kyzFromfcNEQ_MMM + kyzFromfcNEQ_MMP + c2o1 * vx3_PPM - c2o1 * vx3_PPP + c2o1 *
-    //          vx3_MPM - c2o1 * vx3_MPP - c2o1 * vx3_PMM + c2o1 * vx3_PMP - c2o1 * vx3_MMM + c2o1 * vx3_MMP) /
-    //         c8o1;
-    b_002 = c1o8 * (c2o1 * (((vx3_PPM + vx3_MMP) - (vx3_PPP + vx3_MMM)) + ((vx3_MPM + vx3_PMP) - (vx3_PMM + vx3_MPP))) +
-                    ((kyzFromfcNEQ_PPP - kyzFromfcNEQ_MMM) + (kyzFromfcNEQ_MMP - kyzFromfcNEQ_PPM)) +
-                    ((kyzFromfcNEQ_PMP - kyzFromfcNEQ_MPM) + (kyzFromfcNEQ_MPP - kyzFromfcNEQ_PMM)));
-
-    // c_002 = (-kxxMyyFromfcNEQ_PPM + kxxMyyFromfcNEQ_PPP - kxxMyyFromfcNEQ_MPM + kxxMyyFromfcNEQ_MPP -
-    //         kxxMyyFromfcNEQ_PMM + kxxMyyFromfcNEQ_PMP - kxxMyyFromfcNEQ_MMM + kxxMyyFromfcNEQ_MMP +
-    //         c2o1 * kxxMzzFromfcNEQ_PPM - c2o1 * kxxMzzFromfcNEQ_PPP + c2o1 * kxxMzzFromfcNEQ_MPM -
-    //         c2o1 * kxxMzzFromfcNEQ_MPP + c2o1 * kxxMzzFromfcNEQ_PMM - c2o1 * kxxMzzFromfcNEQ_PMP +
-    //         c2o1 * kxxMzzFromfcNEQ_MMM - c2o1 * kxxMzzFromfcNEQ_MMP - c2o1 * vx1_PPM + c2o1 * vx1_PPP +
-    //         c2o1 * vx1_MPM - c2o1 * vx1_MPP - c2o1 * vx1_PMM + c2o1 * vx1_PMP + c2o1 * vx1_MMM - c2o1 * vx1_MMP -
-    //         c2o1 * vx2_PPM + c2o1 * vx2_PPP - c2o1 * vx2_MPM + c2o1 * vx2_MPP + c2o1 * vx2_PMM - c2o1 * vx2_PMP +
-    //         c2o1 * vx2_MMM - c2o1 * vx2_MMP) /
-    //         c16o1;
-    c_002 =
-        c1o16 * (c2o1 * (((kxxMzzFromfcNEQ_MMM - kxxMzzFromfcNEQ_PPP) + (kxxMzzFromfcNEQ_PPM - kxxMzzFromfcNEQ_MMP)) +
-                         ((kxxMzzFromfcNEQ_MPM - kxxMzzFromfcNEQ_PMP) + (kxxMzzFromfcNEQ_PMM - kxxMzzFromfcNEQ_MPP)) +
-                         ((vx1_PPP + vx1_MMM) - (vx1_MMP + vx1_PPM)) + ((vx1_MPM + vx1_PMP) - (vx1_PMM + vx1_MPP)) +
-                         ((vx2_PPP + vx2_MMM) - (vx2_MMP + vx2_PPM)) + ((vx2_PMM + vx2_MPP) - (vx2_MPM + vx2_PMP))) +
-                 ((kxxMyyFromfcNEQ_PPP - kxxMyyFromfcNEQ_MMM) + (kxxMyyFromfcNEQ_MMP - kxxMyyFromfcNEQ_PPM)) +
-                 ((kxxMyyFromfcNEQ_PMP - kxxMyyFromfcNEQ_MPM) + (kxxMyyFromfcNEQ_MPP - kxxMyyFromfcNEQ_PMM)));
-
-    // a_110 = (vx1_PPM + vx1_PPP - vx1_MPM - vx1_MPP - vx1_PMM - vx1_PMP + vx1_MMM + vx1_MMP) / c2o1;
-    // b_110 = (vx2_PPM + vx2_PPP - vx2_MPM - vx2_MPP - vx2_PMM - vx2_PMP + vx2_MMM + vx2_MMP) / c2o1;
-    // c_110 = (vx3_PPM + vx3_PPP - vx3_MPM - vx3_MPP - vx3_PMM - vx3_PMP + vx3_MMM + vx3_MMP) / c2o1;
-    a_110 = c1o2 * (((vx1_PPP + vx1_MMM) + (vx1_MMP + vx1_PPM)) - ((vx1_MPM + vx1_PMP) + (vx1_PMM + vx1_MPP)));
-    b_110 = c1o2 * (((vx2_PPP + vx2_MMM) + (vx2_MMP + vx2_PPM)) - ((vx2_MPM + vx2_PMP) + (vx2_PMM + vx2_MPP)));
-    c_110 = c1o2 * (((vx3_PPP + vx3_MMM) + (vx3_MMP + vx3_PPM)) - ((vx3_MPM + vx3_PMP) + (vx3_PMM + vx3_MPP)));
-
-    // a_101 = (-vx1_PPM + vx1_PPP + vx1_MPM - vx1_MPP - vx1_PMM + vx1_PMP + vx1_MMM - vx1_MMP) / c2o1;
-    // b_101 = (-vx2_PPM + vx2_PPP + vx2_MPM - vx2_MPP - vx2_PMM + vx2_PMP + vx2_MMM - vx2_MMP) / c2o1;
-    // c_101 = (-vx3_PPM + vx3_PPP + vx3_MPM - vx3_MPP - vx3_PMM + vx3_PMP + vx3_MMM - vx3_MMP) / c2o1;
-    a_101 = c1o2 * (((vx1_PPP + vx1_MMM) - (vx1_MMP + vx1_PPM)) + ((vx1_MPM + vx1_PMP) - (vx1_PMM + vx1_MPP)));
-    b_101 = c1o2 * (((vx2_PPP + vx2_MMM) - (vx2_MMP + vx2_PPM)) + ((vx2_MPM + vx2_PMP) - (vx2_PMM + vx2_MPP)));
-    c_101 = c1o2 * (((vx3_PPP + vx3_MMM) - (vx3_MMP + vx3_PPM)) + ((vx3_MPM + vx3_PMP) - (vx3_PMM + vx3_MPP)));
-
-    // a_011 = (-vx1_PPM + vx1_PPP - vx1_MPM + vx1_MPP + vx1_PMM - vx1_PMP + vx1_MMM - vx1_MMP) / c2o1;
-    // b_011 = (-vx2_PPM + vx2_PPP - vx2_MPM + vx2_MPP + vx2_PMM - vx2_PMP + vx2_MMM - vx2_MMP) / c2o1;
-    // c_011 = (-vx3_PPM + vx3_PPP - vx3_MPM + vx3_MPP + vx3_PMM - vx3_PMP + vx3_MMM - vx3_MMP) / c2o1;
-    a_011 = c1o2 * (((vx1_PPP + vx1_MMM) - (vx1_MMP + vx1_PPM)) + ((vx1_PMM + vx1_MPP) - (vx1_MPM + vx1_PMP)));
-    b_011 = c1o2 * (((vx2_PPP + vx2_MMM) - (vx2_MMP + vx2_PPM)) + ((vx2_PMM + vx2_MPP) - (vx2_MPM + vx2_PMP)));
-    c_011 = c1o2 * (((vx3_PPP + vx3_MMM) - (vx3_MMP + vx3_PPM)) + ((vx3_PMM + vx3_MPP) - (vx3_MPM + vx3_PMP)));
-
-    // a_111 = -vx1_PPM + vx1_PPP + vx1_MPM - vx1_MPP + vx1_PMM - vx1_PMP - vx1_MMM + vx1_MMP;
-    // b_111 = -vx2_PPM + vx2_PPP + vx2_MPM - vx2_MPP + vx2_PMM - vx2_PMP - vx2_MMM + vx2_MMP;
-    // c_111 = -vx3_PPM + vx3_PPP + vx3_MPM - vx3_MPP + vx3_PMM - vx3_PMP - vx3_MMM + vx3_MMP;
-    a_111 = ((vx1_PPP - vx1_MMM) + (vx1_MMP - vx1_PPM)) + ((vx1_MPM - vx1_PMP) + (vx1_PMM - vx1_MPP));
-    b_111 = ((vx2_PPP - vx2_MMM) + (vx2_MMP - vx2_PPM)) + ((vx2_MPM - vx2_PMP) + (vx2_PMM - vx2_MPP));
-    c_111 = ((vx3_PPP - vx3_MMM) + (vx3_MMP - vx3_PPM)) + ((vx3_MPM - vx3_PMP) + (vx3_PMM - vx3_MPP));
-
-    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-    real kxyAverage    = c0o1;
-    real kyzAverage    = c0o1;
-    real kxzAverage    = c0o1;
-    real kxxMyyAverage = c0o1;
-    real kxxMzzAverage = c0o1;
-
-    // real kxyAverage    = (kxyFromfcNEQ_MMM+
-    //                       kxyFromfcNEQ_MMP+
-    //                       kxyFromfcNEQ_PMP+
-    //                       kxyFromfcNEQ_PMM+
-    //                       kxyFromfcNEQ_MPM+
-    //                       kxyFromfcNEQ_MPP+
-    //                       kxyFromfcNEQ_PPP+
-    //                       kxyFromfcNEQ_PPM) * c1o8 - (a_010 + b_100);
-    // real kyzAverage    = (kyzFromfcNEQ_MMM+
-    //                       kyzFromfcNEQ_MMP+
-    //                       kyzFromfcNEQ_PMP+
-    //                       kyzFromfcNEQ_PMM+
-    //                       kyzFromfcNEQ_MPM+
-    //                       kyzFromfcNEQ_MPP+
-    //                       kyzFromfcNEQ_PPP+
-    //                       kyzFromfcNEQ_PPM) * c1o8 - (b_001 + c_010);
-    // real kxzAverage    = (kxzFromfcNEQ_MMM+
-    //                       kxzFromfcNEQ_MMP+
-    //                       kxzFromfcNEQ_PMP+
-    //                       kxzFromfcNEQ_PMM+
-    //                       kxzFromfcNEQ_MPM+
-    //                       kxzFromfcNEQ_MPP+
-    //                       kxzFromfcNEQ_PPP+
-    //                       kxzFromfcNEQ_PPM) * c1o8 - (a_001 + c_100);
-    // real kxxMyyAverage = (kxxMyyFromfcNEQ_MMM+
-    //                       kxxMyyFromfcNEQ_MMP+
-    //                       kxxMyyFromfcNEQ_PMP+
-    //                       kxxMyyFromfcNEQ_PMM+
-    //                       kxxMyyFromfcNEQ_MPM+
-    //                       kxxMyyFromfcNEQ_MPP+
-    //                       kxxMyyFromfcNEQ_PPP+
-    //                       kxxMyyFromfcNEQ_PPM) * c1o8 - (a_100 - b_010);
-    // real kxxMzzAverage = (kxxMzzFromfcNEQ_MMM+
-    //                       kxxMzzFromfcNEQ_MMP+
-    //                       kxxMzzFromfcNEQ_PMP+
-    //                       kxxMzzFromfcNEQ_PMM+
-    //                       kxxMzzFromfcNEQ_MPM+
-    //                       kxxMzzFromfcNEQ_MPP+
-    //                       kxxMzzFromfcNEQ_PPP+
-    //                       kxxMzzFromfcNEQ_PPM) * c1o8 - (a_100 - c_001);
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - Set the relative position of the offset cell {-1, 0, 1}
-    //!
-    real xoff    = neighborCoarseToFine.x[nodeIndex];
-    real yoff    = neighborCoarseToFine.y[nodeIndex];
-    real zoff    = neighborCoarseToFine.z[nodeIndex];
-
-    real xoff_sq = xoff * xoff;
-    real yoff_sq = yoff * yoff;
-    real zoff_sq = zoff * zoff;
-
-    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    //drho
-    real LaplaceRho = 
-        ((xoff != c0o1) || (yoff != c0o1) || (zoff != c0o1))
-        ? c0o1
-        : -c3o1 * (a_100 * a_100 + b_010 * b_010 + c_001 * c_001) - c6o1 * (b_100 * a_010 + c_100 * a_001 + c_010 * b_001);
-    // d_000 = ( drho_PPM + drho_PPP + drho_MPM + drho_MPP + drho_PMM + drho_PMP + drho_MMM + drho_MMP) * c1o8;
-    d_000 = c1o8 * (((drho_PPP + drho_MMM) + (drho_PPM + drho_MMP)) + ((drho_PMM + drho_MPP) + (drho_PMP + drho_MPM)));
-
-    // d_100 = ( drho_PPM + drho_PPP - drho_MPM - drho_MPP + drho_PMM + drho_PMP - drho_MMM - drho_MMP) * c1o4;
-    d_100 = c1o4 * (((drho_PPP - drho_MMM) + (drho_PPM - drho_MMP)) + ((drho_PMM - drho_MPP) + (drho_PMP - drho_MPM)));
-
-    // d_010 = ( drho_PPM + drho_PPP + drho_MPM + drho_MPP - drho_PMM - drho_PMP - drho_MMM - drho_MMP) * c1o4;
-    d_010 = c1o4 * (((drho_PPP - drho_MMM) + (drho_PPM - drho_MMP)) + ((drho_MPP - drho_PMM) + (drho_MPM - drho_PMP)));
+    Distributions27 distFine;
+    vf::gpu::getPointersToDistributions(distFine, distributionsFine, numberOfLBnodesFine, true);
 
-    // d_001 = (-drho_PPM + drho_PPP - drho_MPM + drho_MPP - drho_PMM + drho_PMP - drho_MMM + drho_MMP) * c1o4;
-    d_001 = c1o4 * (((drho_PPP - drho_MMM) + (drho_MMP - drho_PPM)) + ((drho_MPP - drho_PMM) + (drho_PMP - drho_MPM)));
-
-    // d_110 = ( drho_PPM + drho_PPP - drho_MPM - drho_MPP - drho_PMM - drho_PMP + drho_MMM + drho_MMP) * c1o2;
-    d_110 = c1o2 * (((drho_PPP + drho_MMM) + (drho_PPM + drho_MMP)) - ((drho_PMM + drho_MPP) + (drho_PMP + drho_MPM)));
-
-    // d_101 = (-drho_PPM + drho_PPP + drho_MPM - drho_MPP - drho_PMM + drho_PMP + drho_MMM - drho_MMP) * c1o2;
-    d_101 = c1o2 * (((drho_PPP + drho_MMM) - (drho_PPM + drho_MMP)) + ((drho_PMP + drho_MPM) - (drho_PMM + drho_MPP)));
-
-    // d_011 = (-drho_PPM + drho_PPP - drho_MPM + drho_MPP + drho_PMM - drho_PMP + drho_MMM - drho_MMP) * c1o2;
-    d_011 = c1o2 * (((drho_PPP + drho_MMM) - (drho_PPM + drho_MMP)) + ((drho_PMM + drho_MPP) - (drho_PMP + drho_MPM)));
-
-    // d_111 =  -drho_PPM + drho_PPP + drho_MPM - drho_MPP + drho_PMM - drho_PMP - drho_MMM + drho_MMP;
-    d_111 = (((drho_PPP - drho_MMM) + (drho_MMP - drho_PPM)) + ((drho_PMM - drho_MPP) + (drho_MPM - drho_PMP)));
-
-    //////////////////////////////////////////////////////////////////////////
-    //! - Extrapolation for refinement in to the wall (polynomial coefficients)
-    //!
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    //
-    // X------X
-    // |      | x---x
-    // |   ---+-+-> |    ----> offset-vector
-    // |      | x---x 
-    // X------X
-    //
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    a_000 = a_000 + xoff * a_100 + yoff * a_010 + zoff * a_001 + xoff_sq * a_200 + yoff_sq * a_020 + zoff_sq * a_002 +
-            xoff * yoff * a_110 + xoff * zoff * a_101 + yoff * zoff * a_011;
-    a_100 = a_100 + c2o1 * xoff * a_200 + yoff * a_110 + zoff * a_101;
-    a_010 = a_010 + c2o1 * yoff * a_020 + xoff * a_110 + zoff * a_011;
-    a_001 = a_001 + c2o1 * zoff * a_002 + xoff * a_101 + yoff * a_011;
-    b_000 = b_000 + xoff * b_100 + yoff * b_010 + zoff * b_001 + xoff_sq * b_200 + yoff_sq * b_020 + zoff_sq * b_002 +
-            xoff * yoff * b_110 + xoff * zoff * b_101 + yoff * zoff * b_011;
-    b_100 = b_100 + c2o1 * xoff * b_200 + yoff * b_110 + zoff * b_101;
-    b_010 = b_010 + c2o1 * yoff * b_020 + xoff * b_110 + zoff * b_011;
-    b_001 = b_001 + c2o1 * zoff * b_002 + xoff * b_101 + yoff * b_011;
-    c_000 = c_000 + xoff * c_100 + yoff * c_010 + zoff * c_001 + xoff_sq * c_200 + yoff_sq * c_020 + zoff_sq * c_002 +
-            xoff * yoff * c_110 + xoff * zoff * c_101 + yoff * zoff * c_011;
-    c_100 = c_100 + c2o1 * xoff * c_200 + yoff * c_110 + zoff * c_101;
-    c_010 = c_010 + c2o1 * yoff * c_020 + xoff * c_110 + zoff * c_011;
-    c_001 = c_001 + c2o1 * zoff * c_002 + xoff * c_101 + yoff * c_011;
-    d_000 = d_000 + xoff * d_100 + yoff * d_010 + zoff * d_001 + 
-            xoff * yoff * d_110 + xoff * zoff * d_101 + yoff * zoff * d_011;
-    d_100 = d_100 + yoff * d_110 + zoff * d_101;
-    d_010 = d_010 + xoff * d_110 + zoff * d_011;
-    d_001 = d_001 + xoff * d_101 + yoff * d_011;
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    //! - Set all moments to zero
-    //!      
-    real m_111 = c0o1;
-    real m_211 = c0o1;
-    real m_011 = c0o1;
-    real m_121 = c0o1;
-    real m_101 = c0o1;
-    real m_112 = c0o1;
-    real m_110 = c0o1;
-    real m_221 = c0o1;
-    real m_001 = c0o1;
-    real m_201 = c0o1;
-    real m_021 = c0o1;
-    real m_212 = c0o1;
-    real m_010 = c0o1;
-    real m_210 = c0o1;
-    real m_012 = c0o1;
-    real m_122 = c0o1;
-    real m_100 = c0o1;
-    real m_120 = c0o1;
-    real m_102 = c0o1;
-    real m_222 = c0o1;
-    real m_022 = c0o1;
-    real m_202 = c0o1;
-    real m_002 = c0o1;
-    real m_220 = c0o1;
-    real m_020 = c0o1;
-    real m_200 = c0o1;
-    real m_000 = c0o1;
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    //! - Define aliases to use the same variable for the distributions (f's):
-    //!
-    real& f_000 = m_111;
-    real& f_P00 = m_211;
-    real& f_M00 = m_011;
-    real& f_0P0 = m_121;
-    real& f_0M0 = m_101;
-    real& f_00P = m_112;
-    real& f_00M = m_110;
-    real& f_PP0 = m_221;
-    real& f_MM0 = m_001;
-    real& f_PM0 = m_201;
-    real& f_MP0 = m_021;
-    real& f_P0P = m_212;
-    real& f_M0M = m_010;
-    real& f_P0M = m_210;
-    real& f_M0P = m_012;
-    real& f_0PP = m_122;
-    real& f_0MM = m_100;
-    real& f_0PM = m_120;
-    real& f_0MP = m_102;
-    real& f_PPP = m_222;
-    real& f_MPP = m_022;
-    real& f_PMP = m_202;
-    real& f_MMP = m_002;
-    real& f_PPM = m_220;
-    real& f_MPM = m_020;
-    real& f_PMM = m_200;
-    real& f_MMM = m_000;
-
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //
     // Position BSW = MMM: -0.25, -0.25, -0.25
     //
@@ -901,81 +66,37 @@ template<bool hasTurbulentViscosity> __global__ void scaleCF_compressible(
     real z = -c1o4;
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // index of the base node and its neighbors
-    k_base_000 = indicesFineMMM[nodeIndex];
-    k_base_M00 = neighborXfine [k_base_000];
-    k_base_0M0 = neighborYfine [k_base_000];
-    k_base_00M = neighborZfine [k_base_000];
-    k_base_MM0 = neighborYfine [k_base_M00];
-    k_base_M0M = neighborZfine [k_base_M00];
-    k_base_0MM = neighborZfine [k_base_0M0];
-    k_base_MMM = neighborZfine [k_base_MM0];
+    unsigned int k_base_000 = indicesFineMMM[nodeIndex];
+    unsigned int k_base_M00 = neighborXfine [k_base_000];
+    unsigned int k_base_0M0 = neighborYfine [k_base_000];
+    unsigned int k_base_00M = neighborZfine [k_base_000];
+    unsigned int k_base_MM0 = neighborYfine [k_base_M00];
+    unsigned int k_base_M0M = neighborZfine [k_base_M00];
+    unsigned int k_base_0MM = neighborZfine [k_base_0M0];
+    unsigned int k_base_MMM = neighborZfine [k_base_MM0];
     //////////////////////////////////////////////////////////////////////////
     // Set neighbor indices
-    k_000 = k_base_000;
-    k_M00 = k_base_M00;
-    k_0M0 = k_base_0M0;
-    k_00M = k_base_00M;
-    k_MM0 = k_base_MM0;
-    k_M0M = k_base_M0M;
-    k_0MM = k_base_0MM;
-    k_MMM = k_base_MMM;
+    vf::gpu::ListIndices indices;
+    indices.k_000 = k_base_000;
+    indices.k_M00 = k_base_M00;
+    indices.k_0M0 = k_base_0M0;
+    indices.k_00M = k_base_00M;
+    indices.k_MM0 = k_base_MM0;
+    indices.k_M0M = k_base_M0M;
+    indices.k_0MM = k_base_0MM;
+    indices.k_MMM = k_base_MMM;
     ////////////////////////////////////////////////////////////////////////////////
     //! - Set moments (zeroth to sixth order) on destination node
     //!
+    real omegaF  = omegaFine;
+    omegaF = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaFine, turbulentViscosityFine[indices.k_000]) : omegaFine;
 
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    interpolateDistributions(
-        x, y, z,
-        m_000, 
-        m_100, m_010, m_001,
-        m_011, m_101, m_110, m_200, m_020, m_002,
-        m_111, m_210, m_012, m_201, m_021, m_120, m_102,
-        m_022, m_202, m_220, m_211, m_121, m_112,
-        m_122, m_212, m_221,
-        m_222,
-        a_000, a_100, a_010, a_001, a_200, a_020, a_002, a_110,  a_101, a_011, a_111,
-        b_000, b_100, b_010, b_001, b_200, b_020, b_002, b_110,  b_101, b_011, b_111,
-        c_000, c_100, c_010, c_001, c_200, c_020, c_002, c_110,  c_101, c_011, c_111,
-        d_000, d_100, d_010, d_001, d_110, d_101, d_011, d_111,
-        LaplaceRho, eps_new, omegaF, 
-        kxxMyyAverage, kxxMzzAverage, kyzAverage, kxzAverage, kxyAverage
-    );
+    const real epsilon_new = c1o2; // ratio of grid resolutions
+    real f[27];
+    vf::lbm::interpolateCF(f, omegaF, epsilon_new, coefficients, x, y, z);
+
+    write(distFine, indices, f);
 
-    //////////////////////////////////////////////////////////////////////////
-    //! - Write distributions: style of reading and writing the distributions from/to
-    //! 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>
-    //!
-    (distFine.f[DIR_000])[k_000] = f_000;
-    (distFine.f[DIR_P00])[k_000] = f_P00;
-    (distFine.f[DIR_M00])[k_M00] = f_M00;
-    (distFine.f[DIR_0P0])[k_000] = f_0P0;
-    (distFine.f[DIR_0M0])[k_0M0] = f_0M0;
-    (distFine.f[DIR_00P])[k_000] = f_00P;
-    (distFine.f[DIR_00M])[k_00M] = f_00M;
-    (distFine.f[DIR_PP0])[k_000] = f_PP0;
-    (distFine.f[DIR_MM0])[k_MM0] = f_MM0;
-    (distFine.f[DIR_PM0])[k_0M0] = f_PM0;
-    (distFine.f[DIR_MP0])[k_M00] = f_MP0;
-    (distFine.f[DIR_P0P])[k_000] = f_P0P;
-    (distFine.f[DIR_M0M])[k_M0M] = f_M0M;
-    (distFine.f[DIR_P0M])[k_00M] = f_P0M;
-    (distFine.f[DIR_M0P])[k_M00] = f_M0P;
-    (distFine.f[DIR_0PP])[k_000] = f_0PP;
-    (distFine.f[DIR_0MM])[k_0MM] = f_0MM;
-    (distFine.f[DIR_0PM])[k_00M] = f_0PM;
-    (distFine.f[DIR_0MP])[k_0M0] = f_0MP;
-    (distFine.f[DIR_PPP])[k_000] = f_PPP;
-    (distFine.f[DIR_MPP])[k_M00] = f_MPP;
-    (distFine.f[DIR_PMP])[k_0M0] = f_PMP;
-    (distFine.f[DIR_MMP])[k_MM0] = f_MMP;
-    (distFine.f[DIR_PPM])[k_00M] = f_PPM;
-    (distFine.f[DIR_MPM])[k_M0M] = f_MPM;
-    (distFine.f[DIR_PMM])[k_0MM] = f_PMM;
-    (distFine.f[DIR_MMM])[k_MMM] = f_MMM;
-    //////////////////////////////////////////////////////////////////////////
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //
@@ -987,66 +108,23 @@ template<bool hasTurbulentViscosity> __global__ void scaleCF_compressible(
     z =  c1o4;
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // Set neighbor indices
-    k_000 = k_00M;
-    k_M00 = k_M0M;
-    k_0M0 = k_0MM;
-    k_00M = neighborZfine[k_00M];
-    k_MM0 = k_MMM;
-    k_M0M = neighborZfine[k_M0M];
-    k_0MM = neighborZfine[k_0MM];
-    k_MMM = neighborZfine[k_MMM];
+    indices.k_000 = indices.k_00M;
+    indices.k_M00 = indices.k_M0M;
+    indices.k_0M0 = indices.k_0MM;
+    indices.k_00M = neighborZfine[indices.k_00M];
+    indices.k_MM0 = indices.k_MMM;
+    indices.k_M0M = neighborZfine[indices.k_M0M];
+    indices.k_0MM = neighborZfine[indices.k_0MM];
+    indices.k_MMM = neighborZfine[indices.k_MMM];
 
     ////////////////////////////////////////////////////////////////////////////////
     // Set moments (zeroth to sixth orders) on destination node
 
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    interpolateDistributions(
-        x, y, z,
-        m_000, 
-        m_100, m_010, m_001,
-        m_011, m_101, m_110, m_200, m_020, m_002,
-        m_111, m_210, m_012, m_201, m_021, m_120, m_102,
-        m_022, m_202, m_220, m_211, m_121, m_112,
-        m_122, m_212, m_221,
-        m_222,
-        a_000, a_100, a_010, a_001, a_200, a_020, a_002, a_110,  a_101, a_011, a_111,
-        b_000, b_100, b_010, b_001, b_200, b_020, b_002, b_110,  b_101, b_011, b_111,
-        c_000, c_100, c_010, c_001, c_200, c_020, c_002, c_110,  c_101, c_011, c_111,
-        d_000, d_100, d_010, d_001, d_110, d_101, d_011, d_111,
-        LaplaceRho, eps_new, omegaF, 
-        kxxMyyAverage, kxxMzzAverage, kyzAverage, kxzAverage, kxyAverage
-    );
+    omegaF = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaFine, turbulentViscosityFine[indices.k_000]) : omegaFine;
 
-    //////////////////////////////////////////////////////////////////////////
-    // Write distributions
-    (distFine.f[DIR_000])[k_000] = f_000;
-    (distFine.f[DIR_P00])[k_000] = f_P00;
-    (distFine.f[DIR_M00])[k_M00] = f_M00;
-    (distFine.f[DIR_0P0])[k_000] = f_0P0;
-    (distFine.f[DIR_0M0])[k_0M0] = f_0M0;
-    (distFine.f[DIR_00P])[k_000] = f_00P;
-    (distFine.f[DIR_00M])[k_00M] = f_00M;
-    (distFine.f[DIR_PP0])[k_000] = f_PP0;
-    (distFine.f[DIR_MM0])[k_MM0] = f_MM0;
-    (distFine.f[DIR_PM0])[k_0M0] = f_PM0;
-    (distFine.f[DIR_MP0])[k_M00] = f_MP0;
-    (distFine.f[DIR_P0P])[k_000] = f_P0P;
-    (distFine.f[DIR_M0M])[k_M0M] = f_M0M;
-    (distFine.f[DIR_P0M])[k_00M] = f_P0M;
-    (distFine.f[DIR_M0P])[k_M00] = f_M0P;
-    (distFine.f[DIR_0PP])[k_000] = f_0PP;
-    (distFine.f[DIR_0MM])[k_0MM] = f_0MM;
-    (distFine.f[DIR_0PM])[k_00M] = f_0PM;
-    (distFine.f[DIR_0MP])[k_0M0] = f_0MP;
-    (distFine.f[DIR_PPP])[k_000] = f_PPP;
-    (distFine.f[DIR_MPP])[k_M00] = f_MPP;
-    (distFine.f[DIR_PMP])[k_0M0] = f_PMP;
-    (distFine.f[DIR_MMP])[k_MM0] = f_MMP;
-    (distFine.f[DIR_PPM])[k_00M] = f_PPM;
-    (distFine.f[DIR_MPM])[k_M0M] = f_MPM;
-    (distFine.f[DIR_PMM])[k_0MM] = f_PMM;
-    (distFine.f[DIR_MMM])[k_MMM] = f_MMM;
+    vf::lbm::interpolateCF(f, omegaF, epsilon_new, coefficients, x, y, z);
+
+    write(distFine, indices, f);
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //
@@ -1058,66 +136,23 @@ template<bool hasTurbulentViscosity> __global__ void scaleCF_compressible(
     z =  c1o4;
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // Set neighbor indices
-    k_000 = k_M00;
-    k_M00 = neighborXfine[k_M00];
-    k_0M0 = k_MM0;
-    k_00M = k_M0M;
-    k_MM0 = neighborXfine[k_MM0];
-    k_M0M = neighborXfine[k_M0M];
-    k_0MM = k_MMM;
-    k_MMM = neighborXfine[k_MMM];
+    indices.k_000 = indices.k_M00;
+    indices.k_M00 = neighborXfine[indices.k_M00];
+    indices.k_0M0 = indices.k_MM0;
+    indices.k_00M = indices.k_M0M;
+    indices.k_MM0 = neighborXfine[indices.k_MM0];
+    indices.k_M0M = neighborXfine[indices.k_M0M];
+    indices.k_0MM = indices.k_MMM;
+    indices.k_MMM = neighborXfine[indices.k_MMM];
 
     ////////////////////////////////////////////////////////////////////////////////
     // Set moments (zeroth to sixth orders) on destination node
 
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    interpolateDistributions(
-        x, y, z,
-        m_000, 
-        m_100, m_010, m_001,
-        m_011, m_101, m_110, m_200, m_020, m_002,
-        m_111, m_210, m_012, m_201, m_021, m_120, m_102,
-        m_022, m_202, m_220, m_211, m_121, m_112,
-        m_122, m_212, m_221,
-        m_222,
-        a_000, a_100, a_010, a_001, a_200, a_020, a_002, a_110,  a_101, a_011, a_111,
-        b_000, b_100, b_010, b_001, b_200, b_020, b_002, b_110,  b_101, b_011, b_111,
-        c_000, c_100, c_010, c_001, c_200, c_020, c_002, c_110,  c_101, c_011, c_111,
-        d_000, d_100, d_010, d_001, d_110, d_101, d_011, d_111,
-        LaplaceRho, eps_new, omegaF, 
-        kxxMyyAverage, kxxMzzAverage, kyzAverage, kxzAverage, kxyAverage
-    );
+    omegaF = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaFine, turbulentViscosityFine[indices.k_000]) : omegaFine;
 
-    //////////////////////////////////////////////////////////////////////////
-    // Write distributions
-    (distFine.f[DIR_000])[k_000] = f_000;
-    (distFine.f[DIR_P00])[k_000] = f_P00;
-    (distFine.f[DIR_M00])[k_M00] = f_M00;
-    (distFine.f[DIR_0P0])[k_000] = f_0P0;
-    (distFine.f[DIR_0M0])[k_0M0] = f_0M0;
-    (distFine.f[DIR_00P])[k_000] = f_00P;
-    (distFine.f[DIR_00M])[k_00M] = f_00M;
-    (distFine.f[DIR_PP0])[k_000] = f_PP0;
-    (distFine.f[DIR_MM0])[k_MM0] = f_MM0;
-    (distFine.f[DIR_PM0])[k_0M0] = f_PM0;
-    (distFine.f[DIR_MP0])[k_M00] = f_MP0;
-    (distFine.f[DIR_P0P])[k_000] = f_P0P;
-    (distFine.f[DIR_M0M])[k_M0M] = f_M0M;
-    (distFine.f[DIR_P0M])[k_00M] = f_P0M;
-    (distFine.f[DIR_M0P])[k_M00] = f_M0P;
-    (distFine.f[DIR_0PP])[k_000] = f_0PP;
-    (distFine.f[DIR_0MM])[k_0MM] = f_0MM;
-    (distFine.f[DIR_0PM])[k_00M] = f_0PM;
-    (distFine.f[DIR_0MP])[k_0M0] = f_0MP;
-    (distFine.f[DIR_PPP])[k_000] = f_PPP;
-    (distFine.f[DIR_MPP])[k_M00] = f_MPP;
-    (distFine.f[DIR_PMP])[k_0M0] = f_PMP;
-    (distFine.f[DIR_MMP])[k_MM0] = f_MMP;
-    (distFine.f[DIR_PPM])[k_00M] = f_PPM;
-    (distFine.f[DIR_MPM])[k_M0M] = f_MPM;
-    (distFine.f[DIR_PMM])[k_0MM] = f_PMM;
-    (distFine.f[DIR_MMM])[k_MMM] = f_MMM;
+    vf::lbm::interpolateCF(f, omegaF, epsilon_new, coefficients, x, y, z);
+
+    write(distFine, indices, f);
 
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //
@@ -1129,67 +164,23 @@ template<bool hasTurbulentViscosity> __global__ void scaleCF_compressible(
     z = -c1o4;
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // Set neighbor indices
-    k_00M = k_000;
-    k_M0M = k_M00;
-    k_0MM = k_0M0;
-    k_MMM = k_MM0;
-    k_000 = k_base_M00;
-    k_M00 = neighborXfine[k_base_M00];
-    k_0M0 = k_base_MM0;
-    k_MM0 = neighborXfine[k_base_MM0];
+    indices.k_00M = indices.k_000;
+    indices.k_M0M = indices.k_M00;
+    indices.k_0MM = indices.k_0M0;
+    indices.k_MMM = indices.k_MM0;
+    indices.k_000 = k_base_M00;
+    indices.k_M00 = neighborXfine[k_base_M00];
+    indices.k_0M0 = k_base_MM0;
+    indices.k_MM0 = neighborXfine[k_base_MM0];
 
     ////////////////////////////////////////////////////////////////////////////////
     // Set moments (zeroth to sixth orders) on destination node
 
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    interpolateDistributions(
-        x, y, z,
-        m_000, 
-        m_100, m_010, m_001,
-        m_011, m_101, m_110, m_200, m_020, m_002,
-        m_111, m_210, m_012, m_201, m_021, m_120, m_102,
-        m_022, m_202, m_220, m_211, m_121, m_112,
-        m_122, m_212, m_221,
-        m_222,
-        a_000, a_100, a_010, a_001, a_200, a_020, a_002, a_110,  a_101, a_011, a_111,
-        b_000, b_100, b_010, b_001, b_200, b_020, b_002, b_110,  b_101, b_011, b_111,
-        c_000, c_100, c_010, c_001, c_200, c_020, c_002, c_110,  c_101, c_011, c_111,
-        d_000, d_100, d_010, d_001, d_110, d_101, d_011, d_111,
-        LaplaceRho, eps_new, omegaF, 
-        kxxMyyAverage, kxxMzzAverage, kyzAverage, kxzAverage, kxyAverage
-    );
+    omegaF = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaFine, turbulentViscosityFine[indices.k_000]) : omegaFine;
 
-    //////////////////////////////////////////////////////////////////////////
-    // Write distributions
-    (distFine.f[DIR_000])[k_000] = f_000;
-    (distFine.f[DIR_P00])[k_000] = f_P00;
-    (distFine.f[DIR_M00])[k_M00] = f_M00;
-    (distFine.f[DIR_0P0])[k_000] = f_0P0;
-    (distFine.f[DIR_0M0])[k_0M0] = f_0M0;
-    (distFine.f[DIR_00P])[k_000] = f_00P;
-    (distFine.f[DIR_00M])[k_00M] = f_00M;
-    (distFine.f[DIR_PP0])[k_000] = f_PP0;
-    (distFine.f[DIR_MM0])[k_MM0] = f_MM0;
-    (distFine.f[DIR_PM0])[k_0M0] = f_PM0;
-    (distFine.f[DIR_MP0])[k_M00] = f_MP0;
-    (distFine.f[DIR_P0P])[k_000] = f_P0P;
-    (distFine.f[DIR_M0M])[k_M0M] = f_M0M;
-    (distFine.f[DIR_P0M])[k_00M] = f_P0M;
-    (distFine.f[DIR_M0P])[k_M00] = f_M0P;
-    (distFine.f[DIR_0PP])[k_000] = f_0PP;
-    (distFine.f[DIR_0MM])[k_0MM] = f_0MM;
-    (distFine.f[DIR_0PM])[k_00M] = f_0PM;
-    (distFine.f[DIR_0MP])[k_0M0] = f_0MP;
-    (distFine.f[DIR_PPP])[k_000] = f_PPP;
-    (distFine.f[DIR_MPP])[k_M00] = f_MPP;
-    (distFine.f[DIR_PMP])[k_0M0] = f_PMP;
-    (distFine.f[DIR_MMP])[k_MM0] = f_MMP;
-    (distFine.f[DIR_PPM])[k_00M] = f_PPM;
-    (distFine.f[DIR_MPM])[k_M0M] = f_MPM;
-    (distFine.f[DIR_PMM])[k_0MM] = f_PMM;
-    (distFine.f[DIR_MMM])[k_MMM] = f_MMM;
+    vf::lbm::interpolateCF(f, omegaF, epsilon_new, coefficients, x, y, z);
 
+    write(distFine, indices, f);
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //
     // Position BNW = MPM: -0.25, 0.25, -0.25
@@ -1212,67 +203,23 @@ template<bool hasTurbulentViscosity> __global__ void scaleCF_compressible(
 
     //////////////////////////////////////////////////////////////////////////
     // Set neighbor indices
-    k_000 = k_base_000;
-    k_M00 = k_base_M00;
-    k_0M0 = k_base_0M0;
-    k_00M = k_base_00M;
-    k_MM0 = k_base_MM0;
-    k_M0M = k_base_M0M;
-    k_0MM = k_base_0MM;
-    k_MMM = k_base_MMM;
+    indices.k_000 = k_base_000;
+    indices.k_M00 = k_base_M00;
+    indices.k_0M0 = k_base_0M0;
+    indices.k_00M = k_base_00M;
+    indices.k_MM0 = k_base_MM0;
+    indices.k_M0M = k_base_M0M;
+    indices.k_0MM = k_base_0MM;
+    indices.k_MMM = k_base_MMM;
 
     ////////////////////////////////////////////////////////////////////////////////
     // Set moments (zeroth to sixth orders) on destination node
 
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    interpolateDistributions(
-        x, y, z,
-        m_000, 
-        m_100, m_010, m_001,
-        m_011, m_101, m_110, m_200, m_020, m_002,
-        m_111, m_210, m_012, m_201, m_021, m_120, m_102,
-        m_022, m_202, m_220, m_211, m_121, m_112,
-        m_122, m_212, m_221,
-        m_222,
-        a_000, a_100, a_010, a_001, a_200, a_020, a_002, a_110,  a_101, a_011, a_111,
-        b_000, b_100, b_010, b_001, b_200, b_020, b_002, b_110,  b_101, b_011, b_111,
-        c_000, c_100, c_010, c_001, c_200, c_020, c_002, c_110,  c_101, c_011, c_111,
-        d_000, d_100, d_010, d_001, d_110, d_101, d_011, d_111,
-        LaplaceRho, eps_new, omegaF, 
-        kxxMyyAverage, kxxMzzAverage, kyzAverage, kxzAverage, kxyAverage
-    );
+    omegaF = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaFine, turbulentViscosityFine[indices.k_000]) : omegaFine;
 
-    //////////////////////////////////////////////////////////////////////////
-    // Write distributions
-    (distFine.f[DIR_000])[k_000] = f_000;
-    (distFine.f[DIR_P00])[k_000] = f_P00;
-    (distFine.f[DIR_M00])[k_M00] = f_M00;
-    (distFine.f[DIR_0P0])[k_000] = f_0P0;
-    (distFine.f[DIR_0M0])[k_0M0] = f_0M0;
-    (distFine.f[DIR_00P])[k_000] = f_00P;
-    (distFine.f[DIR_00M])[k_00M] = f_00M;
-    (distFine.f[DIR_PP0])[k_000] = f_PP0;
-    (distFine.f[DIR_MM0])[k_MM0] = f_MM0;
-    (distFine.f[DIR_PM0])[k_0M0] = f_PM0;
-    (distFine.f[DIR_MP0])[k_M00] = f_MP0;
-    (distFine.f[DIR_P0P])[k_000] = f_P0P;
-    (distFine.f[DIR_M0M])[k_M0M] = f_M0M;
-    (distFine.f[DIR_P0M])[k_00M] = f_P0M;
-    (distFine.f[DIR_M0P])[k_M00] = f_M0P;
-    (distFine.f[DIR_0PP])[k_000] = f_0PP;
-    (distFine.f[DIR_0MM])[k_0MM] = f_0MM;
-    (distFine.f[DIR_0PM])[k_00M] = f_0PM;
-    (distFine.f[DIR_0MP])[k_0M0] = f_0MP;
-    (distFine.f[DIR_PPP])[k_000] = f_PPP;
-    (distFine.f[DIR_MPP])[k_M00] = f_MPP;
-    (distFine.f[DIR_PMP])[k_0M0] = f_PMP;
-    (distFine.f[DIR_MMP])[k_MM0] = f_MMP;
-    (distFine.f[DIR_PPM])[k_00M] = f_PPM;
-    (distFine.f[DIR_MPM])[k_M0M] = f_MPM;
-    (distFine.f[DIR_PMM])[k_0MM] = f_PMM;
-    (distFine.f[DIR_MMM])[k_MMM] = f_MMM;
+    vf::lbm::interpolateCF(f, omegaF, epsilon_new, coefficients, x, y, z);
 
+    write(distFine, indices, f);
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //
     // Position TNW = MPP: -0.25, 0.25, 0.25
@@ -1283,67 +230,20 @@ template<bool hasTurbulentViscosity> __global__ void scaleCF_compressible(
     z =  c1o4;
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // Set neighbor indices
-    k_000 = k_00M;
-    k_M00 = k_M0M;
-    k_0M0 = k_0MM;
-    k_00M = neighborZfine[k_00M];
-    k_MM0 = k_MMM;
-    k_M0M = neighborZfine[k_M0M];
-    k_0MM = neighborZfine[k_0MM];
-    k_MMM = neighborZfine[k_MMM];
+    indices.k_000 = indices.k_00M;
+    indices.k_M00 = indices.k_M0M;
+    indices.k_0M0 = indices.k_0MM;
+    indices.k_00M = neighborZfine[indices.k_00M];
+    indices.k_MM0 = indices.k_MMM;
+    indices.k_M0M = neighborZfine[indices.k_M0M];
+    indices.k_0MM = neighborZfine[indices.k_0MM];
+    indices.k_MMM = neighborZfine[indices.k_MMM];
 
-    ////////////////////////////////////////////////////////////////////////////////
-    // Set moments (zeroth to sixth orders) on destination node
+    omegaF = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaFine, turbulentViscosityFine[indices.k_000]) : omegaFine;
 
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    interpolateDistributions(
-        x, y, z,
-        m_000, 
-        m_100, m_010, m_001,
-        m_011, m_101, m_110, m_200, m_020, m_002,
-        m_111, m_210, m_012, m_201, m_021, m_120, m_102,
-        m_022, m_202, m_220, m_211, m_121, m_112,
-        m_122, m_212, m_221,
-        m_222,
-        a_000, a_100, a_010, a_001, a_200, a_020, a_002, a_110,  a_101, a_011, a_111,
-        b_000, b_100, b_010, b_001, b_200, b_020, b_002, b_110,  b_101, b_011, b_111,
-        c_000, c_100, c_010, c_001, c_200, c_020, c_002, c_110,  c_101, c_011, c_111,
-        d_000, d_100, d_010, d_001, d_110, d_101, d_011, d_111,
-        LaplaceRho, eps_new, omegaF, 
-        kxxMyyAverage, kxxMzzAverage, kyzAverage, kxzAverage, kxyAverage
-    );
-
-    //////////////////////////////////////////////////////////////////////////
-    // Write distributions
-    (distFine.f[DIR_000])[k_000] = f_000;
-    (distFine.f[DIR_P00])[k_000] = f_P00;
-    (distFine.f[DIR_M00])[k_M00] = f_M00;
-    (distFine.f[DIR_0P0])[k_000] = f_0P0;
-    (distFine.f[DIR_0M0])[k_0M0] = f_0M0;
-    (distFine.f[DIR_00P])[k_000] = f_00P;
-    (distFine.f[DIR_00M])[k_00M] = f_00M;
-    (distFine.f[DIR_PP0])[k_000] = f_PP0;
-    (distFine.f[DIR_MM0])[k_MM0] = f_MM0;
-    (distFine.f[DIR_PM0])[k_0M0] = f_PM0;
-    (distFine.f[DIR_MP0])[k_M00] = f_MP0;
-    (distFine.f[DIR_P0P])[k_000] = f_P0P;
-    (distFine.f[DIR_M0M])[k_M0M] = f_M0M;
-    (distFine.f[DIR_P0M])[k_00M] = f_P0M;
-    (distFine.f[DIR_M0P])[k_M00] = f_M0P;
-    (distFine.f[DIR_0PP])[k_000] = f_0PP;
-    (distFine.f[DIR_0MM])[k_0MM] = f_0MM;
-    (distFine.f[DIR_0PM])[k_00M] = f_0PM;
-    (distFine.f[DIR_0MP])[k_0M0] = f_0MP;
-    (distFine.f[DIR_PPP])[k_000] = f_PPP;
-    (distFine.f[DIR_MPP])[k_M00] = f_MPP;
-    (distFine.f[DIR_PMP])[k_0M0] = f_PMP;
-    (distFine.f[DIR_MMP])[k_MM0] = f_MMP;
-    (distFine.f[DIR_PPM])[k_00M] = f_PPM;
-    (distFine.f[DIR_MPM])[k_M0M] = f_MPM;
-    (distFine.f[DIR_PMM])[k_0MM] = f_PMM;
-    (distFine.f[DIR_MMM])[k_MMM] = f_MMM;
+    vf::lbm::interpolateCF(f, omegaF, epsilon_new, coefficients, x, y, z);
 
+    write(distFine, indices, f);
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //
     // Position TNE = PPP: 0.25, 0.25, 0.25
@@ -1354,67 +254,20 @@ template<bool hasTurbulentViscosity> __global__ void scaleCF_compressible(
     z = c1o4;
     ////////////////////////////////////////////////////////////////////////////////////
     // Set neighbor indices
-    k_000 = k_M00;
-    k_M00 = neighborXfine[k_M00];
-    k_0M0 = k_MM0;
-    k_00M = k_M0M;
-    k_MM0 = neighborXfine[k_MM0];
-    k_M0M = neighborXfine[k_M0M];
-    k_0MM = k_MMM;
-    k_MMM = neighborXfine[k_MMM];
+    indices.k_000 = indices.k_M00;
+    indices.k_M00 = neighborXfine[indices.k_M00];
+    indices.k_0M0 = indices.k_MM0;
+    indices.k_00M = indices.k_M0M;
+    indices.k_MM0 = neighborXfine[indices.k_MM0];
+    indices.k_M0M = neighborXfine[indices.k_M0M];
+    indices.k_0MM = indices.k_MMM;
+    indices.k_MMM = neighborXfine[indices.k_MMM];
 
-    ////////////////////////////////////////////////////////////////////////////////
-    // Set moments (zeroth to sixth orders) on destination node
+    omegaF = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaFine, turbulentViscosityFine[indices.k_000]) : omegaFine;
 
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    interpolateDistributions(
-        x, y, z,
-        m_000, 
-        m_100, m_010, m_001,
-        m_011, m_101, m_110, m_200, m_020, m_002,
-        m_111, m_210, m_012, m_201, m_021, m_120, m_102,
-        m_022, m_202, m_220, m_211, m_121, m_112,
-        m_122, m_212, m_221,
-        m_222,
-        a_000, a_100, a_010, a_001, a_200, a_020, a_002, a_110,  a_101, a_011, a_111,
-        b_000, b_100, b_010, b_001, b_200, b_020, b_002, b_110,  b_101, b_011, b_111,
-        c_000, c_100, c_010, c_001, c_200, c_020, c_002, c_110,  c_101, c_011, c_111,
-        d_000, d_100, d_010, d_001, d_110, d_101, d_011, d_111,
-        LaplaceRho, eps_new, omegaF, 
-        kxxMyyAverage, kxxMzzAverage, kyzAverage, kxzAverage, kxyAverage
-    );
-
-    //////////////////////////////////////////////////////////////////////////
-    // Write distributions
-    (distFine.f[DIR_000])[k_000] = f_000;
-    (distFine.f[DIR_P00])[k_000] = f_P00;
-    (distFine.f[DIR_M00])[k_M00] = f_M00;
-    (distFine.f[DIR_0P0])[k_000] = f_0P0;
-    (distFine.f[DIR_0M0])[k_0M0] = f_0M0;
-    (distFine.f[DIR_00P])[k_000] = f_00P;
-    (distFine.f[DIR_00M])[k_00M] = f_00M;
-    (distFine.f[DIR_PP0])[k_000] = f_PP0;
-    (distFine.f[DIR_MM0])[k_MM0] = f_MM0;
-    (distFine.f[DIR_PM0])[k_0M0] = f_PM0;
-    (distFine.f[DIR_MP0])[k_M00] = f_MP0;
-    (distFine.f[DIR_P0P])[k_000] = f_P0P;
-    (distFine.f[DIR_M0M])[k_M0M] = f_M0M;
-    (distFine.f[DIR_P0M])[k_00M] = f_P0M;
-    (distFine.f[DIR_M0P])[k_M00] = f_M0P;
-    (distFine.f[DIR_0PP])[k_000] = f_0PP;
-    (distFine.f[DIR_0MM])[k_0MM] = f_0MM;
-    (distFine.f[DIR_0PM])[k_00M] = f_0PM;
-    (distFine.f[DIR_0MP])[k_0M0] = f_0MP;
-    (distFine.f[DIR_PPP])[k_000] = f_PPP;
-    (distFine.f[DIR_MPP])[k_M00] = f_MPP;
-    (distFine.f[DIR_PMP])[k_0M0] = f_PMP;
-    (distFine.f[DIR_MMP])[k_MM0] = f_MMP;
-    (distFine.f[DIR_PPM])[k_00M] = f_PPM;
-    (distFine.f[DIR_MPM])[k_M0M] = f_MPM;
-    (distFine.f[DIR_PMM])[k_0MM] = f_PMM;
-    (distFine.f[DIR_MMM])[k_MMM] = f_MMM;
+    vf::lbm::interpolateCF(f, omegaF, epsilon_new, coefficients, x, y, z);
 
+    write(distFine, indices, f);
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     //
     //Position BNE = PPM: 0.25, 0.25, -0.25
@@ -1425,66 +278,252 @@ template<bool hasTurbulentViscosity> __global__ void scaleCF_compressible(
     z = -c1o4;
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // Set neighbor indices
-    k_00M = k_000;
-    k_M0M = k_M00;
-    k_0MM = k_0M0;
-    k_MMM = k_MM0;
-    k_000 = k_base_M00;
-    k_M00 = neighborXfine[k_base_M00];
-    k_0M0 = k_base_MM0;
-    k_MM0 = neighborXfine[k_base_MM0];
+    indices.k_00M = indices.k_000;
+    indices.k_M0M = indices.k_M00;
+    indices.k_0MM = indices.k_0M0;
+    indices.k_MMM = indices.k_MM0;
+    indices.k_000 = k_base_M00;
+    indices.k_M00 = neighborXfine[k_base_M00];
+    indices.k_0M0 = k_base_MM0;
+    indices.k_MM0 = neighborXfine[k_base_MM0];
+
+    omegaF = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaFine, turbulentViscosityFine[indices.k_000]) : omegaFine;
+
+    vf::lbm::interpolateCF(f, omegaF, epsilon_new, coefficients, x, y, z);
+
+    write(distFine, indices, f);
+}
+
+//////////////////////////////////////////////////////////////////////////
+//! \brief Interpolate from coarse to fine nodes
+//! \details This scaling function is designed for the Cumulant K17 Kernel chimera collision kernel.
+//!
+//! The function is executed in the following steps:
+//!
+// based on scaleCF_RhoSq_comp_27
+template<bool hasTurbulentViscosity> __global__ void scaleCF_compressible(
+    real* distributionsCoarse, 
+    real* distributionsFine, 
+    unsigned int* neighborXcoarse,
+    unsigned int* neighborYcoarse,
+    unsigned int* neighborZcoarse,
+    unsigned int* neighborXfine,
+    unsigned int* neighborYfine,
+    unsigned int* neighborZfine,
+    unsigned long long numberOfLBnodesCoarse, 
+    unsigned long long numberOfLBnodesFine, 
+    bool isEvenTimestep,
+    unsigned int* indicesCoarseMMM, 
+    unsigned int* indicesFineMMM, 
+    unsigned int numberOfInterfaceNodes, 
+    real omegaCoarse, 
+    real omegaFine, 
+    real* turbulentViscosityCoarse,
+    real* turbulentViscosityFine,
+    ICellNeigh neighborCoarseToFine)
+{
+    const unsigned nodeIndex = vf::gpu::getNodeIndex();
+
+    if (nodeIndex >= numberOfInterfaceNodes)
+        return;
+
+    // 1.calculate moments
+    vf::lbm::MomentsOnSourceNodeSet momentsSet;
 
+    // - ###########################################
+    // TODO: The following part starting from here
+    //       should be exchanged by function call of calculate_moment_set<hasTurbulentViscosity>()
+    //       However, this leads to a very small deviation in the results (~10e-6).
+    real omegaC  = omegaCoarse;
+    Distributions27 distCoarse;
+    vf::gpu::getPointersToDistributions(distCoarse, distributionsCoarse, numberOfLBnodesCoarse, isEvenTimestep);
+
+    vf::gpu::ListIndices indices;
     ////////////////////////////////////////////////////////////////////////////////
-    // Set moments (zeroth to sixth orders) on destination node
+    //! - Calculate moments for each source node 
+    //!
+    ////////////////////////////////////////////////////////////////////////////////
+    // source node BSW = MMM
+    ////////////////////////////////////////////////////////////////////////////////
+    // index of the base node and its neighbors
+    unsigned int k_base_000 = indicesCoarseMMM[nodeIndex];
+    unsigned int k_base_M00 = neighborXcoarse [k_base_000];
+    unsigned int k_base_0M0 = neighborYcoarse [k_base_000];
+    unsigned int k_base_00M = neighborZcoarse [k_base_000];
+    unsigned int k_base_MM0 = neighborYcoarse [k_base_M00];
+    unsigned int k_base_M0M = neighborZcoarse [k_base_M00];
+    unsigned int k_base_0MM = neighborZcoarse [k_base_0M0];
+    unsigned int k_base_MMM = neighborZcoarse [k_base_MM0];
+    ////////////////////////////////////////////////////////////////////////////////
+    // Set neighbor indices
+    indices.k_000 = k_base_000;
+    indices.k_M00 = k_base_M00;
+    indices.k_0M0 = k_base_0M0;
+    indices.k_00M = k_base_00M;
+    indices.k_MM0 = k_base_MM0;
+    indices.k_M0M = k_base_M0M;
+    indices.k_0MM = k_base_0MM;
+    indices.k_MMM = k_base_MMM;
+
+    omegaC = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaCoarse, turbulentViscosityCoarse[indices.k_000]) : omegaCoarse;
+
+    real f_coarse[27];
+
+    read(f_coarse, distCoarse, indices);
+    momentsSet.calculateMMM(f_coarse, omegaC);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node TSW = MMP
+    //////////////////////////////////////////////////////////////////////////
+    // Set neighbor indices - has to be recalculated for the new source node
+    indices.k_000 = indices.k_00M;
+    indices.k_M00 = indices.k_M0M;
+    indices.k_0M0 = indices.k_0MM;
+    indices.k_00M = neighborZcoarse[indices.k_00M];
+    indices.k_MM0 = indices.k_MMM;
+    indices.k_M0M = neighborZcoarse[indices.k_M0M];
+    indices.k_0MM = neighborZcoarse[indices.k_0MM];
+    indices.k_MMM = neighborZcoarse[indices.k_MMM];
+
+    omegaC = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaCoarse, turbulentViscosityCoarse[indices.k_000]) : omegaCoarse;
+
+    read(f_coarse, distCoarse, indices);
+    momentsSet.calculateMMP(f_coarse, omegaC);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node TSE = PMP
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_000 = indices.k_M00;
+    indices.k_M00 = neighborXcoarse[indices.k_M00];
+    indices.k_0M0 = indices.k_MM0;
+    indices.k_00M = indices.k_M0M;
+    indices.k_MM0 = neighborXcoarse[indices.k_MM0];
+    indices.k_M0M = neighborXcoarse[indices.k_M0M];
+    indices.k_0MM = indices.k_MMM;
+    indices.k_MMM = neighborXcoarse[indices.k_MMM];
+
+    omegaC = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaCoarse, turbulentViscosityCoarse[indices.k_000]) : omegaCoarse;
+
+    read(f_coarse, distCoarse, indices);
+    momentsSet.calculatePMP(f_coarse, omegaC);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node BSE = PMM 
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_00M = indices.k_000;
+    indices.k_M0M = indices.k_M00;
+    indices.k_0MM = indices.k_0M0;
+    indices.k_MMM = indices.k_MM0;
+    indices.k_000 = k_base_M00;
+    indices.k_M00 = neighborXcoarse[k_base_M00];
+    indices.k_0M0 = k_base_MM0;
+    indices.k_MM0 = neighborXcoarse[k_base_MM0];
+
+    omegaC = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaCoarse, turbulentViscosityCoarse[indices.k_000]) : omegaCoarse;
 
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    interpolateDistributions(
-        x, y, z,
-        m_000, 
-        m_100, m_010, m_001,
-        m_011, m_101, m_110, m_200, m_020, m_002,
-        m_111, m_210, m_012, m_201, m_021, m_120, m_102,
-        m_022, m_202, m_220, m_211, m_121, m_112,
-        m_122, m_212, m_221,
-        m_222,
-        a_000, a_100, a_010, a_001, a_200, a_020, a_002, a_110,  a_101, a_011, a_111,
-        b_000, b_100, b_010, b_001, b_200, b_020, b_002, b_110,  b_101, b_011, b_111,
-        c_000, c_100, c_010, c_001, c_200, c_020, c_002, c_110,  c_101, c_011, c_111,
-        d_000, d_100, d_010, d_001, d_110, d_101, d_011, d_111,
-        LaplaceRho, eps_new, omegaF, 
-        kxxMyyAverage, kxxMzzAverage, kyzAverage, kxzAverage, kxyAverage
-    );
+    read(f_coarse, distCoarse, indices);
+    momentsSet.calculatePMM(f_coarse, omegaC);
 
     //////////////////////////////////////////////////////////////////////////
-    // Write distributions
-    (distFine.f[DIR_000])[k_000] = f_000;
-    (distFine.f[DIR_P00])[k_000] = f_P00;
-    (distFine.f[DIR_M00])[k_M00] = f_M00;
-    (distFine.f[DIR_0P0])[k_000] = f_0P0;
-    (distFine.f[DIR_0M0])[k_0M0] = f_0M0;
-    (distFine.f[DIR_00P])[k_000] = f_00P;
-    (distFine.f[DIR_00M])[k_00M] = f_00M;
-    (distFine.f[DIR_PP0])[k_000] = f_PP0;
-    (distFine.f[DIR_MM0])[k_MM0] = f_MM0;
-    (distFine.f[DIR_PM0])[k_0M0] = f_PM0;
-    (distFine.f[DIR_MP0])[k_M00] = f_MP0;
-    (distFine.f[DIR_P0P])[k_000] = f_P0P;
-    (distFine.f[DIR_M0M])[k_M0M] = f_M0M;
-    (distFine.f[DIR_P0M])[k_00M] = f_P0M;
-    (distFine.f[DIR_M0P])[k_M00] = f_M0P;
-    (distFine.f[DIR_0PP])[k_000] = f_0PP;
-    (distFine.f[DIR_0MM])[k_0MM] = f_0MM;
-    (distFine.f[DIR_0PM])[k_00M] = f_0PM;
-    (distFine.f[DIR_0MP])[k_0M0] = f_0MP;
-    (distFine.f[DIR_PPP])[k_000] = f_PPP;
-    (distFine.f[DIR_MPP])[k_M00] = f_MPP;
-    (distFine.f[DIR_PMP])[k_0M0] = f_PMP;
-    (distFine.f[DIR_MMP])[k_MM0] = f_MMP;
-    (distFine.f[DIR_PPM])[k_00M] = f_PPM;
-    (distFine.f[DIR_MPM])[k_M0M] = f_MPM;
-    (distFine.f[DIR_PMM])[k_0MM] = f_PMM;
-    (distFine.f[DIR_MMM])[k_MMM] = f_MMM;
+    // source node BNW = MPM
+    //////////////////////////////////////////////////////////////////////////
+    // index of the base node and its neighbors --> indices of all source nodes
+    k_base_000 = k_base_0M0;
+    k_base_M00 = k_base_MM0;
+    k_base_0M0 = neighborYcoarse[k_base_0M0];
+    k_base_00M = k_base_0MM;
+    k_base_MM0 = neighborYcoarse[k_base_MM0];
+    k_base_M0M = k_base_MMM;
+    k_base_0MM = neighborYcoarse[k_base_0MM];
+    k_base_MMM = neighborYcoarse[k_base_MMM];
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_000 = k_base_000;
+    indices.k_M00 = k_base_M00;
+    indices.k_0M0 = k_base_0M0;
+    indices.k_00M = k_base_00M;
+    indices.k_MM0 = k_base_MM0;
+    indices.k_M0M = k_base_M0M;
+    indices.k_0MM = k_base_0MM;
+    indices.k_MMM = k_base_MMM;
+
+    omegaC = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaCoarse, turbulentViscosityCoarse[indices.k_000]) : omegaCoarse;
+
+    read(f_coarse, distCoarse, indices);
+    momentsSet.calculateMPM(f_coarse, omegaC);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node TNW = MPP
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_000 = indices.k_00M;
+    indices.k_M00 = indices.k_M0M;
+    indices.k_0M0 = indices.k_0MM;
+    indices.k_00M = neighborZcoarse[indices.k_00M];
+    indices.k_MM0 = indices.k_MMM;
+    indices.k_M0M = neighborZcoarse[indices.k_M0M];
+    indices.k_0MM = neighborZcoarse[indices.k_0MM];
+    indices.k_MMM = neighborZcoarse[indices.k_MMM];
+
+    omegaC = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaCoarse, turbulentViscosityCoarse[indices.k_000]) : omegaCoarse;
+
+    read(f_coarse, distCoarse, indices);
+    momentsSet.calculateMPP(f_coarse, omegaC);
+    //////////////////////////////////////////////////////////////////////////
+    // source node TNE = PPP
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_000 = indices.k_M00;
+    indices.k_M00 = neighborXcoarse[indices.k_M00];
+    indices.k_0M0 = indices.k_MM0;
+    indices.k_00M = indices.k_M0M;
+    indices.k_MM0 = neighborXcoarse[indices.k_MM0];
+    indices.k_M0M = neighborXcoarse[indices.k_M0M];
+    indices.k_0MM = indices.k_MMM;
+    indices.k_MMM = neighborXcoarse[indices.k_MMM];
+
+    omegaC = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaCoarse, turbulentViscosityCoarse[indices.k_000]) : omegaCoarse;
+
+    read(f_coarse, distCoarse, indices);
+    momentsSet.calculatePPP(f_coarse, omegaC);
+    //////////////////////////////////////////////////////////////////////////
+    // source node BNE = PPM
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_00M = indices.k_000;
+    indices.k_M0M = indices.k_M00;
+    indices.k_0MM = indices.k_0M0;
+    indices.k_MMM = indices.k_MM0;
+    indices.k_000 = k_base_M00;
+    indices.k_M00 = neighborXcoarse[k_base_M00];
+    indices.k_0M0 = k_base_MM0;
+    indices.k_MM0 = neighborXcoarse[k_base_MM0];
+
+    omegaC = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaCoarse, turbulentViscosityCoarse[indices.k_000]) : omegaCoarse;
+
+    read(f_coarse, distCoarse, indices);
+    momentsSet.calculatePPM(f_coarse, omegaC);
+    // should be extractel until this line
+    // - ###################################################################
+
+    // 2.calculate coefficients
+    vf::lbm::Coefficients coefficients;
+    momentsSet.calculateCoefficients(coefficients, neighborCoarseToFine.x[nodeIndex], neighborCoarseToFine.y[nodeIndex], neighborCoarseToFine.z[nodeIndex]);
+
+    // 3. interpolate coarse to fine
+    interpolate<hasTurbulentViscosity>(
+        coefficients,
+        nodeIndex,
+        distributionsFine, 
+        neighborXfine,
+        neighborYfine,
+        neighborZfine,
+        numberOfLBnodesFine,
+        indicesFineMMM,
+        omegaFine,
+        turbulentViscosityFine);
 }
 
 template __global__ void scaleCF_compressible<true>( real* distributionsCoarse, real* distributionsFine, unsigned int* neighborXcoarse, unsigned int* neighborYcoarse, unsigned int* neighborZcoarse, unsigned int* neighborXfine, unsigned int* neighborYfine, unsigned int* neighborZfine, unsigned long long numberOfLBnodesCoarse, unsigned long long numberOfLBnodesFine, bool isEvenTimestep, unsigned int* indicesCoarseMMM, unsigned int* indicesFineMMM, unsigned int numberOfInterfaceNodes, real omegaCoarse, real omegaFine, real* turbulentViscosityCoarse, real* turbulentViscosityFine, ICellNeigh offsetCF);
diff --git a/src/gpu/VirtualFluids_GPU/GPU/GridScaling/scaleFC_compressible.cu b/src/gpu/VirtualFluids_GPU/GPU/GridScaling/scaleFC_compressible.cu
index 5776ba476e3537360b32ee85f32514324946ff75..3276db0595329b4c948779d0b27857170d125f78 100644
--- a/src/gpu/VirtualFluids_GPU/GPU/GridScaling/scaleFC_compressible.cu
+++ b/src/gpu/VirtualFluids_GPU/GPU/GridScaling/scaleFC_compressible.cu
@@ -35,16 +35,44 @@
 #include "LBM/GPUHelperFunctions/KernelUtilities.h"
 #include "LBM/GPUHelperFunctions/ScalingUtilities.h"
 
-using namespace vf::basics::constant;
-using namespace vf::lbm::dir;
-using namespace vf::gpu;
+#include <lbm/KernelParameter.h>
+#include <lbm/refinement/InterpolationFC.h>
+#include <lbm/refinement/Coefficients.h>
+
+
+template <bool hasTurbulentViscosity> __device__ void interpolate(
+    vf::lbm::Coefficients& coefficients,
+    const unsigned int nodeIndex,
+    real* distributionsCoarse, 
+    unsigned int* neighborXcoarse,
+    unsigned int* neighborYcoarse,
+    unsigned int* neighborZcoarse,
+    unsigned long long numberOfLBnodesCoarse,
+    unsigned int* indicesCoarse000,
+    real omegaCoarse,
+    real* turbulentViscosityCoarse,
+    bool isEvenTimestep
+)
+{
+    // Position Coarse 0., 0., 0.
+    Distributions27 distCoarse;
+    vf::gpu::getPointersToDistributions(distCoarse, distributionsCoarse, numberOfLBnodesCoarse, isEvenTimestep);
+
+    vf::gpu::ListIndices indices(indicesCoarse000[nodeIndex], neighborXcoarse, neighborYcoarse, neighborZcoarse);
+
+    const real epsilonNew = c2o1; // ratio of grid resolutions
+    const real omegaCoarseNew = hasTurbulentViscosity ? vf::gpu::calculateOmega(omegaCoarse, turbulentViscosityCoarse[indices.k_000]) : omegaCoarse;
+    real fCoarse[27];
+    vf::lbm::interpolateFC(fCoarse, epsilonNew, omegaCoarseNew, coefficients);
+
+    vf::gpu::write(distCoarse, indices, fCoarse);
+}
+
+
 
 //////////////////////////////////////////////////////////////////////////
 //! \brief Interpolate from fine to coarse
 //! \details This scaling function is designed for the Cumulant K17 Kernel chimera collision kernel
-//! The function is executed in the following steps:
-//!
-
 // based on scaleFC_RhoSq_comp_27
 template<bool hasTurbulentViscosity> __global__ void scaleFC_compressible(
     real *distributionsCoarse,
@@ -61,653 +89,41 @@ template<bool hasTurbulentViscosity> __global__ void scaleFC_compressible(
     unsigned int *indicesCoarse000,
     unsigned int *indicesFineMMM,
     unsigned int numberOfInterfaceNodes,
-    real omegaCoarse,
-    real omegaFine,
+    const real omega_coarse,
+    const real omegaFine,
     real* turbulentViscosityCoarse,
     real* turbulentViscosityFine,
     ICellNeigh neighborFineToCoarse)
 {
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - Get the node index coordinates from threadIdx, blockIdx, blockDim and gridDim.
-    //!
-    const unsigned nodeIndex = getNodeIndex();
+    const unsigned nodeIndex = vf::gpu::getNodeIndex();
 
-    //////////////////////////////////////////////////////////////////////////
-    //! - Return for non-interface node
     if (nodeIndex >= numberOfInterfaceNodes)
         return;
 
-    //////////////////////////////////////////////////////////////////////////
-    //! - 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 distFine, distCoarse;
-    getPointersToDistributions(distFine, distributionsFine, numberOfLBnodesFine, true);
-    getPointersToDistributions(distCoarse, distributionsCoarse, numberOfLBnodesCoarse, isEvenTimestep);
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - declare local variables for source nodes
-    //!
-    real eps_new = c2o1; // ratio of grid resolutions
-    real omegaF  = omegaFine;
-    real omegaC  = omegaCoarse;
-
-    // zeroth and first order moments at the source nodes
-    real drho_PPP, vx1_PPP, vx2_PPP, vx3_PPP;
-    real drho_MPP, vx1_MPP, vx2_MPP, vx3_MPP;
-    real drho_PMP, vx1_PMP, vx2_PMP, vx3_PMP;
-    real drho_MMP, vx1_MMP, vx2_MMP, vx3_MMP;
-    real drho_PPM, vx1_PPM, vx2_PPM, vx3_PPM;
-    real drho_MPM, vx1_MPM, vx2_MPM, vx3_MPM;
-    real drho_PMM, vx1_PMM, vx2_PMM, vx3_PMM;
-    real drho_MMM, vx1_MMM, vx2_MMM, vx3_MMM;
-
-    // second order moments at the source nodes
-    real kxyFromfcNEQ_PPP, kyzFromfcNEQ_PPP, kxzFromfcNEQ_PPP, kxxMyyFromfcNEQ_PPP, kxxMzzFromfcNEQ_PPP;
-    real kxyFromfcNEQ_MPP, kyzFromfcNEQ_MPP, kxzFromfcNEQ_MPP, kxxMyyFromfcNEQ_MPP, kxxMzzFromfcNEQ_MPP;
-    real kxyFromfcNEQ_PMP, kyzFromfcNEQ_PMP, kxzFromfcNEQ_PMP, kxxMyyFromfcNEQ_PMP, kxxMzzFromfcNEQ_PMP;
-    real kxyFromfcNEQ_MMP, kyzFromfcNEQ_MMP, kxzFromfcNEQ_MMP, kxxMyyFromfcNEQ_MMP, kxxMzzFromfcNEQ_MMP;
-    real kxyFromfcNEQ_PPM, kyzFromfcNEQ_PPM, kxzFromfcNEQ_PPM, kxxMyyFromfcNEQ_PPM, kxxMzzFromfcNEQ_PPM;
-    real kxyFromfcNEQ_MPM, kyzFromfcNEQ_MPM, kxzFromfcNEQ_MPM, kxxMyyFromfcNEQ_MPM, kxxMzzFromfcNEQ_MPM;
-    real kxyFromfcNEQ_PMM, kyzFromfcNEQ_PMM, kxzFromfcNEQ_PMM, kxxMyyFromfcNEQ_PMM, kxxMzzFromfcNEQ_PMM;
-    real kxyFromfcNEQ_MMM, kyzFromfcNEQ_MMM, kxzFromfcNEQ_MMM, kxxMyyFromfcNEQ_MMM, kxxMzzFromfcNEQ_MMM;
-
-    //////////////////////////////////////////////////////////////////////////
-    //! - Calculate moments for each source node 
-    //!
-    //////////////////////////////////////////////////////////////////////////
-    // source node BSW = MMM
-    //////////////////////////////////////////////////////////////////////////
-    // index of the base node and its neighbors
-    unsigned int k_base_000 = indicesFineMMM[nodeIndex];
-    unsigned int k_base_M00 = neighborXfine [k_base_000];
-    unsigned int k_base_0M0 = neighborYfine [k_base_000];
-    unsigned int k_base_00M = neighborZfine [k_base_000];
-    unsigned int k_base_MM0 = neighborYfine [k_base_M00];
-    unsigned int k_base_M0M = neighborZfine [k_base_M00];
-    unsigned int k_base_0MM = neighborZfine [k_base_0M0];
-    unsigned int k_base_MMM = neighborZfine [k_base_MM0];
-    //////////////////////////////////////////////////////////////////////////
-    // Set neighbor indices
-    unsigned int k_000 = k_base_000;
-    unsigned int k_M00 = k_base_M00;
-    unsigned int k_0M0 = k_base_0M0;
-    unsigned int k_00M = k_base_00M;
-    unsigned int k_MM0 = k_base_MM0;
-    unsigned int k_M0M = k_base_M0M;
-    unsigned int k_0MM = k_base_0MM;
-    unsigned int k_MMM = k_base_MMM;
-
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    calculateMomentsOnSourceNodes( distFine, omegaF,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_MMM, vx1_MMM, vx2_MMM, vx3_MMM,
-        kxyFromfcNEQ_MMM, kyzFromfcNEQ_MMM, kxzFromfcNEQ_MMM, kxxMyyFromfcNEQ_MMM, kxxMzzFromfcNEQ_MMM);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node TSW = MMP
-    //////////////////////////////////////////////////////////////////////////
-    // Set neighbor indices - has to be recalculated for the new source node
-    k_000 = k_00M;
-    k_M00 = k_M0M;
-    k_0M0 = k_0MM;
-    k_00M = neighborZfine[k_00M];
-    k_MM0 = k_MMM;
-    k_M0M = neighborZfine[k_M0M];
-    k_0MM = neighborZfine[k_0MM];
-    k_MMM = neighborZfine[k_MMM];
-
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    calculateMomentsOnSourceNodes( distFine, omegaF,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_MMP, vx1_MMP, vx2_MMP, vx3_MMP,
-        kxyFromfcNEQ_MMP, kyzFromfcNEQ_MMP, kxzFromfcNEQ_MMP, kxxMyyFromfcNEQ_MMP, kxxMzzFromfcNEQ_MMP);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node TSE = PMP
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_000 = k_M00;
-    k_M00 = neighborXfine[k_M00];
-    k_0M0 = k_MM0;
-    k_00M = k_M0M;
-    k_MM0 = neighborXfine[k_MM0];
-    k_M0M = neighborXfine[k_M0M];
-    k_0MM = k_MMM;
-    k_MMM = neighborXfine[k_MMM];
-
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    calculateMomentsOnSourceNodes( distFine, omegaF,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_PMP, vx1_PMP, vx2_PMP, vx3_PMP,
-        kxyFromfcNEQ_PMP, kyzFromfcNEQ_PMP, kxzFromfcNEQ_PMP, kxxMyyFromfcNEQ_PMP, kxxMzzFromfcNEQ_PMP);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node BSE = PMM 
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_00M = k_000;
-    k_M0M = k_M00;
-    k_0MM = k_0M0;
-    k_MMM = k_MM0;
-    k_000 = k_base_M00;
-    k_M00 = neighborXfine[k_base_M00];
-    k_0M0 = k_base_MM0;
-    k_MM0 = neighborXfine[k_base_MM0];
-
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    calculateMomentsOnSourceNodes( distFine, omegaF,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_PMM, vx1_PMM, vx2_PMM, vx3_PMM,
-        kxyFromfcNEQ_PMM, kyzFromfcNEQ_PMM, kxzFromfcNEQ_PMM, kxxMyyFromfcNEQ_PMM, kxxMzzFromfcNEQ_PMM);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node BNW = MPM
-    //////////////////////////////////////////////////////////////////////////
-    // index of the base node and its neighbors --> indices of all source nodes
-    k_base_000 = k_base_0M0;
-    k_base_M00 = k_base_MM0;
-    k_base_0M0 = neighborYfine[k_base_0M0];
-    k_base_00M = k_base_0MM;
-    k_base_MM0 = neighborYfine[k_base_MM0];
-    k_base_M0M = k_base_MMM;
-    k_base_0MM = neighborYfine[k_base_0MM];
-    k_base_MMM = neighborYfine[k_base_MMM];
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_000 = k_base_000;
-    k_M00 = k_base_M00;
-    k_0M0 = k_base_0M0;
-    k_00M = k_base_00M;
-    k_MM0 = k_base_MM0;
-    k_M0M = k_base_M0M;
-    k_0MM = k_base_0MM;
-    k_MMM = k_base_MMM;
-
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    calculateMomentsOnSourceNodes( distFine, omegaF,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_MPM, vx1_MPM, vx2_MPM, vx3_MPM,
-        kxyFromfcNEQ_MPM, kyzFromfcNEQ_MPM, kxzFromfcNEQ_MPM, kxxMyyFromfcNEQ_MPM, kxxMzzFromfcNEQ_MPM);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node TNW = MPP
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_000 = k_00M;
-    k_M00 = k_M0M;
-    k_0M0 = k_0MM;
-    k_00M = neighborZfine[k_00M];
-    k_MM0 = k_MMM;
-    k_M0M = neighborZfine[k_M0M];
-    k_0MM = neighborZfine[k_0MM];
-    k_MMM = neighborZfine[k_MMM];
-
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-    
-    calculateMomentsOnSourceNodes( distFine, omegaF,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_MPP, vx1_MPP, vx2_MPP, vx3_MPP,
-        kxyFromfcNEQ_MPP, kyzFromfcNEQ_MPP, kxzFromfcNEQ_MPP, kxxMyyFromfcNEQ_MPP, kxxMzzFromfcNEQ_MPP);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node TNE = PPP
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_000 = k_M00;
-    k_M00 = neighborXfine[k_M00];
-    k_0M0 = k_MM0;
-    k_00M = k_M0M;
-    k_MM0 = neighborXfine[k_MM0];
-    k_M0M = neighborXfine[k_M0M];
-    k_0MM = k_MMM;
-    k_MMM = neighborXfine[k_MMM];
-
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    calculateMomentsOnSourceNodes( distFine, omegaF,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_PPP, vx1_PPP, vx2_PPP, vx3_PPP,
-        kxyFromfcNEQ_PPP, kyzFromfcNEQ_PPP, kxzFromfcNEQ_PPP, kxxMyyFromfcNEQ_PPP, kxxMzzFromfcNEQ_PPP);
-
-    //////////////////////////////////////////////////////////////////////////
-    // source node BNE = PPM
-    //////////////////////////////////////////////////////////////////////////
-    // index
-    k_00M = k_000;
-    k_M0M = k_M00;
-    k_0MM = k_0M0;
-    k_MMM = k_MM0;
-    k_000 = k_base_M00;
-    k_M00 = neighborXfine[k_base_M00];
-    k_0M0 = k_base_MM0;
-    k_MM0 = neighborXfine[k_base_MM0];
-    
-    if(hasTurbulentViscosity) omegaF = omegaFine/ (c1o1 + c3o1*omegaFine*turbulentViscosityFine[k_000]);
-
-    calculateMomentsOnSourceNodes( distFine, omegaF,
-        k_000, k_M00, k_0M0, k_00M, k_MM0, k_M0M, k_0MM, k_MMM, drho_PPM, vx1_PPM, vx2_PPM, vx3_PPM,
-        kxyFromfcNEQ_PPM, kyzFromfcNEQ_PPM, kxzFromfcNEQ_PPM, kxxMyyFromfcNEQ_PPM, kxxMzzFromfcNEQ_PPM);
-
-    //////////////////////////////////////////////////////////////////////////
-    //! - Calculate coefficients for polynomial interpolation
-    //!
-    // example: a_110: derivation in x and y direction
-    real a_000, a_100, a_010, a_001, a_200, a_020, a_002, a_110, a_101, a_011;
-    real b_000, b_100, b_010, b_001, b_200, b_020, b_002, b_110, b_101, b_011;
-    real c_000, c_100, c_010, c_001, c_200, c_020, c_002, c_110, c_101, c_011;
-    real d_000, d_100, d_010, d_001, d_110, d_101, d_011;
-
-    a_000 = c1o64 * (
-            c2o1 * (
-            ((kxyFromfcNEQ_MMM - kxyFromfcNEQ_PPP) + (kxyFromfcNEQ_MMP - kxyFromfcNEQ_PPM)) + ((kxyFromfcNEQ_PMM - kxyFromfcNEQ_MPP) + (kxyFromfcNEQ_PMP - kxyFromfcNEQ_MPM)) + 
-            ((kxzFromfcNEQ_MMM - kxzFromfcNEQ_PPP) + (kxzFromfcNEQ_PPM - kxzFromfcNEQ_MMP)) + ((kxzFromfcNEQ_PMM - kxzFromfcNEQ_MPP) + (kxzFromfcNEQ_MPM - kxzFromfcNEQ_PMP)) + 
-            ((vx2_PPP + vx2_MMM) + (vx2_PPM + vx2_MMP)) - ((vx2_MPP + vx2_PMM) + (vx2_MPM + vx2_PMP)) + 
-            ((vx3_PPP + vx3_MMM) - (vx3_PPM + vx3_MMP)) + ((vx3_PMP + vx3_MPM) - (vx3_MPP + vx3_PMM))) + 
-            c8o1 * (((vx1_PPP + vx1_MMM) + (vx1_PPM + vx1_MMP)) + ((vx1_MPP + vx1_PMM) + (vx1_PMP + vx1_MPM))) +
-            ((kxxMyyFromfcNEQ_MMM - kxxMyyFromfcNEQ_PPP) + (kxxMyyFromfcNEQ_MMP - kxxMyyFromfcNEQ_PPM)) + 
-            ((kxxMyyFromfcNEQ_MPP - kxxMyyFromfcNEQ_PMM) + (kxxMyyFromfcNEQ_MPM - kxxMyyFromfcNEQ_PMP)) +
-            ((kxxMzzFromfcNEQ_MMM - kxxMzzFromfcNEQ_PPP) + (kxxMzzFromfcNEQ_MMP - kxxMzzFromfcNEQ_PPM)) + 
-            ((kxxMzzFromfcNEQ_MPP - kxxMzzFromfcNEQ_PMM) + (kxxMzzFromfcNEQ_MPM - kxxMzzFromfcNEQ_PMP)));
-    b_000 = c1o64 * (
-            c2o1 * (
-            ((kxxMyyFromfcNEQ_PPP - kxxMyyFromfcNEQ_MMM) + (kxxMyyFromfcNEQ_PPM - kxxMyyFromfcNEQ_MMP)) + 
-            ((kxxMyyFromfcNEQ_MPP - kxxMyyFromfcNEQ_PMM) + (kxxMyyFromfcNEQ_MPM - kxxMyyFromfcNEQ_PMP)) + 
-            ((kxyFromfcNEQ_MMM - kxyFromfcNEQ_PPP) + (kxyFromfcNEQ_MMP - kxyFromfcNEQ_PPM)) + 
-            ((kxyFromfcNEQ_MPP - kxyFromfcNEQ_PMM) + (kxyFromfcNEQ_MPM - kxyFromfcNEQ_PMP)) + 
-            ((kyzFromfcNEQ_MMM - kyzFromfcNEQ_PPP) + (kyzFromfcNEQ_PPM - kyzFromfcNEQ_MMP)) + 
-            ((kyzFromfcNEQ_PMM - kyzFromfcNEQ_MPP) + (kyzFromfcNEQ_MPM - kyzFromfcNEQ_PMP)) + 
-            ((vx1_PPP + vx1_MMM) + (vx1_PPM + vx1_MMP)) - ((vx1_MPM + vx1_MPP) + (vx1_PMM + vx1_PMP)) + 
-            ((vx3_PPP + vx3_MMM) - (vx3_PPM + vx3_MMP)) + ((vx3_MPP + vx3_PMM) - (vx3_MPM + vx3_PMP))) + 
-            c8o1 * (((vx2_PPP + vx2_MMM) + (vx2_PPM + vx2_MMP)) + ((vx2_MPP + vx2_PMM) + (vx2_MPM + vx2_PMP))) + 
-            ((kxxMzzFromfcNEQ_MMM - kxxMzzFromfcNEQ_PPP) + (kxxMzzFromfcNEQ_MMP - kxxMzzFromfcNEQ_PPM)) +
-            ((kxxMzzFromfcNEQ_PMM - kxxMzzFromfcNEQ_MPP) + (kxxMzzFromfcNEQ_PMP - kxxMzzFromfcNEQ_MPM)));
-    c_000 = c1o64 * ( 
-            c2o1 * (
-            ((kxxMzzFromfcNEQ_PPP - kxxMzzFromfcNEQ_MMM) + (kxxMzzFromfcNEQ_MMP - kxxMzzFromfcNEQ_PPM)) + 
-            ((kxxMzzFromfcNEQ_MPP - kxxMzzFromfcNEQ_PMM) + (kxxMzzFromfcNEQ_PMP - kxxMzzFromfcNEQ_MPM)) + 
-            ((kxzFromfcNEQ_MMM - kxzFromfcNEQ_PPP) + (kxzFromfcNEQ_MMP - kxzFromfcNEQ_PPM)) + 
-            ((kxzFromfcNEQ_MPP - kxzFromfcNEQ_PMM) + (kxzFromfcNEQ_MPM - kxzFromfcNEQ_PMP)) + 
-            ((kyzFromfcNEQ_MMM - kyzFromfcNEQ_PPP) + (kyzFromfcNEQ_MMP - kyzFromfcNEQ_PPM)) + 
-            ((kyzFromfcNEQ_PMM - kyzFromfcNEQ_MPP) + (kyzFromfcNEQ_PMP - kyzFromfcNEQ_MPM)) + 
-            ((vx1_PPP + vx1_MMM) - (vx1_MMP + vx1_PPM)) + ((vx1_MPM + vx1_PMP) - (vx1_MPP + vx1_PMM)) + 
-            ((vx2_PPP + vx2_MMM) - (vx2_MMP + vx2_PPM)) + ((vx2_MPP + vx2_PMM) - (vx2_MPM + vx2_PMP))) + 
-            c8o1 * (((vx3_PPP + vx3_MMM) + (vx3_PPM + vx3_MMP)) + ((vx3_PMM + vx3_MPP) + (vx3_PMP + vx3_MPM))) +
-            ((kxxMyyFromfcNEQ_MMM - kxxMyyFromfcNEQ_PPP) + (kxxMyyFromfcNEQ_PPM - kxxMyyFromfcNEQ_MMP)) + 
-            ((kxxMyyFromfcNEQ_PMM - kxxMyyFromfcNEQ_MPP) + (kxxMyyFromfcNEQ_MPM - kxxMyyFromfcNEQ_PMP)));
-
-    a_100 = c1o4 * (((vx1_PPP - vx1_MMM) + (vx1_PPM - vx1_MMP)) + ((vx1_PMM - vx1_MPP) + (vx1_PMP - vx1_MPM)));
-    b_100 = c1o4 * (((vx2_PPP - vx2_MMM) + (vx2_PPM - vx2_MMP)) + ((vx2_PMM - vx2_MPP) + (vx2_PMP - vx2_MPM)));
-    c_100 = c1o4 * (((vx3_PPP - vx3_MMM) + (vx3_PPM - vx3_MMP)) + ((vx3_PMM - vx3_MPP) + (vx3_PMP - vx3_MPM)));
-
-    a_200 = c1o16 * ( 
-            c2o1 * (
-            ((vx2_PPP + vx2_MMM) + (vx2_PPM - vx2_MPP)) + ((vx2_MMP - vx2_PMM) - (vx2_MPM + vx2_PMP)) + 
-            ((vx3_PPP + vx3_MMM) - (vx3_PPM + vx3_MPP)) + ((vx3_MPM + vx3_PMP) - (vx3_MMP + vx3_PMM))) + 
-            ((kxxMyyFromfcNEQ_PPP - kxxMyyFromfcNEQ_MMM) + (kxxMyyFromfcNEQ_PPM - kxxMyyFromfcNEQ_MMP)) + 
-            ((kxxMyyFromfcNEQ_PMM - kxxMyyFromfcNEQ_MPP) + (kxxMyyFromfcNEQ_PMP - kxxMyyFromfcNEQ_MPM)) + 
-            ((kxxMzzFromfcNEQ_PPP - kxxMzzFromfcNEQ_MMM) + (kxxMzzFromfcNEQ_PPM - kxxMzzFromfcNEQ_MMP)) + 
-            ((kxxMzzFromfcNEQ_PMM - kxxMzzFromfcNEQ_MPP) + (kxxMzzFromfcNEQ_PMP - kxxMzzFromfcNEQ_MPM)));
-    b_200 = c1o8 * (
-            c2o1 * (
-            -((vx1_PPP + vx1_MMM) + (vx1_PPM + vx1_MMP)) + ((vx1_MPP + vx1_PMM) + (vx1_MPM + vx1_PMP))) +
-            ((kxyFromfcNEQ_PPP - kxyFromfcNEQ_MMM) + (kxyFromfcNEQ_PPM - kxyFromfcNEQ_MMP)) + 
-            ((kxyFromfcNEQ_PMM - kxyFromfcNEQ_MPP) + (kxyFromfcNEQ_PMP - kxyFromfcNEQ_MPM)));
-    c_200 = c1o8 * (
-            c2o1 * (
-            ((vx1_PPM + vx1_MMP) - (vx1_PPP + vx1_MMM)) + ((vx1_MPP + vx1_PMM) - (vx1_MPM + vx1_PMP))) +
-            ((kxzFromfcNEQ_PPP - kxzFromfcNEQ_MMM) + (kxzFromfcNEQ_PPM - kxzFromfcNEQ_MMP)) + 
-            ((kxzFromfcNEQ_PMM - kxzFromfcNEQ_MPP) + (kxzFromfcNEQ_PMP - kxzFromfcNEQ_MPM)));
-
-    a_010 = c1o4 * (((vx1_PPP - vx1_MMM) + (vx1_PPM - vx1_MMP)) + ((vx1_MPP - vx1_PMM) + (vx1_MPM - vx1_PMP)));
-    b_010 = c1o4 * (((vx2_PPP - vx2_MMM) + (vx2_PPM - vx2_MMP)) + ((vx2_MPP - vx2_PMM) + (vx2_MPM - vx2_PMP)));
-    c_010 = c1o4 * (((vx3_PPP - vx3_MMM) + (vx3_PPM - vx3_MMP)) + ((vx3_MPP - vx3_PMM) + (vx3_MPM - vx3_PMP)));
-
-    a_020 = c1o8 * (
-            c2o1 * (-((vx2_PPP + vx2_MMM) + (vx2_MMP + vx2_PPM)) + ((vx2_MPP + vx2_PMM) + (vx2_MPM + vx2_PMP))) +
-            ((kxyFromfcNEQ_PPP - kxyFromfcNEQ_MMM) + (kxyFromfcNEQ_PPM - kxyFromfcNEQ_MMP)) + 
-            ((kxyFromfcNEQ_MPP - kxyFromfcNEQ_PMM) + (kxyFromfcNEQ_MPM - kxyFromfcNEQ_PMP)));
-    b_020 = c1o16 * (
-            c2o1 * (
-            ((kxxMyyFromfcNEQ_MMM - kxxMyyFromfcNEQ_PPP) + (kxxMyyFromfcNEQ_MMP - kxxMyyFromfcNEQ_PPM)) +
-            ((kxxMyyFromfcNEQ_PMM - kxxMyyFromfcNEQ_MPP) + (kxxMyyFromfcNEQ_PMP - kxxMyyFromfcNEQ_MPM)) +
-            ((vx1_PPP + vx1_MMM) + (vx1_PPM + vx1_MMP)) - ((vx1_MPP + vx1_PMM) + (vx1_PMP + vx1_MPM)) + 
-            ((vx3_PPP + vx3_MMM) - (vx3_PPM + vx3_MMP)) + ((vx3_MPP + vx3_PMM) - (vx3_MPM + vx3_PMP))) +
-            ((kxxMzzFromfcNEQ_PPP - kxxMzzFromfcNEQ_MMM) + (kxxMzzFromfcNEQ_PPM - kxxMzzFromfcNEQ_MMP)) + 
-            ((kxxMzzFromfcNEQ_MPP - kxxMzzFromfcNEQ_PMM) + (kxxMzzFromfcNEQ_MPM - kxxMzzFromfcNEQ_PMP)));
-    c_020 = c1o8 * (
-            c2o1 * (((vx2_MMP + vx2_PPM) - (vx2_PPP + vx2_MMM)) + ((vx2_PMP + vx2_MPM) - (vx2_MPP + vx2_PMM))) +
-            ((kyzFromfcNEQ_PPP - kyzFromfcNEQ_MMM) + (kyzFromfcNEQ_PPM - kyzFromfcNEQ_MMP)) +
-            ((kyzFromfcNEQ_MPP - kyzFromfcNEQ_PMM) + (kyzFromfcNEQ_MPM - kyzFromfcNEQ_PMP)));
-
-    a_001 = c1o4 * (((vx1_PPP - vx1_MMM) + (vx1_MMP - vx1_PPM)) + ((vx1_MPP - vx1_PMM) + (vx1_PMP - vx1_MPM)));
-    b_001 = c1o4 * (((vx2_PPP - vx2_MMM) + (vx2_MMP - vx2_PPM)) + ((vx2_MPP - vx2_PMM) + (vx2_PMP - vx2_MPM)));
-    c_001 = c1o4 * (((vx3_PPP - vx3_MMM) + (vx3_MMP - vx3_PPM)) + ((vx3_MPP - vx3_PMM) + (vx3_PMP - vx3_MPM)));
-
-    a_002 = c1o8 * (
-            c2o1 * (((vx3_PPM + vx3_MMP) - (vx3_PPP + vx3_MMM)) + ((vx3_MPP + vx3_PMM) - (vx3_PMP + vx3_MPM))) +
-                    ((kxzFromfcNEQ_PPP - kxzFromfcNEQ_MMM) + (kxzFromfcNEQ_MMP - kxzFromfcNEQ_PPM)) +
-                    ((kxzFromfcNEQ_PMP - kxzFromfcNEQ_MPM) + (kxzFromfcNEQ_MPP - kxzFromfcNEQ_PMM)));
-    b_002 = c1o8 * (
-            c2o1 * (((vx3_PPM + vx3_MMP) - (vx3_PPP + vx3_MMM)) + ((vx3_MPM + vx3_PMP) - (vx3_PMM + vx3_MPP))) + 
-                    ((kyzFromfcNEQ_PPP - kyzFromfcNEQ_MMM) + (kyzFromfcNEQ_MMP - kyzFromfcNEQ_PPM)) + 
-                    ((kyzFromfcNEQ_PMP - kyzFromfcNEQ_MPM) + (kyzFromfcNEQ_MPP - kyzFromfcNEQ_PMM)));
-    c_002 = c1o16 * (
-            c2o1 * (
-            ((kxxMzzFromfcNEQ_MMM - kxxMzzFromfcNEQ_PPP) + (kxxMzzFromfcNEQ_PPM - kxxMzzFromfcNEQ_MMP)) + 
-            ((kxxMzzFromfcNEQ_MPM - kxxMzzFromfcNEQ_PMP) + (kxxMzzFromfcNEQ_PMM - kxxMzzFromfcNEQ_MPP)) + 
-            ((vx1_PPP + vx1_MMM) - (vx1_MMP + vx1_PPM)) + ((vx1_MPM + vx1_PMP) - (vx1_PMM + vx1_MPP)) + 
-            ((vx2_PPP + vx2_MMM) - (vx2_MMP + vx2_PPM)) + ((vx2_PMM + vx2_MPP) - (vx2_MPM + vx2_PMP))) + 
-            ((kxxMyyFromfcNEQ_PPP - kxxMyyFromfcNEQ_MMM) + (kxxMyyFromfcNEQ_MMP - kxxMyyFromfcNEQ_PPM)) +
-            ((kxxMyyFromfcNEQ_PMP - kxxMyyFromfcNEQ_MPM) + (kxxMyyFromfcNEQ_MPP - kxxMyyFromfcNEQ_PMM)));
-
-    a_110 = c1o2 * (((vx1_PPP + vx1_MMM) + (vx1_MMP + vx1_PPM)) - ((vx1_MPM + vx1_PMP) + (vx1_PMM + vx1_MPP)));
-    b_110 = c1o2 * (((vx2_PPP + vx2_MMM) + (vx2_MMP + vx2_PPM)) - ((vx2_MPM + vx2_PMP) + (vx2_PMM + vx2_MPP)));
-    c_110 = c1o2 * (((vx3_PPP + vx3_MMM) + (vx3_MMP + vx3_PPM)) - ((vx3_MPM + vx3_PMP) + (vx3_PMM + vx3_MPP)));
-
-    a_101 = c1o2 * (((vx1_PPP + vx1_MMM) - (vx1_MMP + vx1_PPM)) + ((vx1_MPM + vx1_PMP) - (vx1_PMM + vx1_MPP)));
-    b_101 = c1o2 * (((vx2_PPP + vx2_MMM) - (vx2_MMP + vx2_PPM)) + ((vx2_MPM + vx2_PMP) - (vx2_PMM + vx2_MPP)));
-    c_101 = c1o2 * (((vx3_PPP + vx3_MMM) - (vx3_MMP + vx3_PPM)) + ((vx3_MPM + vx3_PMP) - (vx3_PMM + vx3_MPP)));
-    
-    a_011 = c1o2 * (((vx1_PPP + vx1_MMM) - (vx1_MMP + vx1_PPM)) + ((vx1_PMM + vx1_MPP) - (vx1_MPM + vx1_PMP)));
-    b_011 = c1o2 * (((vx2_PPP + vx2_MMM) - (vx2_MMP + vx2_PPM)) + ((vx2_PMM + vx2_MPP) - (vx2_MPM + vx2_PMP)));
-    c_011 = c1o2 * (((vx3_PPP + vx3_MMM) - (vx3_MMP + vx3_PPM)) + ((vx3_PMM + vx3_MPP) - (vx3_MPM + vx3_PMP)));
-
-    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    
-    real kxyAverage    = c0o1;
-    real kyzAverage    = c0o1;
-    real kxzAverage    = c0o1;
-    real kxxMyyAverage = c0o1;
-    real kxxMzzAverage = c0o1;
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - Set the relative position of the offset cell {-1, 0, 1}
-    //!
-    real xoff    = neighborFineToCoarse.x[nodeIndex];
-    real yoff    = neighborFineToCoarse.y[nodeIndex];
-    real zoff    = neighborFineToCoarse.z[nodeIndex];
-     
-    real xoff_sq = xoff * xoff;
-    real yoff_sq = yoff * yoff;
-    real zoff_sq = zoff * zoff;
-
-    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    //!- Calculate coefficients for the polynomial interpolation of the pressure
-    //! 
-    real LaplaceRho = 
-        ((xoff != c0o1) || (yoff != c0o1) || (zoff != c0o1))
-        ? c0o1 : -c3o1 * (a_100 * a_100 + b_010 * b_010 + c_001 * c_001) - c6o1 * (b_100 * a_010 + c_100 * a_001 + c_010 * b_001);
-    d_000 =  c1o8 * ((((drho_PPP + drho_MMM) + (drho_PPM + drho_MMP)) + ((drho_PMM + drho_MPP) + (drho_PMP + drho_MPM))) - c2o1 * LaplaceRho);
-    d_100 = c1o4 * (((drho_PPP - drho_MMM) + (drho_PPM - drho_MMP)) + ((drho_PMM - drho_MPP) + (drho_PMP - drho_MPM)));
-    d_010 = c1o4 * (((drho_PPP - drho_MMM) + (drho_PPM - drho_MMP)) + ((drho_MPP - drho_PMM) + (drho_MPM - drho_PMP)));
-    d_001 = c1o4 * (((drho_PPP - drho_MMM) + (drho_MMP - drho_PPM)) + ((drho_MPP - drho_PMM) + (drho_PMP - drho_MPM)));
-    d_110 = c1o2 * (((drho_PPP + drho_MMM) + (drho_PPM + drho_MMP)) - ((drho_PMM + drho_MPP) + (drho_PMP + drho_MPM)));
-    d_101 = c1o2 * (((drho_PPP + drho_MMM) - (drho_PPM + drho_MMP)) + ((drho_PMP + drho_MPM) - (drho_PMM + drho_MPP)));
-    d_011 = c1o2 * (((drho_PPP + drho_MMM) - (drho_PPM + drho_MMP)) + ((drho_PMM + drho_MPP) - (drho_PMP + drho_MPM)));
-
-
-    //////////////////////////////////////////////////////////////////////////
-    //! - Extrapolation for refinement in to the wall (polynomial coefficients)
-    //!
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    //
-    // x------x
-    // |      |
-    // |   ---+--->X
-    // |      |  \
-    // x------x   \
-    //          offset-vector
-    //
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    a_000 = a_000 + xoff * a_100 + yoff * a_010 + zoff * a_001 + xoff_sq * a_200 + yoff_sq * a_020 + zoff_sq * a_002 +
-            xoff * yoff * a_110 + xoff * zoff * a_101 + yoff * zoff * a_011;
-    a_100 = a_100 + c2o1 * xoff * a_200 + yoff * a_110 + zoff * a_101;
-    a_010 = a_010 + c2o1 * yoff * a_020 + xoff * a_110 + zoff * a_011;
-    a_001 = a_001 + c2o1 * zoff * a_002 + xoff * a_101 + yoff * a_011;
-    b_000 = b_000 + xoff * b_100 + yoff * b_010 + zoff * b_001 + xoff_sq * b_200 + yoff_sq * b_020 + zoff_sq * b_002 +
-            xoff * yoff * b_110 + xoff * zoff * b_101 + yoff * zoff * b_011;
-    b_100 = b_100 + c2o1 * xoff * b_200 + yoff * b_110 + zoff * b_101;
-    b_010 = b_010 + c2o1 * yoff * b_020 + xoff * b_110 + zoff * b_011;
-    b_001 = b_001 + c2o1 * zoff * b_002 + xoff * b_101 + yoff * b_011;
-    c_000 = c_000 + xoff * c_100 + yoff * c_010 + zoff * c_001 + xoff_sq * c_200 + yoff_sq * c_020 + zoff_sq * c_002 +
-            xoff * yoff * c_110 + xoff * zoff * c_101 + yoff * zoff * c_011;
-    c_100 = c_100 + c2o1 * xoff * c_200 + yoff * c_110 + zoff * c_101;
-    c_010 = c_010 + c2o1 * yoff * c_020 + xoff * c_110 + zoff * c_011;
-    c_001 = c_001 + c2o1 * zoff * c_002 + xoff * c_101 + yoff * c_011;
-    d_000 = d_000 + xoff * d_100 + yoff * d_010 + zoff * d_001 + 
-            xoff * yoff * d_110 + xoff * zoff * d_101 + yoff * zoff * d_011;
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    //! - Set all moments to zero
-    //!
-    real m_111 = c0o1;
-    real m_211 = c0o1;
-    real m_011 = c0o1;
-    real m_121 = c0o1;
-    real m_101 = c0o1;
-    real m_112 = c0o1;
-    real m_110 = c0o1;
-    real m_221 = c0o1;
-    real m_001 = c0o1;
-    real m_201 = c0o1;
-    real m_021 = c0o1;
-    real m_212 = c0o1;
-    real m_010 = c0o1;
-    real m_210 = c0o1;
-    real m_012 = c0o1;
-    real m_122 = c0o1;
-    real m_100 = c0o1;
-    real m_120 = c0o1;
-    real m_102 = c0o1;
-    real m_222 = c0o1;
-    real m_022 = c0o1;
-    real m_202 = c0o1;
-    real m_002 = c0o1;
-    real m_220 = c0o1;
-    real m_020 = c0o1;
-    real m_200 = c0o1;
-    real m_000 = c0o1;
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    //! - Define aliases to use the same variable for the distributions (f's):
-    //!
-    real& f_000 = m_111;
-    real& f_P00 = m_211;
-    real& f_M00 = m_011;
-    real& f_0P0 = m_121;
-    real& f_0M0 = m_101;
-    real& f_00P = m_112;
-    real& f_00M = m_110;
-    real& f_PP0 = m_221;
-    real& f_MM0 = m_001;
-    real& f_PM0 = m_201;
-    real& f_MP0 = m_021;
-    real& f_P0P = m_212;
-    real& f_M0M = m_010;
-    real& f_P0M = m_210;
-    real& f_M0P = m_012;
-    real& f_0PP = m_122;
-    real& f_0MM = m_100;
-    real& f_0PM = m_120;
-    real& f_0MP = m_102;
-    real& f_PPP = m_222;
-    real& f_MPP = m_022;
-    real& f_PMP = m_202;
-    real& f_MMP = m_002;
-    real& f_PPM = m_220;
-    real& f_MPM = m_020;
-    real& f_PMM = m_200;
-    real& f_MMM = m_000;
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - Declare local variables for destination nodes
-    //!
-    real vvx, vvy, vvz, vx_sq, vy_sq, vz_sq;
-    real mxxPyyPzz, mxxMyy, mxxMzz, mxxyPyzz, mxxyMyzz, mxxzPyyz, mxxzMyyz, mxyyPxzz, mxyyMxzz;
-    real useNEQ = c1o1; // zero; //one;   //.... one = on ..... zero = off
-    real press;
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    //
-    // Position Coarse 0., 0., 0.
-    //
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    // x = 0.;
-    // y = 0.;
-    // z = 0.;
-    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-    // index of the destination node and its neighbors
-    k_000 = indicesCoarse000[nodeIndex];
-    k_M00 = neighborXcoarse [k_000];
-    k_0M0 = neighborYcoarse [k_000];
-    k_00M = neighborZcoarse [k_000];
-    k_MM0 = neighborYcoarse [k_M00];
-    k_M0M = neighborZcoarse [k_M00];
-    k_0MM = neighborZcoarse [k_0M0];
-    k_MMM = neighborZcoarse [k_MM0];
-    ////////////////////////////////////////////////////////////////////////////////////
-
-    if(hasTurbulentViscosity) omegaC = omegaCoarse / (c1o1 + c3o1*omegaCoarse*turbulentViscosityCoarse[k_000]);
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - Set macroscopic values on destination node (zeroth and first order moments)
-    //!
-    press = d_000;
-    vvx   = a_000;
-    vvy   = b_000;
-    vvz   = c_000;
-
-    m_000 = press; // m_000 is press, if drho is interpolated directly
-
-    vx_sq = vvx * vvx;
-    vy_sq = vvy * vvy;
-    vz_sq = vvz * vvz;
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //! - Set moments (second to sixth order) on destination node
-    //!
-    // linear combinations for second order moments
-    mxxPyyPzz = m_000;
-
-    mxxMyy = -c2o3 * ((a_100 - b_010) + kxxMyyAverage) * eps_new / omegaC * (c1o1 + press);
-    mxxMzz = -c2o3 * ((a_100 - c_001) + kxxMzzAverage) * eps_new / omegaC * (c1o1 + press);
-
-    m_011 = -c1o3 * ((b_001 + c_010) + kyzAverage) * eps_new / omegaC * (c1o1 + press);
-    m_101 = -c1o3 * ((a_001 + c_100) + kxzAverage) * eps_new / omegaC * (c1o1 + press);
-    m_110 = -c1o3 * ((a_010 + b_100) + kxyAverage) * eps_new / omegaC * (c1o1 + press);
-
-    m_200 = c1o3 * (        mxxMyy +        mxxMzz + mxxPyyPzz) * useNEQ;
-    m_020 = c1o3 * (-c2o1 * mxxMyy +        mxxMzz + mxxPyyPzz) * useNEQ;
-    m_002 = c1o3 * (        mxxMyy - c2o1 * mxxMzz + mxxPyyPzz) * useNEQ;
-
-    // linear combinations for third order moments
-    m_111 = c0o1;
-
-    mxxyPyzz = c0o1;
-    mxxyMyzz = c0o1;
-    mxxzPyyz = c0o1;
-    mxxzMyyz = c0o1;
-    mxyyPxzz = c0o1;
-    mxyyMxzz = c0o1;
-
-    m_210 = ( mxxyMyzz + mxxyPyzz) * c1o2;
-    m_012 = (-mxxyMyzz + mxxyPyzz) * c1o2;
-    m_201 = ( mxxzMyyz + mxxzPyyz) * c1o2;
-    m_021 = (-mxxzMyyz + mxxzPyyz) * c1o2;
-    m_120 = ( mxyyMxzz + mxyyPxzz) * c1o2;
-    m_102 = (-mxyyMxzz + mxyyPxzz) * c1o2;
-
-    // fourth order moments
-    m_022 = m_000 * c1o9;
-    m_202 = m_022;
-    m_220 = m_022;
-
-    // fifth order moments
-
-    // sixth order moments
-    m_222 = m_000 * c1o27;
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    //! - Chimera transform from central moments to well conditioned distributions as defined in Appendix J in
-    //! <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> see also Eq. (88)-(96) in <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>
-    //!
-    ////////////////////////////////////////////////////////////////////////////////////
-    // X - Dir
-    backwardInverseChimeraWithK(m_000, m_100, m_200, vvx, vx_sq, c1o1, c1o1);
-    backwardChimera(            m_010, m_110, m_210, vvx, vx_sq);
-    backwardInverseChimeraWithK(m_020, m_120, m_220, vvx, vx_sq, c3o1, c1o3);
-    backwardChimera(            m_001, m_101, m_201, vvx, vx_sq);
-    backwardChimera(            m_011, m_111, m_211, vvx, vx_sq);
-    backwardChimera(            m_021, m_121, m_221, vvx, vx_sq);
-    backwardInverseChimeraWithK(m_002, m_102, m_202, vvx, vx_sq, c3o1, c1o3);
-    backwardChimera(            m_012, m_112, m_212, vvx, vx_sq);
-    backwardInverseChimeraWithK(m_022, m_122, m_222, vvx, vx_sq, c9o1, c1o9);
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    // Y - Dir
-    backwardInverseChimeraWithK(m_000, m_010, m_020, vvy, vy_sq, c6o1, c1o6);
-    backwardChimera(            m_001, m_011, m_021, vvy, vy_sq);
-    backwardInverseChimeraWithK(m_002, m_012, m_022, vvy, vy_sq, c18o1, c1o18);
-    backwardInverseChimeraWithK(m_100, m_110, m_120, vvy, vy_sq, c3o2, c2o3);
-    backwardChimera(            m_101, m_111, m_121, vvy, vy_sq);
-    backwardInverseChimeraWithK(m_102, m_112, m_122, vvy, vy_sq, c9o2, c2o9);
-    backwardInverseChimeraWithK(m_200, m_210, m_220, vvy, vy_sq, c6o1, c1o6);
-    backwardChimera(            m_201, m_211, m_221, vvy, vy_sq);
-    backwardInverseChimeraWithK(m_202, m_212, m_222, vvy, vy_sq, c18o1, c1o18);
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    // Z - Dir
-    backwardInverseChimeraWithK(m_000, m_001, m_002, vvz, vz_sq, c36o1, c1o36);
-    backwardInverseChimeraWithK(m_010, m_011, m_012, vvz, vz_sq, c9o1,  c1o9);
-    backwardInverseChimeraWithK(m_020, m_021, m_022, vvz, vz_sq, c36o1, c1o36);
-    backwardInverseChimeraWithK(m_100, m_101, m_102, vvz, vz_sq, c9o1,  c1o9);
-    backwardInverseChimeraWithK(m_110, m_111, m_112, vvz, vz_sq, c9o4,  c4o9);
-    backwardInverseChimeraWithK(m_120, m_121, m_122, vvz, vz_sq, c9o1,  c1o9);
-    backwardInverseChimeraWithK(m_200, m_201, m_202, vvz, vz_sq, c36o1, c1o36);
-    backwardInverseChimeraWithK(m_210, m_211, m_212, vvz, vz_sq, c9o1,  c1o9);
-    backwardInverseChimeraWithK(m_220, m_221, m_222, vvz, vz_sq, c36o1, c1o36);
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    //! - Write distributions: style of reading and writing the distributions from/to
-    //! 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>
-    //!
-    (distCoarse.f[DIR_000])[k_000] = f_000;
-    (distCoarse.f[DIR_P00])[k_000] = f_P00;
-    (distCoarse.f[DIR_M00])[k_M00] = f_M00;
-    (distCoarse.f[DIR_0P0])[k_000] = f_0P0;
-    (distCoarse.f[DIR_0M0])[k_0M0] = f_0M0;
-    (distCoarse.f[DIR_00P])[k_000] = f_00P;
-    (distCoarse.f[DIR_00M])[k_00M] = f_00M;
-    (distCoarse.f[DIR_PP0])[k_000] = f_PP0;
-    (distCoarse.f[DIR_MM0])[k_MM0] = f_MM0;
-    (distCoarse.f[DIR_PM0])[k_0M0] = f_PM0;
-    (distCoarse.f[DIR_MP0])[k_M00] = f_MP0;
-    (distCoarse.f[DIR_P0P])[k_000] = f_P0P;
-    (distCoarse.f[DIR_M0M])[k_M0M] = f_M0M;
-    (distCoarse.f[DIR_P0M])[k_00M] = f_P0M;
-    (distCoarse.f[DIR_M0P])[k_M00] = f_M0P;
-    (distCoarse.f[DIR_0PP])[k_000] = f_0PP;
-    (distCoarse.f[DIR_0MM])[k_0MM] = f_0MM;
-    (distCoarse.f[DIR_0PM])[k_00M] = f_0PM;
-    (distCoarse.f[DIR_0MP])[k_0M0] = f_0MP;
-    (distCoarse.f[DIR_PPP])[k_000] = f_PPP;
-    (distCoarse.f[DIR_MPP])[k_M00] = f_MPP;
-    (distCoarse.f[DIR_PMP])[k_0M0] = f_PMP;
-    (distCoarse.f[DIR_MMP])[k_MM0] = f_MMP;
-    (distCoarse.f[DIR_PPM])[k_00M] = f_PPM;
-    (distCoarse.f[DIR_MPM])[k_M0M] = f_MPM;
-    (distCoarse.f[DIR_PMM])[k_0MM] = f_PMM;
-    (distCoarse.f[DIR_MMM])[k_MMM] = f_MMM;
-    ////////////////////////////////////////////////////////////////////////////////////
+    // 1.calculate moments
+    vf::lbm::MomentsOnSourceNodeSet momentsSet;
+    vf::gpu::calculateMomentSet<hasTurbulentViscosity>(
+        momentsSet, nodeIndex, distributionsFine, neighborXfine, neighborYfine, neighborZfine, indicesFineMMM, turbulentViscosityFine, numberOfLBnodesFine, omegaFine, true);
+
+    // 2.calculate coefficients
+    vf::lbm::Coefficients coefficients;
+    momentsSet.calculateCoefficients(coefficients, neighborFineToCoarse.x[nodeIndex], neighborFineToCoarse.y[nodeIndex], neighborFineToCoarse.z[nodeIndex]);
+
+    // 3. interpolate fine to coarse
+    interpolate<hasTurbulentViscosity>(
+        coefficients,
+        nodeIndex,
+        distributionsCoarse, 
+        neighborXcoarse,
+        neighborYcoarse,
+        neighborZcoarse,
+        numberOfLBnodesCoarse,
+        indicesCoarse000,
+        omega_coarse,
+        turbulentViscosityCoarse,
+        isEvenTimestep);
 }
 
-template __global__ void scaleFC_compressible<true>( real *distributionsCoarse, real *distributionsFine, unsigned int *neighborXcoarse, unsigned int *neighborYcoarse, unsigned int *neighborZcoarse, unsigned int *neighborXfine, unsigned int *neighborYfine, unsigned int *neighborZfine, unsigned long long numberOfLBnodesCoarse, unsigned long long numberOfLBnodesFine, bool isEvenTimestep, unsigned int *indicesCoarse000, unsigned int *indicesFineMMM, unsigned int numberOfInterfaceNodes, real omegaCoarse, real omegaFine, real* turbulentViscosityCoarse, real* turbulentViscosityFine, ICellNeigh neighborFineToCoarse);
+template __global__ void scaleFC_compressible<true>(real *distributionsCoarse, real *distributionsFine, unsigned int *neighborXcoarse, unsigned int *neighborYcoarse, unsigned int *neighborZcoarse, unsigned int *neighborXfine, unsigned int *neighborYfine, unsigned int *neighborZfine, unsigned long long numberOfLBnodesCoarse, unsigned long long numberOfLBnodesFine, bool isEvenTimestep, unsigned int *indicesCoarse000, unsigned int *indicesFineMMM, unsigned int numberOfInterfaceNodes, real omegaCoarse, real omegaFine, real* turbulentViscosityCoarse, real* turbulentViscosityFine, ICellNeigh neighborFineToCoarse);
 
-template __global__ void scaleFC_compressible<false>( real *distributionsCoarse, real *distributionsFine, unsigned int *neighborXcoarse, unsigned int *neighborYcoarse, unsigned int *neighborZcoarse, unsigned int *neighborXfine, unsigned int *neighborYfine, unsigned int *neighborZfine, unsigned long long numberOfLBnodesCoarse, unsigned long long numberOfLBnodesFine, bool isEvenTimestep, unsigned int *indicesCoarse000, unsigned int *indicesFineMMM, unsigned int numberOfInterfaceNodes, real omegaCoarse, real omegaFine, real* turbulentViscosityCoarse, real* turbulentViscosityFine, ICellNeigh neighborFineToCoarse);
\ No newline at end of file
+template __global__ void scaleFC_compressible<false>(real *distributionsCoarse, real *distributionsFine, unsigned int *neighborXcoarse, unsigned int *neighborYcoarse, unsigned int *neighborZcoarse, unsigned int *neighborXfine, unsigned int *neighborYfine, unsigned int *neighborZfine, unsigned long long numberOfLBnodesCoarse, unsigned long long numberOfLBnodesFine, bool isEvenTimestep, unsigned int *indicesCoarse000, unsigned int *indicesFineMMM, unsigned int numberOfInterfaceNodes, real omegaCoarse, real omegaFine, real* turbulentViscosityCoarse, real* turbulentViscosityFine, ICellNeigh neighborFineToCoarse);
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/Kernel/Utilities/DistributionHelper.cu b/src/gpu/VirtualFluids_GPU/Kernel/Utilities/DistributionHelper.cu
index a1d9ba6665576c90406eee13084e5133acdb448c..3cc4b33f0b752943c97b1b770c62189a6c17d9c8 100644
--- a/src/gpu/VirtualFluids_GPU/Kernel/Utilities/DistributionHelper.cu
+++ b/src/gpu/VirtualFluids_GPU/Kernel/Utilities/DistributionHelper.cu
@@ -19,33 +19,33 @@ __device__ DistributionWrapper::DistributionWrapper(real *distributions, unsigne
 
 __device__ void DistributionWrapper::read()
 {
-    distribution.f[vf::lbm::dir::PZZ] = (distribution_references.f[DIR_P00])[k];
-    distribution.f[vf::lbm::dir::MZZ] = (distribution_references.f[DIR_M00])[kw];
-    distribution.f[vf::lbm::dir::ZPZ] = (distribution_references.f[DIR_0P0])[k];
-    distribution.f[vf::lbm::dir::ZMZ] = (distribution_references.f[DIR_0M0])[ks];
-    distribution.f[vf::lbm::dir::ZZP] = (distribution_references.f[DIR_00P])[k];
-    distribution.f[vf::lbm::dir::ZZM] = (distribution_references.f[DIR_00M])[kb];
-    distribution.f[vf::lbm::dir::PPZ] = (distribution_references.f[DIR_PP0])[k];
-    distribution.f[vf::lbm::dir::MMZ] = (distribution_references.f[DIR_MM0])[ksw];
-    distribution.f[vf::lbm::dir::PMZ] = (distribution_references.f[DIR_PM0])[ks];
-    distribution.f[vf::lbm::dir::MPZ] = (distribution_references.f[DIR_MP0])[kw];
-    distribution.f[vf::lbm::dir::PZP] = (distribution_references.f[DIR_P0P])[k];
-    distribution.f[vf::lbm::dir::MZM] = (distribution_references.f[DIR_M0M])[kbw];
-    distribution.f[vf::lbm::dir::PZM] = (distribution_references.f[DIR_P0M])[kb];
-    distribution.f[vf::lbm::dir::MZP] = (distribution_references.f[DIR_M0P])[kw];
-    distribution.f[vf::lbm::dir::ZPP] = (distribution_references.f[DIR_0PP])[k];
-    distribution.f[vf::lbm::dir::ZMM] = (distribution_references.f[DIR_0MM])[kbs];
-    distribution.f[vf::lbm::dir::ZPM] = (distribution_references.f[DIR_0PM])[kb];
-    distribution.f[vf::lbm::dir::ZMP] = (distribution_references.f[DIR_0MP])[ks];
-    distribution.f[vf::lbm::dir::PPP] = (distribution_references.f[DIR_PPP])[k];
-    distribution.f[vf::lbm::dir::MPP] = (distribution_references.f[DIR_MPP])[kw];
-    distribution.f[vf::lbm::dir::PMP] = (distribution_references.f[DIR_PMP])[ks];
-    distribution.f[vf::lbm::dir::MMP] = (distribution_references.f[DIR_MMP])[ksw];
-    distribution.f[vf::lbm::dir::PPM] = (distribution_references.f[DIR_PPM])[kb];
-    distribution.f[vf::lbm::dir::MPM] = (distribution_references.f[DIR_MPM])[kbw];
-    distribution.f[vf::lbm::dir::PMM] = (distribution_references.f[DIR_PMM])[kbs];
-    distribution.f[vf::lbm::dir::MMM] = (distribution_references.f[DIR_MMM])[kbsw];
-    distribution.f[vf::lbm::dir::ZZZ] = (distribution_references.f[DIR_000])[k];
+    distribution.f[vf::lbm::dir::DIR_P00] = (distribution_references.f[DIR_P00])[k];
+    distribution.f[vf::lbm::dir::DIR_M00] = (distribution_references.f[DIR_M00])[kw];
+    distribution.f[vf::lbm::dir::DIR_0P0] = (distribution_references.f[DIR_0P0])[k];
+    distribution.f[vf::lbm::dir::DIR_0M0] = (distribution_references.f[DIR_0M0])[ks];
+    distribution.f[vf::lbm::dir::DIR_00P] = (distribution_references.f[DIR_00P])[k];
+    distribution.f[vf::lbm::dir::DIR_00M] = (distribution_references.f[DIR_00M])[kb];
+    distribution.f[vf::lbm::dir::DIR_PP0] = (distribution_references.f[DIR_PP0])[k];
+    distribution.f[vf::lbm::dir::DIR_MM0] = (distribution_references.f[DIR_MM0])[ksw];
+    distribution.f[vf::lbm::dir::DIR_PM0] = (distribution_references.f[DIR_PM0])[ks];
+    distribution.f[vf::lbm::dir::DIR_MP0] = (distribution_references.f[DIR_MP0])[kw];
+    distribution.f[vf::lbm::dir::DIR_P0P] = (distribution_references.f[DIR_P0P])[k];
+    distribution.f[vf::lbm::dir::DIR_M0M] = (distribution_references.f[DIR_M0M])[kbw];
+    distribution.f[vf::lbm::dir::DIR_P0M] = (distribution_references.f[DIR_P0M])[kb];
+    distribution.f[vf::lbm::dir::DIR_M0P] = (distribution_references.f[DIR_M0P])[kw];
+    distribution.f[vf::lbm::dir::DIR_0PP] = (distribution_references.f[DIR_0PP])[k];
+    distribution.f[vf::lbm::dir::DIR_0MM] = (distribution_references.f[DIR_0MM])[kbs];
+    distribution.f[vf::lbm::dir::DIR_0PM] = (distribution_references.f[DIR_0PM])[kb];
+    distribution.f[vf::lbm::dir::DIR_0MP] = (distribution_references.f[DIR_0MP])[ks];
+    distribution.f[vf::lbm::dir::DIR_PPP] = (distribution_references.f[DIR_PPP])[k];
+    distribution.f[vf::lbm::dir::DIR_MPP] = (distribution_references.f[DIR_MPP])[kw];
+    distribution.f[vf::lbm::dir::DIR_PMP] = (distribution_references.f[DIR_PMP])[ks];
+    distribution.f[vf::lbm::dir::DIR_MMP] = (distribution_references.f[DIR_MMP])[ksw];
+    distribution.f[vf::lbm::dir::DIR_PPM] = (distribution_references.f[DIR_PPM])[kb];
+    distribution.f[vf::lbm::dir::DIR_MPM] = (distribution_references.f[DIR_MPM])[kbw];
+    distribution.f[vf::lbm::dir::DIR_PMM] = (distribution_references.f[DIR_PMM])[kbs];
+    distribution.f[vf::lbm::dir::DIR_MMM] = (distribution_references.f[DIR_MMM])[kbsw];
+    distribution.f[vf::lbm::dir::DIR_000] = (distribution_references.f[DIR_000])[k];
 }
 
 __device__ void DistributionWrapper::write()
diff --git a/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManager.cpp b/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManager.cpp
index e8fc3f318c920be36be7861a28659124a7b1e977..1c1e65fa34720a1f9d19b5ef02e4afda167b323f 100644
--- a/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManager.cpp
+++ b/src/gpu/VirtualFluids_GPU/KernelManager/BCKernelManager.cpp
@@ -415,7 +415,7 @@ void BCKernelManager::runPrecursorBCKernelPost(int level, uint t, CudaMemoryMana
         para->getParD(level)->precursorBC.current = para->getParD(level)->precursorBC.next;
         para->getParD(level)->precursorBC.next = tmp;
 
-        real loadTime = nextTime*pow(2,-level)*para->getTimeRatio();
+        real loadTime = nextTime*exp2(-level)*para->getTimeRatio();
 
         for(auto reader : para->getParH(level)->transientBCInputFileReader)
         {   
diff --git a/src/gpu/VirtualFluids_GPU/LBM/GPUHelperFunctions/KernelUtilities.h b/src/gpu/VirtualFluids_GPU/LBM/GPUHelperFunctions/KernelUtilities.h
index 5541bc54597ea02c5e3e89d00169b6eb6ff6564b..ebd1b8ab367b31c62fc1608b39215622819d35d9 100644
--- a/src/gpu/VirtualFluids_GPU/LBM/GPUHelperFunctions/KernelUtilities.h
+++ b/src/gpu/VirtualFluids_GPU/LBM/GPUHelperFunctions/KernelUtilities.h
@@ -34,8 +34,11 @@
 #define KERNEL_UTILITIES_H
 
 #include "LBM/LB.h"
-#include "lbm/constants/D3Q27.h"
-#include "basics/constants/NumericConstants.h"
+
+#include <cassert>
+
+#include <lbm/constants/D3Q27.h>
+#include <basics/constants/NumericConstants.h>
 
 using namespace vf::basics::constant;
 using namespace vf::lbm::dir;
@@ -201,6 +204,125 @@ __inline__ __device__ bool isValidFluidNode(uint nodeType)
 }
 
 
+struct ListIndices
+{
+    __device__ ListIndices() {}
+    __device__ ListIndices(unsigned int k, unsigned int* neighborX, unsigned int* neighborY, unsigned int* neighborZ)
+    {
+        k_000 = k;
+        k_M00 = neighborX[k_000];
+        k_0M0 = neighborY[k_000];
+        k_00M = neighborZ[k_000];
+        k_MM0 = neighborY[k_M00];
+        k_M0M = neighborZ[k_M00];
+        k_0MM = neighborZ[k_0M0];
+        k_MMM = neighborZ[k_MM0];
+    }
+
+    unsigned int k_000 { 0 };
+    unsigned int k_M00 { 0 };
+    unsigned int k_0M0 { 0 };
+    unsigned int k_00M { 0 };
+    unsigned int k_MM0 { 0 };
+    unsigned int k_M0M { 0 };
+    unsigned int k_0MM { 0 };
+    unsigned int k_MMM { 0 };
+};
+
+
+////////////////////////////////////////////////////////////////////////////////////
+//! - Read distributions: style of reading and writing the distributions from/to
+//! 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>
+__device__ __inline__ void read(real *f, const Distributions27 &dist, const ListIndices &indices)
+{
+    f[DIR_000] = (dist.f[DIR_000])[indices.k_000];
+    f[DIR_P00] = (dist.f[DIR_P00])[indices.k_000];
+    f[DIR_M00] = (dist.f[DIR_M00])[indices.k_M00];
+    f[DIR_0P0] = (dist.f[DIR_0P0])[indices.k_000];
+    f[DIR_0M0] = (dist.f[DIR_0M0])[indices.k_0M0];
+    f[DIR_00P] = (dist.f[DIR_00P])[indices.k_000];
+    f[DIR_00M] = (dist.f[DIR_00M])[indices.k_00M];
+    f[DIR_PP0] = (dist.f[DIR_PP0])[indices.k_000];
+    f[DIR_MM0] = (dist.f[DIR_MM0])[indices.k_MM0];
+    f[DIR_PM0] = (dist.f[DIR_PM0])[indices.k_0M0];
+    f[DIR_MP0] = (dist.f[DIR_MP0])[indices.k_M00];
+    f[DIR_P0P] = (dist.f[DIR_P0P])[indices.k_000];
+    f[DIR_M0M] = (dist.f[DIR_M0M])[indices.k_M0M];
+    f[DIR_P0M] = (dist.f[DIR_P0M])[indices.k_00M];
+    f[DIR_M0P] = (dist.f[DIR_M0P])[indices.k_M00];
+    f[DIR_0PP] = (dist.f[DIR_0PP])[indices.k_000];
+    f[DIR_0MM] = (dist.f[DIR_0MM])[indices.k_0MM];
+    f[DIR_0PM] = (dist.f[DIR_0PM])[indices.k_00M];
+    f[DIR_0MP] = (dist.f[DIR_0MP])[indices.k_0M0];
+    f[DIR_PPP] = (dist.f[DIR_PPP])[indices.k_000];
+    f[DIR_MPP] = (dist.f[DIR_MPP])[indices.k_M00];
+    f[DIR_PMP] = (dist.f[DIR_PMP])[indices.k_0M0];
+    f[DIR_MMP] = (dist.f[DIR_MMP])[indices.k_MM0];
+    f[DIR_PPM] = (dist.f[DIR_PPM])[indices.k_00M];
+    f[DIR_MPM] = (dist.f[DIR_MPM])[indices.k_M0M];
+    f[DIR_PMM] = (dist.f[DIR_PMM])[indices.k_0MM];
+    f[DIR_MMM] = (dist.f[DIR_MMM])[indices.k_MMM];
+}
+
+__device__ __inline__ void readInverse(real *f, const Distributions27 &dist, const ListIndices &indices)
+{
+    //TODO: https://git.rz.tu-bs.de/irmb/VirtualFluids_dev/-/issues/101
+    assert((false) || !fprintf(stderr, "Not implemented yet.\n")); 
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+//! - Write distributions: style of reading and writing the distributions from/to
+//! 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>
+__inline__ __device__ void write(Distributions27 &destination, const ListIndices &indices, const real* f)
+{
+    (destination.f[DIR_000])[indices.k_000] = f[DIR_000];
+    (destination.f[DIR_P00])[indices.k_000] = f[DIR_P00];
+    (destination.f[DIR_M00])[indices.k_M00] = f[DIR_M00];
+    (destination.f[DIR_0P0])[indices.k_000] = f[DIR_0P0];
+    (destination.f[DIR_0M0])[indices.k_0M0] = f[DIR_0M0];
+    (destination.f[DIR_00P])[indices.k_000] = f[DIR_00P];
+    (destination.f[DIR_00M])[indices.k_00M] = f[DIR_00M];
+    (destination.f[DIR_PP0])[indices.k_000] = f[DIR_PP0];
+    (destination.f[DIR_MM0])[indices.k_MM0] = f[DIR_MM0];
+    (destination.f[DIR_PM0])[indices.k_0M0] = f[DIR_PM0];
+    (destination.f[DIR_MP0])[indices.k_M00] = f[DIR_MP0];
+    (destination.f[DIR_P0P])[indices.k_000] = f[DIR_P0P];
+    (destination.f[DIR_M0M])[indices.k_M0M] = f[DIR_M0M];
+    (destination.f[DIR_P0M])[indices.k_00M] = f[DIR_P0M];
+    (destination.f[DIR_M0P])[indices.k_M00] = f[DIR_M0P];
+    (destination.f[DIR_0PP])[indices.k_000] = f[DIR_0PP];
+    (destination.f[DIR_0MM])[indices.k_0MM] = f[DIR_0MM];
+    (destination.f[DIR_0PM])[indices.k_00M] = f[DIR_0PM];
+    (destination.f[DIR_0MP])[indices.k_0M0] = f[DIR_0MP];
+    (destination.f[DIR_PPP])[indices.k_000] = f[DIR_PPP];
+    (destination.f[DIR_MPP])[indices.k_M00] = f[DIR_MPP];
+    (destination.f[DIR_PMP])[indices.k_0M0] = f[DIR_PMP];
+    (destination.f[DIR_MMP])[indices.k_MM0] = f[DIR_MMP];
+    (destination.f[DIR_PPM])[indices.k_00M] = f[DIR_PPM];
+    (destination.f[DIR_MPM])[indices.k_M0M] = f[DIR_MPM];
+    (destination.f[DIR_PMM])[indices.k_0MM] = f[DIR_PMM];
+    (destination.f[DIR_MMM])[indices.k_MMM] = f[DIR_MMM];
+}
+
+__inline__ __device__ void writeInverse(Distributions27 &destination, const ListIndices &indices, const real* f)
+{
+    //TODO: https://git.rz.tu-bs.de/irmb/VirtualFluids_dev/-/issues/101
+    assert((false) || !fprintf(stderr, "Not implemented yet.\n")); 
+}
+
+
+
+
+__inline__ __device__ real calculateOmega(const real omega_old, real turbulenceViscosity)
+{
+    return omega_old / (c1o1 + c3o1 * omega_old * turbulenceViscosity);
+}
+
 }
 
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/LBM/GPUHelperFunctions/ScalingUtilities.h b/src/gpu/VirtualFluids_GPU/LBM/GPUHelperFunctions/ScalingUtilities.h
index a7c1390c728df1d0ca83424fb7f9f4fb09faba65..606f6b38b4f50ebc621cce23f05c2d54091934f9 100644
--- a/src/gpu/VirtualFluids_GPU/LBM/GPUHelperFunctions/ScalingUtilities.h
+++ b/src/gpu/VirtualFluids_GPU/LBM/GPUHelperFunctions/ScalingUtilities.h
@@ -33,9 +33,15 @@
 #ifndef SCALING_HELPER_FUNCTIONS_H
 #define SCALING_HELPER_FUNCTIONS_H
 
-#include "LBM/LB.h" 
-#include "lbm/constants/D3Q27.h"
-#include "basics/constants/NumericConstants.h"
+#include "LBM/GPUHelperFunctions/KernelUtilities.h"
+
+#include <basics/constants/NumericConstants.h>
+
+#include <lbm/constants/D3Q27.h>
+#include <lbm/KernelParameter.h>
+#include <basics/DataTypes.h>
+
+#include <lbm/refinement/Coefficients.h>
 
 using namespace vf::basics::constant;
 using namespace vf::lbm::dir;
@@ -43,94 +49,196 @@ using namespace vf::lbm::dir;
 namespace vf::gpu
 {
 
-__device__ __inline__ void calculateMomentsOnSourceNodes(Distributions27 &dist, real &omega, unsigned int &k_000,
-                                                         unsigned int &k_M00, unsigned int &k_0M0, unsigned int &k_00M,
-                                                         unsigned int &k_MM0, unsigned int &k_M0M, unsigned int &k_0MM,
-                                                         unsigned int &k_MMM, real &drho, real &velocityX,
-                                                         real &velocityY, real &velocityZ, real &kxyFromfcNEQ,
-                                                         real &kyzFromfcNEQ, real &kxzFromfcNEQ, real &kxxMyyFromfcNEQ,
-                                                         real &kxxMzzFromfcNEQ)
+template<bool hasTurbulentViscosity> __device__ void calculateMomentSet(
+    vf::lbm::MomentsOnSourceNodeSet& momentsSet,
+    const unsigned nodeIndex,
+    real *distribution,
+    unsigned int *neighborX,
+    unsigned int *neighborY,
+    unsigned int *neighborZ,
+    unsigned int *indices_MMM,
+    real* turbulentViscosity,
+    unsigned long long numberOfLBnodes,
+    const real omega,
+    bool isEvenTimestep
+)
 {
-    ////////////////////////////////////////////////////////////////////////////////////
-    //! - Set local distributions (f's) on source nodes:
-    //!
-    real f_000 = (dist.f[DIR_000])[k_000];
-    real f_P00 = (dist.f[DIR_P00])[k_000];
-    real f_M00 = (dist.f[DIR_M00])[k_M00];
-    real f_0P0 = (dist.f[DIR_0P0])[k_000];
-    real f_0M0 = (dist.f[DIR_0M0])[k_0M0];
-    real f_00P = (dist.f[DIR_00P])[k_000];
-    real f_00M = (dist.f[DIR_00M])[k_00M];
-    real f_PP0 = (dist.f[DIR_PP0])[k_000];
-    real f_MM0 = (dist.f[DIR_MM0])[k_MM0];
-    real f_PM0 = (dist.f[DIR_PM0])[k_0M0];
-    real f_MP0 = (dist.f[DIR_MP0])[k_M00];
-    real f_P0P = (dist.f[DIR_P0P])[k_000];
-    real f_M0M = (dist.f[DIR_M0M])[k_M0M];
-    real f_P0M = (dist.f[DIR_P0M])[k_00M];
-    real f_M0P = (dist.f[DIR_M0P])[k_M00];
-    real f_0PP = (dist.f[DIR_0PP])[k_000];
-    real f_0MM = (dist.f[DIR_0MM])[k_0MM];
-    real f_0PM = (dist.f[DIR_0PM])[k_00M];
-    real f_0MP = (dist.f[DIR_0MP])[k_0M0];
-    real f_PPP = (dist.f[DIR_PPP])[k_000];
-    real f_MPP = (dist.f[DIR_MPP])[k_M00];
-    real f_PMP = (dist.f[DIR_PMP])[k_0M0];
-    real f_MMP = (dist.f[DIR_MMP])[k_MM0];
-    real f_PPM = (dist.f[DIR_PPM])[k_00M];
-    real f_MPM = (dist.f[DIR_MPM])[k_M0M];
-    real f_PMM = (dist.f[DIR_PMM])[k_0MM];
-    real f_MMM = (dist.f[DIR_MMM])[k_MMM];
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    //! - 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>
-    //!
-    drho = ((((f_PPP + f_MMM) + (f_MPM + f_PMP)) + ((f_MPP + f_PMM) + (f_MMP + f_PPM))) +
-            (((f_0MP + f_0PM) + (f_0MM + f_0PP)) + ((f_M0P + f_P0M) + (f_M0M + f_P0P)) +
-             ((f_MP0 + f_PM0) + (f_MM0 + f_PP0))) +
-            ((f_M00 + f_P00) + (f_0M0 + f_0P0) + (f_00M + f_00P))) +
-           f_000;
-
-    real oneOverRho = c1o1 / (c1o1 + drho);
-
-    velocityX = ((((f_PPP - f_MMM) + (f_PMP - f_MPM)) + ((f_PMM - f_MPP) + (f_PPM - f_MMP))) +
-                 (((f_P0M - f_M0P) + (f_P0P - f_M0M)) + ((f_PM0 - f_MP0) + (f_PP0 - f_MM0))) + (f_P00 - f_M00)) *
-                oneOverRho;
-    velocityY = ((((f_PPP - f_MMM) + (f_MPM - f_PMP)) + ((f_MPP - f_PMM) + (f_PPM - f_MMP))) +
-                 (((f_0PM - f_0MP) + (f_0PP - f_0MM)) + ((f_MP0 - f_PM0) + (f_PP0 - f_MM0))) + (f_0P0 - f_0M0)) *
-                oneOverRho;
-    velocityZ = ((((f_PPP - f_MMM) + (f_PMP - f_MPM)) + ((f_MPP - f_PMM) + (f_MMP - f_PPM))) +
-                 (((f_0MP - f_0PM) + (f_0PP - f_0MM)) + ((f_M0P - f_P0M) + (f_P0P - f_M0M))) + (f_00P - f_00M)) *
-                oneOverRho;
-
-    ////////////////////////////////////////////////////////////////////////////////////
-    //! - Calculate second order moments for interpolation
+    real omega_ = omega;
+    Distributions27 distFine;
+    getPointersToDistributions(distFine, distribution, numberOfLBnodes, isEvenTimestep);
+
+    ListIndices indices;
+
+    //////////////////////////////////////////////////////////////////////////
+    //! - Calculate moments for each source node 
     //!
-    // example: kxxMzz: moment, second derivative in x direction minus the second derivative in z direction
-    kxyFromfcNEQ = -c3o1 * omega *
-                   ((f_MM0 + f_MMM + f_MMP - f_MP0 - f_MPM - f_MPP - f_PM0 - f_PMM - f_PMP + f_PP0 + f_PPM + f_PPP) /
-                    (c1o1 + drho) -
-                    ((velocityX * velocityY)));
-    kyzFromfcNEQ = -c3o1 * omega *
-                   ((f_0MM + f_PMM + f_MMM - f_0MP - f_PMP - f_MMP - f_0PM - f_PPM - f_MPM + f_0PP + f_PPP + f_MPP) /
-                    (c1o1 + drho) -
-                    ((velocityY * velocityZ)));
-    kxzFromfcNEQ = -c3o1 * omega *
-                   ((f_M0M + f_MMM + f_MPM - f_M0P - f_MMP - f_MPP - f_P0M - f_PMM - f_PPM + f_P0P + f_PMP + f_PPP) /
-                    (c1o1 + drho) -
-                    ((velocityX * velocityZ)));
-    kxxMyyFromfcNEQ = -c3o2 * omega *
-                      ((f_M0M + f_M00 + f_M0P - f_0MM - f_0M0 - f_0MP - f_0PM - f_0P0 - f_0PP + f_P0M + f_P00 + f_P0P) /
-                       (c1o1 + drho) -
-                       ((velocityX * velocityX - velocityY * velocityY)));
-    kxxMzzFromfcNEQ = -c3o2 * omega *
-                      ((f_MM0 + f_M00 + f_MP0 - f_0MM - f_0MP - f_00M - f_00P - f_0PM - f_0PP + f_PM0 + f_P00 + f_PP0) /
-                       (c1o1 + drho) -
-                       ((velocityX * velocityX - velocityZ * velocityZ)));
+    //////////////////////////////////////////////////////////////////////////
+    // source node BSW = MMM
+    //////////////////////////////////////////////////////////////////////////
+    // index of the base node and its neighbors
+    unsigned int k_base_000 = indices_MMM[nodeIndex];
+    unsigned int k_base_M00 = neighborX [k_base_000];
+    unsigned int k_base_0M0 = neighborY [k_base_000];
+    unsigned int k_base_00M = neighborZ [k_base_000];
+    unsigned int k_base_MM0 = neighborY [k_base_M00];
+    unsigned int k_base_M0M = neighborZ [k_base_M00];
+    unsigned int k_base_0MM = neighborZ [k_base_0M0];
+    unsigned int k_base_MMM = neighborZ [k_base_MM0];
+    //////////////////////////////////////////////////////////////////////////
+    // Set neighbor indices
+    indices.k_000 = k_base_000;
+    indices.k_M00 = k_base_M00;
+    indices.k_0M0 = k_base_0M0;
+    indices.k_00M = k_base_00M;
+    indices.k_MM0 = k_base_MM0;
+    indices.k_M0M = k_base_M0M;
+    indices.k_0MM = k_base_0MM;
+    indices.k_MMM = k_base_MMM;
+
+    omega_ = hasTurbulentViscosity ? calculateOmega(omega, turbulentViscosity[indices.k_000]) : omega;
+
+    real f_fine[27];
+
+    read(f_fine, distFine, indices);
+    momentsSet.calculateMMM(f_fine, omega_);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node TSW = MMP
+    //////////////////////////////////////////////////////////////////////////
+    // Set neighbor indices - has to be recalculated for the new source node
+    indices.k_000 = indices.k_00M;
+    indices.k_M00 = indices.k_M0M;
+    indices.k_0M0 = indices.k_0MM;
+    indices.k_00M = neighborZ[indices.k_00M];
+    indices.k_MM0 = indices.k_MMM;
+    indices.k_M0M = neighborZ[indices.k_M0M];
+    indices.k_0MM = neighborZ[indices.k_0MM];
+    indices.k_MMM = neighborZ[indices.k_MMM];
+
+    omega_ = hasTurbulentViscosity ? calculateOmega(omega, turbulentViscosity[indices.k_000]) : omega;
+
+    read(f_fine, distFine, indices);
+    momentsSet.calculateMMP(f_fine, omega_);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node TSE = PMP
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_000 = indices.k_M00;
+    indices.k_M00 = neighborX[indices.k_M00];
+    indices.k_0M0 = indices.k_MM0;
+    indices.k_00M = indices.k_M0M;
+    indices.k_MM0 = neighborX[indices.k_MM0];
+    indices.k_M0M = neighborX[indices.k_M0M];
+    indices.k_0MM = indices.k_MMM;
+    indices.k_MMM = neighborX[indices.k_MMM];
+
+    omega_ = hasTurbulentViscosity ? calculateOmega(omega, turbulentViscosity[indices.k_000]) : omega;
+
+    read(f_fine, distFine, indices);
+    momentsSet.calculatePMP(f_fine, omega_);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node BSE = PMM 
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_00M = indices.k_000;
+    indices.k_M0M = indices.k_M00;
+    indices.k_0MM = indices.k_0M0;
+    indices.k_MMM = indices.k_MM0;
+    indices.k_000 = k_base_M00;
+    indices.k_M00 = neighborX[k_base_M00];
+    indices.k_0M0 = k_base_MM0;
+    indices.k_MM0 = neighborX[k_base_MM0];
+
+    omega_ = hasTurbulentViscosity ? calculateOmega(omega, turbulentViscosity[indices.k_000]) : omega;
+
+    read(f_fine, distFine, indices);
+    momentsSet.calculatePMM(f_fine, omega_);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node BNW = MPM
+    //////////////////////////////////////////////////////////////////////////
+    // index of the base node and its neighbors --> indices of all source nodes
+    k_base_000 = k_base_0M0;
+    k_base_M00 = k_base_MM0;
+    k_base_0M0 = neighborY[k_base_0M0];
+    k_base_00M = k_base_0MM;
+    k_base_MM0 = neighborY[k_base_MM0];
+    k_base_M0M = k_base_MMM;
+    k_base_0MM = neighborY[k_base_0MM];
+    k_base_MMM = neighborY[k_base_MMM];
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_000 = k_base_000;
+    indices.k_M00 = k_base_M00;
+    indices.k_0M0 = k_base_0M0;
+    indices.k_00M = k_base_00M;
+    indices.k_MM0 = k_base_MM0;
+    indices.k_M0M = k_base_M0M;
+    indices.k_0MM = k_base_0MM;
+    indices.k_MMM = k_base_MMM;
+
+    omega_ = hasTurbulentViscosity ? calculateOmega(omega, turbulentViscosity[indices.k_000]) : omega;
+
+    read(f_fine, distFine, indices);
+    momentsSet.calculateMPM(f_fine, omega_);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node TNW = MPP
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_000 = indices.k_00M;
+    indices.k_M00 = indices.k_M0M;
+    indices.k_0M0 = indices.k_0MM;
+    indices.k_00M = neighborZ[indices.k_00M];
+    indices.k_MM0 = indices.k_MMM;
+    indices.k_M0M = neighborZ[indices.k_M0M];
+    indices.k_0MM = neighborZ[indices.k_0MM];
+    indices.k_MMM = neighborZ[indices.k_MMM];
+
+    omega_ = hasTurbulentViscosity ? calculateOmega(omega, turbulentViscosity[indices.k_000]) : omega;
+
+    read(f_fine, distFine, indices);
+    momentsSet.calculateMPP(f_fine, omega_);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node TNE = PPP
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_000 = indices.k_M00;
+    indices.k_M00 = neighborX[indices.k_M00];
+    indices.k_0M0 = indices.k_MM0;
+    indices.k_00M = indices.k_M0M;
+    indices.k_MM0 = neighborX[indices.k_MM0];
+    indices.k_M0M = neighborX[indices.k_M0M];
+    indices.k_0MM = indices.k_MMM;
+    indices.k_MMM = neighborX[indices.k_MMM];
+
+    omega_ = hasTurbulentViscosity ? calculateOmega(omega, turbulentViscosity[indices.k_000]) : omega;
+
+    read(f_fine, distFine, indices);
+    momentsSet.calculatePPP(f_fine, omega_);
+
+    //////////////////////////////////////////////////////////////////////////
+    // source node BNE = PPM
+    //////////////////////////////////////////////////////////////////////////
+    // index
+    indices.k_00M = indices.k_000;
+    indices.k_M0M = indices.k_M00;
+    indices.k_0MM = indices.k_0M0;
+    indices.k_MMM = indices.k_MM0;
+    indices.k_000 = k_base_M00;
+    indices.k_M00 = neighborX[k_base_M00];
+    indices.k_0M0 = k_base_MM0;
+    indices.k_MM0 = neighborX[k_base_MM0];
+    
+    omega_ = hasTurbulentViscosity ? calculateOmega(omega, turbulentViscosity[indices.k_000]) : omega;
+
+    read(f_fine, distFine, indices);
+    momentsSet.calculatePPM(f_fine, omega_);
 }
 
-} // namespace vf::gpu
+}
 
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/LBM/LB.h b/src/gpu/VirtualFluids_GPU/LBM/LB.h
index a5ae5f5ceef213e8ec9b2306106035a09b1ffd0d..5da2a2a82c59d9a70e26849d4ee413b7c6e8f1d3 100644
--- a/src/gpu/VirtualFluids_GPU/LBM/LB.h
+++ b/src/gpu/VirtualFluids_GPU/LBM/LB.h
@@ -107,47 +107,59 @@ constexpr std::initializer_list<CollisionTemplate> bulk_CollisionTemplate = { Co
 
 //Interface Cells
 // example of old names (pre 2023) ICellCFC: interpolation from Coarse (C) to Fine (F), indices of the Coarse cells (C)
-typedef struct ICells{
+struct ICells
+{
    uint* fineCellIndices;
    uint* coarseCellIndices;
    uint numberOfCells;
-} InterpolationCells;
+};
+
+using InterpolationCells = ICells;
 
 //! \brief stores location of neighboring cell (necessary for refinement into the wall)
-typedef struct ICellNeigh{
+struct ICellNeigh
+{
    real* x;
    real* y;
    real* z;
-} InterpolationCellNeighbor;
+};
 
-// Distribution functions g 6
-typedef struct  Distri6 { // ADD IN FUTURE RELEASE
+using InterpolationCellNeighbor = ICellNeigh;
+
+// ADD IN FUTURE RELEASE
+struct Distributions6 
+{
    real* g[6];
-} Distributions6;
+};
 
-// Distribution functions f 7
-typedef struct  Distri7{ // ADD IN FUTURE RELEASE
+// ADD IN FUTURE RELEASE
+struct  Distributions7
+{
    real* f[7];
-} Distributions7;
+};
 
-// Distribution functions f 19
-typedef struct  Distri19{ // DEPRECATED
+// DEPRECATED
+struct  Distributions19
+{
    real* f[19];
-} Distributions19;
+};
 
-// Distribution functions f 27
-typedef struct  Distri27{
+struct  Distributions27
+{
    real* f[27];
-} Distributions27, DistributionReferences27;
+};
 
-// Subgrid distances q 27
-typedef struct SubgridDist27{
+using DistributionReferences27 = Distributions27;
+
+struct SubgridDistances27
+{
    real* q[27];
-} SubgridDistances27;
+};
 
 //Q for second order BCs
 //! \struct to manage sub-grid-distances (q) for second order Boundary Conditions (BCs)
-typedef struct QforBC{
+struct QforBoundaryConditions
+{
    int* k;
    int* kN;
    long long* valueQ;
@@ -160,13 +172,15 @@ typedef struct QforBC{
    real *Vx1,     *Vy1,     *Vz1;
    real *deltaVz, *RhoBC;
    real *normalX, *normalY, *normalZ;
-}QforBoundaryConditions;
+};
 
-typedef struct QforPrecursorBC{
+struct QforPrecursorBoundaryConditions
+{
    int* k;
    int numberOfBCnodes=0;
    int sizeQ;
    int numberOfPrecursorNodes=0;
+   uint streamIndex=0;
    uint nPrecursorReads=0;
    uint timeStepsBetweenReads;
    size_t numberOfQuantities;
@@ -175,34 +189,38 @@ typedef struct QforPrecursorBC{
    real* weights0PP, *weights0PM, *weights0MP,  *weights0MM;
    real* last, *current, *next;
    real velocityX, velocityY, velocityZ;
-}QforPrecursorBoundaryConditions;
+};
 
-//BCTemp
-typedef struct TempforBC{  // ADD IN FUTURE RELEASE
+// ADD IN FUTURE RELEASE
+struct TempforBoundaryConditions
+{
    int* k;
    real* temp;
    int kTemp=0;
-}TempforBoundaryConditions;
+};
 
-//BCTempVel
-typedef struct TempVelforBC{  // ADD IN FUTURE RELEASE
+// ADD IN FUTURE RELEASE
+struct TempVelforBoundaryConditions
+{
    int* k;
    real* temp;
    real* tempPulse;
    real* velo;
    int kTemp=0;
-}TempVelforBoundaryConditions;
+};
 
-//BCTempPress
-typedef struct TempPressforBC{  // ADD IN FUTURE RELEASE
+// ADD IN FUTURE RELEASE
+struct TempPressforBoundaryConditions
+{
    int* k;
    real* temp;
    real* velo;
    int kTemp=0;
-}TempPressforBoundaryConditions;
+};
 
 // Settings for wall model used in StressBC
-typedef struct WMparas{
+struct WallModelParameters
+{
    real* z0;
    int* samplingOffset;
    bool hasMonitor;
@@ -210,11 +228,12 @@ typedef struct WMparas{
    real* Fx;
    real* Fy;
    real* Fz;
-}WallModelParameters;
+};
 
 
-//measurePoints
-typedef struct MeasP{ // ADD IN FUTURE RELEASE
+// ADD IN FUTURE RELEASE
+struct MeasurePoints
+{
    std::string name;
    uint k;
    std::vector<real> Vx;
@@ -225,10 +244,11 @@ typedef struct MeasP{ // ADD IN FUTURE RELEASE
    //real* Vy;
    //real* Vz;
    //real* Rho;
-}MeasurePoints;
+};
+
 
-//Process Neighbors
-typedef struct PN27{
+struct ProcessNeighbor27
+{
    real* f[27];
    uint memsizeFs;
    int* index;
@@ -236,9 +256,11 @@ typedef struct PN27{
    uint rankNeighbor;
    int numberOfNodes;
    int numberOfFs;
-}ProcessNeighbor27;
+};
 
-typedef struct PN_F3 { // ADD IN FUTURE RELEASE
+// ADD IN FUTURE RELEASE
+struct ProcessNeighborF3
+{
    real* g[6];
    uint memsizeGs;
    int* index;
@@ -246,10 +268,11 @@ typedef struct PN_F3 { // ADD IN FUTURE RELEASE
    uint rankNeighbor;
    int numberOfNodes;
    int numberOfGs;
-}ProcessNeighborF3;
+};
 
-//path line particles // DEPRECATED
-typedef struct PLP{
+// DEPRECATED
+struct PathLineParticles
+{
    bool *stuck, *hot;
    real *coordXabsolut, *coordYabsolut, *coordZabsolut;
    real *coordXlocal,   *coordYlocal,   *coordZlocal;
@@ -260,13 +283,12 @@ typedef struct PLP{
    uint *cellBaseID;
    uint numberOfParticles, numberOfTimestepsParticles;
    uint memSizeID, memSizeTimestep, memSizerealAll, memSizereal, memSizeBool, memSizeBoolBC;
-}PathLineParticles;
+};
 
 //////////////////////////////////////////////////////////////////////////
 // DEPRECATED
-inline int vectorPosition(int i, int j, int k, int Lx, int Ly )
+inline int vectorPosition(int i, int j, int k, int Lx, int Ly)
 {
-   //return((j+15)*(Lx+2*16)+(i+15));
    return((Lx+2*STARTOFFX)*((Ly+2*STARTOFFY)*(k+STARTOFFZ)+(j+STARTOFFY))+(i+STARTOFFX));
 }
 //////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp b/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp
index 55c0250223901a94d03bd1e65bbb72438bcc99c3..dddc795ccda96b49a03373c05a701f32662e9565 100644
--- a/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp
+++ b/src/gpu/VirtualFluids_GPU/LBM/Simulation.cpp
@@ -139,9 +139,8 @@ void Simulation::init(GridProvider &gridProvider, BoundaryConditionFactory *bcFa
     //////////////////////////////////////////////////////////////////////////
     // CUDA streams
     if (para->getUseStreams()) {
-        para->getStreamManager()->registerStream(CudaStreamIndex::SubDomainBorder);
-        para->getStreamManager()->registerStream(CudaStreamIndex::Bulk);
-        para->getStreamManager()->launchStreams();
+        para->getStreamManager()->registerAndLaunchStream(CudaStreamIndex::SubDomainBorder);
+        para->getStreamManager()->registerAndLaunchStream(CudaStreamIndex::Bulk);
         para->getStreamManager()->createCudaEvents();
     }
     //////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/VirtualFluids_GPU/Output/FileWriter.cpp b/src/gpu/VirtualFluids_GPU/Output/FileWriter.cpp
index cb8cefa389c141b7f38bbc54a68d8cf9841ba699..e28c802429c1703314c59402e2d4d490388b8ce1 100644
--- a/src/gpu/VirtualFluids_GPU/Output/FileWriter.cpp
+++ b/src/gpu/VirtualFluids_GPU/Output/FileWriter.cpp
@@ -8,7 +8,7 @@
 #include "FileWriter.h"
 #include <logger/Logger.h>
 
-#include <stdio.h>
+#include <cstdio>
 #include <fstream>
 #include <sstream>
 #include <cmath>
@@ -23,6 +23,37 @@
 
 #include <basics/writer/WbWriterVtkXmlBinary.h>
 
+std::string makePartFileNameEnding(int level, int ID, int part, int timestep)
+{
+    return "_lev_" + StringUtil::toString<int>(level) + "_ID_" + StringUtil::toString<int>(ID) + "_Part_" + StringUtil::toString<int>(part) + "_t_" + StringUtil::toString<int>(timestep) + ".vtk";
+}
+
+std::string makeCollectionFileNameEnding(int ID, int timestep)
+{
+    return "_ID_" + StringUtil::toString<int>(ID) + "_t_" + StringUtil::toString<int>(timestep) + ".vtk";
+}
+
+std::string makePartFileName(const std::string &prefix, int level, int ID, int part, int timestep)
+{
+    return prefix + "_bin" + makePartFileNameEnding(level, ID, part, timestep);
+}
+
+std::string makeMedianPartFileName(const std::string &prefix, int level, int ID, int part, int timestep)
+{
+    return prefix + "_bin_median" + makePartFileNameEnding(level, ID, part, timestep);
+}
+
+
+std::string makeCollectionFileName(const std::string &prefix, int ID, int timestep)
+{
+    return prefix + "_bin" + makeCollectionFileNameEnding(ID, timestep);
+}
+
+std::string makeMedianCollectionFileName(const std::string &prefix, int ID, int timestep)
+{
+    return prefix + "_bin_median" + makeCollectionFileNameEnding(ID, timestep);
+}
+
 void FileWriter::writeInit(std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager)
 {
     unsigned int timestep = para->getTimestepInit();
@@ -50,30 +81,29 @@ void FileWriter::writeTimestep(std::shared_ptr<Parameter> para, unsigned int tim
 
 void FileWriter::writeTimestep(std::shared_ptr<Parameter> para, unsigned int timestep, int level)
 {
-    const unsigned int numberOfParts = (uint)para->getParH(level)->numberOfNodes / para->getlimitOfNodesForVTK() + 1;
-    std::vector<std::string> fname;
-    std::vector<std::string> fnameMed;
+    const unsigned int numberOfParts = (uint)para->getParH(level)->numberOfNodes / para->getLimitOfNodesForVTK() + 1;
+    std::vector<std::string> fnames;
+    std::vector<std::string> fnamesMed;
 
     for (unsigned int i = 1; i <= numberOfParts; i++)
     {
-        fname.push_back(para->getFName() + "_bin_lev_" + StringUtil::toString<int>(level) + "_ID_" + StringUtil::toString<int>(para->getMyProcessID()) + "_Part_" + StringUtil::toString<int>(i) + "_t_" + StringUtil::toString<int>(timestep) + ".vtk");
-        fnameMed.push_back(para->getFName() + "_bin_median_lev_" + StringUtil::toString<int>(level) + "_ID_" + StringUtil::toString<int>(para->getMyProcessID()) + "_Part_" + StringUtil::toString<int>(i) + "_t_" + StringUtil::toString<int>(timestep) + ".vtk");
+        std::string fname = makePartFileName(para->getFName(), level, para->getMyProcessID(), i, timestep); 
+        std::string fnameMed = makeMedianPartFileName(para->getFName(), level, para->getMyProcessID(), i, timestep); 
 
-        this->fileNamesForCollectionFile.push_back( fname.back() );
-        this->fileNamesForCollectionFileMedian.push_back( fnameMed.back() );
+        fnames.push_back(fname);
+        fnamesMed.push_back(fnameMed);
     }
 
-    if (para->getDiffOn() == true)
-        writeUnstrucuredGridLTConc(para, level, fname);
-    else
-        writeUnstrucuredGridLT(para, level, fname);
+    std::vector<std::string> fnamesLong = writeUnstructuredGridLT(para, level, fnames);
+    for(auto fname : fnamesLong)
+        this->fileNamesForCollectionFile.push_back(fname.substr( fname.find_last_of('/') + 1 ));
+
 
     if (para->getCalcMedian())
     {
-        if (para->getDiffOn() == true)
-            writeUnstrucuredGridMedianLTConc(para, level, fnameMed);
-        else
-            writeUnstrucuredGridMedianLT(para, level, fnameMed);
+        std::vector<std::string> fnamesMedianLong = writeUnstructuredGridMedianLT(para, level, fnamesMed);
+        for(auto fname : fnamesMedianLong)
+            this->fileNamesForCollectionFileMedian.push_back(fname.substr( fname.find_last_of('/') + 1 ));
     }
 }
 
@@ -84,194 +114,169 @@ bool FileWriter::isPeriodicCell(std::shared_ptr<Parameter> para, int level, unsi
            (para->getParH(level)->coordinateZ[number5] < para->getParH(level)->coordinateZ[number1]);
 }
 
-void VIRTUALFLUIDS_GPU_EXPORT FileWriter::writeCollectionFile(std::shared_ptr<Parameter> para, unsigned int timestep)
+std::vector<std::string> FileWriter::getNodeDataNames(std::shared_ptr<Parameter> para)
 {
 
-    std::string filename = para->getFName() + "_bin_ID_" + StringUtil::toString<int>(para->getMyProcessID()) + "_t_" + StringUtil::toString<int>(timestep) + ".vtk";
-
-    std::ofstream file;
-
-    file.open( filename + ".pvtu" );
-
-    //////////////////////////////////////////////////////////////////////////
-    file << "<?xml version=\"1.0\"?>" << std::endl;
-    file << "<VTKFile type=\"PUnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" << std::endl;
-    file << "  <PUnstructuredGrid GhostLevel=\"1\">" << std::endl;
+    std::vector<std::string> nodeDataNames;
+    nodeDataNames.push_back("press");
+    nodeDataNames.push_back("rho");
+    nodeDataNames.push_back("vx1");
+    nodeDataNames.push_back("vx2");
+    nodeDataNames.push_back("vx3");
+    nodeDataNames.push_back("geo");
 
-    file << "    <PPointData>" << std::endl;
-    file << "       <PDataArray type=\"Float64\" Name=\"press\" /> " << std::endl;
-    file << "       <PDataArray type=\"Float64\" Name=\"rho\"   /> " << std::endl;
-    file << "       <PDataArray type=\"Float64\" Name=\"vx1\"   /> " << std::endl;
-    file << "       <PDataArray type=\"Float64\" Name=\"vx2\"   /> " << std::endl;
-    file << "       <PDataArray type=\"Float64\" Name=\"vx3\"   /> " << std::endl;
-    file << "       <PDataArray type=\"Float64\" Name=\"geo\"   /> " << std::endl;
-    if( para->getDiffOn() ) file << "       <PDataArray type=\"Float64\" Name=\"conc\"  /> " << std::endl;
-    file << "    </PPointData>" << std::endl;
+    if(para->getDiffOn()) 
+        nodeDataNames.push_back("conc");
 
-    file << "    <PPoints>" << std::endl;
-    file << "      <PDataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\"/>" << std::endl;
-    file << "    </PPoints>" << std::endl;
-
-    for( auto& fname : this->fileNamesForCollectionFile )
+    if(para->getIsBodyForce())
     {
-        const auto filenameWithoutPath=fname.substr( fname.find_last_of('/') + 1 );
-        file << "    <Piece Source=\"" << filenameWithoutPath << ".bin.vtu\"/>" << std::endl;
+        nodeDataNames.push_back("Fx");
+        nodeDataNames.push_back("Fy");
+        nodeDataNames.push_back("Fz");
     }
 
-    file << "  </PUnstructuredGrid>" << std::endl;
-    file << "</VTKFile>" << std::endl;
+    if(para->getUseTurbulentViscosity())
+    {
+        nodeDataNames.push_back("nut");
+    }
 
-    //////////////////////////////////////////////////////////////////////////
+    if (para->getCalcTurbulenceIntensity()) {
+        nodeDataNames.push_back("vxx");
+        nodeDataNames.push_back("vyy");
+        nodeDataNames.push_back("vzz");
+        nodeDataNames.push_back("vxy");
+        nodeDataNames.push_back("vxz");
+        nodeDataNames.push_back("vyz");
+    }
+    return nodeDataNames;
+}
 
-    file.close();
+std::vector<std::string> FileWriter::getMedianNodeDataNames(std::shared_ptr<Parameter> para)
+{
+    std::vector<std::string> nodeDataNames;
+    
+    if(para->getDiffOn()) 
+        nodeDataNames.push_back("conc");
+    nodeDataNames.push_back("pressMed");
+    nodeDataNames.push_back("rhoMed");
+    nodeDataNames.push_back("vx1Med");
+    nodeDataNames.push_back("vx2Med");
+    nodeDataNames.push_back("vx3Med");
+    nodeDataNames.push_back("geo");
+
+    return nodeDataNames;
+}
 
+std::string VIRTUALFLUIDS_GPU_EXPORT FileWriter::writeCollectionFile(std::shared_ptr<Parameter> para, unsigned int timestep)
+{
+    std::string filename = makeCollectionFileName(para->getFName(), para->getMyProcessID(), timestep);
+    auto nodeDataNames = this->getNodeDataNames(para);
+    std::vector<std::string> cellDataNames;
+    std::string pFileName= WbWriterVtkXmlBinary::getInstance()->writeParallelFile(filename, this->fileNamesForCollectionFile, nodeDataNames, cellDataNames);
     this->fileNamesForCollectionFile.clear();
+    return pFileName;
 }
 
-void VIRTUALFLUIDS_GPU_EXPORT FileWriter::writeCollectionFileMedian(std::shared_ptr<Parameter> para, unsigned int timestep)
+std::string VIRTUALFLUIDS_GPU_EXPORT FileWriter::writeCollectionFileMedian(std::shared_ptr<Parameter> para, unsigned int timestep)
 {
-
-    std::string filename = para->getFName() + "_bin_median_ID_" + StringUtil::toString<int>(para->getMyProcessID()) + "_t_" + StringUtil::toString<int>(timestep) + ".vtk";
-
-    std::ofstream file;
-
-    file.open( filename + ".pvtu" );
-
-    //////////////////////////////////////////////////////////////////////////
-
-    file << "<VTKFile type=\"PUnstructuredGrid\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">" << std::endl;
-    file << "  <PUnstructuredGrid GhostLevel=\"1\">" << std::endl;
-
-    file << "    <PPointData>" << std::endl;
-    if( para->getDiffOn() ) file << "       <DataArray type=\"Float32\" Name=\"concMed\"  /> " << std::endl;
-    file << "       <DataArray type=\"Float32\" Name=\"pressMed\" /> " << std::endl;
-    file << "       <DataArray type=\"Float32\" Name=\"rhoMed\"   /> " << std::endl;
-    file << "       <DataArray type=\"Float32\" Name=\"vx1Med\"   /> " << std::endl;
-    file << "       <DataArray type=\"Float32\" Name=\"vx2Med\"   /> " << std::endl;
-    file << "       <DataArray type=\"Float32\" Name=\"vx3Med\"   /> " << std::endl;
-    file << "       <DataArray type=\"Float32\" Name=\"geo\"   /> " << std::endl;
-    file << "    </PPointData>" << std::endl;
-
-    file << "    <PPoints>" << std::endl;
-    file << "      <PDataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\"/>" << std::endl;
-    file << "    </PPoints>" << std::endl;
-
-    for( auto& fname : this->fileNamesForCollectionFileMedian )
-    {
-        const auto filenameWithoutPath=fname.substr( fname.find_last_of('/') + 1 );
-        file << "    <Piece Source=\"" << filenameWithoutPath << ".bin.vtu\"/>" << std::endl;
-    }
-
-    file << "  </PUnstructuredGrid>" << std::endl;
-    file << "</VTKFile>" << std::endl;
-
-    //////////////////////////////////////////////////////////////////////////
-
-    file.close();
-
+    std::string filename = makeMedianCollectionFileName(para->getFName(), para->getMyProcessID(), timestep);
+    std::vector<std::string> nodeDataNames = getMedianNodeDataNames(para);
+    std::vector<std::string> cellDataNames;
+    std::string pFileName =  WbWriterVtkXmlBinary::getInstance()->writeParallelFile(filename, this->fileNamesForCollectionFileMedian, nodeDataNames, cellDataNames);
     this->fileNamesForCollectionFileMedian.clear();
+    return pFileName;
 }
 
-void FileWriter::writeUnstrucuredGridLT(std::shared_ptr<Parameter> para, int level, std::vector<std::string >& fname)
+std::vector<std::string> FileWriter::writeUnstructuredGridLT(std::shared_ptr<Parameter> para, int level, std::vector<std::string >& fname)
 {
     std::vector< UbTupleFloat3 > nodes;
     std::vector< UbTupleUInt8 > cells;
-    std::vector< std::string > nodedatanames;
-    nodedatanames.push_back("press");
-    nodedatanames.push_back("rho");
-    nodedatanames.push_back("vx1");
-    nodedatanames.push_back("vx2");
-    nodedatanames.push_back("vx3");
-    nodedatanames.push_back("geo");
+    std::vector< std::string > nodeDataNames = getNodeDataNames(para);
+
+    std::vector< std::string > outFNames;
+
+    uint dataIndex = 6;
+
+    uint firstConcNode = dataIndex;
+    if(para->getDiffOn()) dataIndex++;
     
-    uint firstBodyForceNode = (uint) nodedatanames.size();
-    if(para->getIsBodyForce())
-    {
-        nodedatanames.push_back("Fx");
-        nodedatanames.push_back("Fy");
-        nodedatanames.push_back("Fz");
-    }
+    uint firstBodyForceNode = dataIndex;
+    if(para->getIsBodyForce()) dataIndex+=3;
 
-    uint firstNutNode = (uint) nodedatanames.size();
-    if(para->getUseTurbulentViscosity())
-    {
-        nodedatanames.push_back("nut");
-    }
+    uint firstNutNode = dataIndex;
+    if(para->getUseTurbulentViscosity()) dataIndex++;
 
-    uint firstTurbNode = (uint) nodedatanames.size();
-    if (para->getCalcTurbulenceIntensity()) {
-        nodedatanames.push_back("vxx");
-        nodedatanames.push_back("vyy");
-        nodedatanames.push_back("vzz");
-        nodedatanames.push_back("vxy");
-        nodedatanames.push_back("vxz");
-        nodedatanames.push_back("vyz");
-    }
+    uint firstTurbulenceNode = dataIndex;
+    if (para->getCalcTurbulenceIntensity()) dataIndex += 6;
     unsigned int number1, number2, number3, number4, number5, number6, number7, number8;
     uint dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8;
     bool neighborsAreFluid;
-    unsigned int startpos = 0;
-    unsigned int endpos = 0;
-    unsigned int sizeOfNodes = 0;
-    std::vector< std::vector< double > > nodedata(nodedatanames.size());
+    unsigned int startPosition;
+    unsigned int endPosition;
+    unsigned int sizeOfNodes;
+    std::vector< std::vector< double > > nodeData(nodeDataNames.size());
 
     for (unsigned int part = 0; part < fname.size(); part++)
     {
-        if (((part + 1)*para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-            sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+        if (((part + 1)*para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+            sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
         else
-            sizeOfNodes = para->getlimitOfNodesForVTK();
+            sizeOfNodes = para->getLimitOfNodesForVTK();
 
         //////////////////////////////////////////////////////////////////////////
-        startpos = part * para->getlimitOfNodesForVTK();
-        endpos = startpos + sizeOfNodes;
+        startPosition = part * para->getLimitOfNodesForVTK();
+        endPosition = startPosition + sizeOfNodes;
         //////////////////////////////////////////////////////////////////////////
         cells.clear();
         nodes.resize(sizeOfNodes);
-        for (uint i = 0; i < (uint)nodedatanames.size(); i++)
-            nodedata[i].resize(sizeOfNodes);
+        for (uint i = 0; i < (uint)nodeDataNames.size(); i++)
+            nodeData[i].resize(sizeOfNodes);
 
         //////////////////////////////////////////////////////////////////////////
-        for (unsigned int pos = startpos; pos < endpos; pos++)
+        for (unsigned int pos = startPosition; pos < endPosition; pos++)
         {
             if (para->getParH(level)->typeOfGridNode[pos] == GEO_FLUID)
             {
+
                 //////////////////////////////////////////////////////////////////////////
                 double x1 = para->getParH(level)->coordinateX[pos];
                 double x2 = para->getParH(level)->coordinateY[pos];
                 double x3 = para->getParH(level)->coordinateZ[pos];
                 //////////////////////////////////////////////////////////////////////////
                 number1 = pos;
-                dn1 = pos - startpos;
+                dn1 = pos - startPosition;
                 neighborsAreFluid = true;
                 //////////////////////////////////////////////////////////////////////////
                 nodes[dn1] = (makeUbTuple((float)(x1), (float)(x2), (float)(x3)));
-                nodedata[0][dn1] = (double)para->getParH(level)->pressure[pos] / (double)3.0 * (double)para->getDensityRatio() * (double)para->getVelocityRatio() * (double)para->getVelocityRatio();
-                nodedata[1][dn1] = (double)para->getParH(level)->rho[pos] / (double)3.0 * (double)para->getDensityRatio() * (double)para->getVelocityRatio() * (double)para->getVelocityRatio();
-                nodedata[2][dn1] = (double)para->getParH(level)->velocityX[pos] * (double)para->getVelocityRatio();
-                nodedata[3][dn1] = (double)para->getParH(level)->velocityY[pos] * (double)para->getVelocityRatio();
-                nodedata[4][dn1] = (double)para->getParH(level)->velocityZ[pos] * (double)para->getVelocityRatio();
-                nodedata[5][dn1] = (double)para->getParH(level)->typeOfGridNode[pos];
+                nodeData[0][dn1] = (double)para->getParH(level)->pressure[pos] / (double)3.0 * (double)para->getDensityRatio() * (double)para->getVelocityRatio() * (double)para->getVelocityRatio();
+                nodeData[1][dn1] = (double)para->getParH(level)->rho[pos] / (double)3.0 * (double)para->getDensityRatio() * (double)para->getVelocityRatio() * (double)para->getVelocityRatio();
+                nodeData[2][dn1] = (double)para->getParH(level)->velocityX[pos] * (double)para->getVelocityRatio();
+                nodeData[3][dn1] = (double)para->getParH(level)->velocityY[pos] * (double)para->getVelocityRatio();
+                nodeData[4][dn1] = (double)para->getParH(level)->velocityZ[pos] * (double)para->getVelocityRatio();
+                nodeData[5][dn1] = (double)para->getParH(level)->typeOfGridNode[pos];
+
+                if(para->getDiffOn())
+                    nodeData[firstConcNode][dn1] = (double)para->getParH(level)->concentration[pos];
 
                 if(para->getIsBodyForce())
                 {
-                    nodedata[firstBodyForceNode    ][dn1] = (double)para->getParH(level)->forceX_SP[pos] * (double)para->getScaledForceRatio(level);
-                    nodedata[firstBodyForceNode + 1][dn1] = (double)para->getParH(level)->forceY_SP[pos] * (double)para->getScaledForceRatio(level);
-                    nodedata[firstBodyForceNode + 2][dn1] = (double)para->getParH(level)->forceZ_SP[pos] * (double)para->getScaledForceRatio(level);
+                    nodeData[firstBodyForceNode    ][dn1] = (double)para->getParH(level)->forceX_SP[pos] * (double)para->getScaledForceRatio(level);
+                    nodeData[firstBodyForceNode + 1][dn1] = (double)para->getParH(level)->forceY_SP[pos] * (double)para->getScaledForceRatio(level);
+                    nodeData[firstBodyForceNode + 2][dn1] = (double)para->getParH(level)->forceZ_SP[pos] * (double)para->getScaledForceRatio(level);
                 }
 
                 if(para->getUseTurbulentViscosity())
                 {
-                    nodedata[firstNutNode][dn1] = (double)para->getParH(level)->turbViscosity[pos] * (double)para->getScaledViscosityRatio(level);
+                    nodeData[firstNutNode][dn1] = (double)para->getParH(level)->turbViscosity[pos] * (double)para->getScaledViscosityRatio(level);
                 }
 
                 if (para->getCalcTurbulenceIntensity()) {
-                    nodedata[firstTurbNode    ][dn1] = (double)para->getParH(level)->vxx[pos];
-                    nodedata[firstTurbNode + 1][dn1] = (double)para->getParH(level)->vyy[pos];
-                    nodedata[firstTurbNode + 2][dn1] = (double)para->getParH(level)->vzz[pos];
-                    nodedata[firstTurbNode + 3][dn1] = (double)para->getParH(level)->vxy[pos];
-                    nodedata[firstTurbNode + 4][dn1] = (double)para->getParH(level)->vxz[pos];
-                    nodedata[firstTurbNode + 5][dn1] = (double)para->getParH(level)->vyz[pos];
+                    nodeData[firstTurbulenceNode    ][dn1] = (double)para->getParH(level)->vxx[pos];
+                    nodeData[firstTurbulenceNode + 1][dn1] = (double)para->getParH(level)->vyy[pos];
+                    nodeData[firstTurbulenceNode + 2][dn1] = (double)para->getParH(level)->vzz[pos];
+                    nodeData[firstTurbulenceNode + 3][dn1] = (double)para->getParH(level)->vxy[pos];
+                    nodeData[firstTurbulenceNode + 4][dn1] = (double)para->getParH(level)->vxz[pos];
+                    nodeData[firstTurbulenceNode + 5][dn1] = (double)para->getParH(level)->vyz[pos];
                 }
 
                 //////////////////////////////////////////////////////////////////////////
@@ -291,21 +296,21 @@ void FileWriter::writeUnstrucuredGridLT(std::shared_ptr<Parameter> para, int lev
                     para->getParH(level)->typeOfGridNode[number7] != GEO_FLUID ||
                     para->getParH(level)->typeOfGridNode[number8] != GEO_FLUID)  neighborsAreFluid = false;
                 //////////////////////////////////////////////////////////////////////////
-                if (number2 > endpos ||
-                    number3 > endpos ||
-                    number4 > endpos ||
-                    number5 > endpos ||
-                    number6 > endpos ||
-                    number7 > endpos ||
-                    number8 > endpos)  neighborsAreFluid = false;
-                //////////////////////////////////////////////////////////////////////////
-                dn2 = number2 - startpos;
-                dn3 = number3 - startpos;
-                dn4 = number4 - startpos;
-                dn5 = number5 - startpos;
-                dn6 = number6 - startpos;
-                dn7 = number7 - startpos;
-                dn8 = number8 - startpos;
+                if (number2 > endPosition ||
+                    number3 > endPosition ||
+                    number4 > endPosition ||
+                    number5 > endPosition ||
+                    number6 > endPosition ||
+                    number7 > endPosition ||
+                    number8 > endPosition)  neighborsAreFluid = false;
+                //////////////////////////////////////////////////////////////////////////
+                dn2 = number2 - startPosition;
+                dn3 = number3 - startPosition;
+                dn4 = number4 - startPosition;
+                dn5 = number5 - startPosition;
+                dn6 = number6 - startPosition;
+                dn7 = number7 - startPosition;
+                dn8 = number8 - startPosition;
                 //////////////////////////////////////////////////////////////////////////
                 if (isPeriodicCell(para, level, number2, number1, number3, number5))
                     continue;
@@ -314,164 +319,53 @@ void FileWriter::writeUnstrucuredGridLT(std::shared_ptr<Parameter> para, int lev
                     cells.push_back(makeUbTuple(dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8));
             }
         }
-        WbWriterVtkXmlBinary::getInstance()->writeOctsWithNodeData(fname[part], nodes, cells, nodedatanames, nodedata);
+        outFNames.push_back( WbWriterVtkXmlBinary::getInstance()->writeOctsWithNodeData(fname[part], nodes, cells, nodeDataNames, nodeData) );
     }
+    return outFNames;
 }
 
-void FileWriter::writeUnstrucuredGridLTConc(std::shared_ptr<Parameter> para, int level, std::vector<std::string >& fname)
+std::vector<std::string> FileWriter::writeUnstructuredGridMedianLT(std::shared_ptr<Parameter> para, int level, std::vector<std::string >& fname)
 {
-    std::vector< UbTupleFloat3 > nodes;
-    std::vector< UbTupleUInt8 > cells;
-    std::vector< std::string > nodedatanames;
-    nodedatanames.push_back("press");
-    nodedatanames.push_back("rho");
-    nodedatanames.push_back("vx1");
-    nodedatanames.push_back("vx2");
-    nodedatanames.push_back("vx3");
-    nodedatanames.push_back("geo");
-    nodedatanames.push_back("conc");
-    unsigned int number1, number2, number3, number4, number5, number6, number7, number8;
-    uint dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8;
-    bool neighborsAreFluid;
-    unsigned int startpos = 0;
-    unsigned int endpos = 0;
-    unsigned int sizeOfNodes = 0;
-    std::vector< std::vector< double > > nodedata(nodedatanames.size());
+    std::vector< std::string > outFNames;
 
-    for (unsigned int part = 0; part < fname.size(); part++)
-    {
-        if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-            sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
-        else
-            sizeOfNodes = para->getlimitOfNodesForVTK();
-
-        //////////////////////////////////////////////////////////////////////////
-        startpos = part * para->getlimitOfNodesForVTK();
-        endpos = startpos + sizeOfNodes;
-        //////////////////////////////////////////////////////////////////////////
-        cells.clear();
-        nodes.resize(sizeOfNodes);
-        nodedata[0].resize(sizeOfNodes);
-        nodedata[1].resize(sizeOfNodes);
-        nodedata[2].resize(sizeOfNodes);
-        nodedata[3].resize(sizeOfNodes);
-        nodedata[4].resize(sizeOfNodes);
-        nodedata[5].resize(sizeOfNodes);
-        nodedata[6].resize(sizeOfNodes);
-        //////////////////////////////////////////////////////////////////////////
-        for (unsigned int pos = startpos; pos < endpos; pos++)
-        {
-            if (para->getParH(level)->typeOfGridNode[pos] == GEO_FLUID)
-            {
-                //////////////////////////////////////////////////////////////////////////
-                double x1 = para->getParH(level)->coordinateX[pos];
-                double x2 = para->getParH(level)->coordinateY[pos];
-                double x3 = para->getParH(level)->coordinateZ[pos];
-                //////////////////////////////////////////////////////////////////////////
-                number1 = pos;
-                dn1 = pos - startpos;
-                neighborsAreFluid = true;
-                //////////////////////////////////////////////////////////////////////////
-                nodes[dn1] = (makeUbTuple((float)(x1), (float)(x2), (float)(x3)));
-                nodedata[0][dn1] = (double)para->getParH(level)->pressure[pos] / (double)3.0 * (double)para->getDensityRatio() * (double)para->getVelocityRatio() * (double)para->getVelocityRatio();
-                nodedata[1][dn1] = (double)para->getParH(level)->rho[pos] / (double)3.0 * (double)para->getDensityRatio() * (double)para->getVelocityRatio() * (double)para->getVelocityRatio();
-                nodedata[2][dn1] = (double)para->getParH(level)->velocityX[pos] * (double)para->getVelocityRatio();
-                nodedata[3][dn1] = (double)para->getParH(level)->velocityY[pos] * (double)para->getVelocityRatio();
-                nodedata[4][dn1] = (double)para->getParH(level)->velocityZ[pos] * (double)para->getVelocityRatio();
-                nodedata[5][dn1] = (double)para->getParH(level)->typeOfGridNode[pos];
-                nodedata[6][dn1] = (double)para->getParH(level)->concentration[pos];
-                //////////////////////////////////////////////////////////////////////////
-                number2 = para->getParH(level)->neighborX[number1];
-                number3 = para->getParH(level)->neighborY[number2];
-                number4 = para->getParH(level)->neighborY[number1];
-                number5 = para->getParH(level)->neighborZ[number1];
-                number6 = para->getParH(level)->neighborZ[number2];
-                number7 = para->getParH(level)->neighborZ[number3];
-                number8 = para->getParH(level)->neighborZ[number4];
-                //////////////////////////////////////////////////////////////////////////
-                if (para->getParH(level)->typeOfGridNode[number2] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number3] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number4] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number5] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number6] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number7] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number8] != GEO_FLUID)  neighborsAreFluid = false;
-                //////////////////////////////////////////////////////////////////////////
-                if (number2 > endpos ||
-                    number3 > endpos ||
-                    number4 > endpos ||
-                    number5 > endpos ||
-                    number6 > endpos ||
-                    number7 > endpos ||
-                    number8 > endpos)  neighborsAreFluid = false;
-                //////////////////////////////////////////////////////////////////////////
-                dn2 = number2 - startpos;
-                dn3 = number3 - startpos;
-                dn4 = number4 - startpos;
-                dn5 = number5 - startpos;
-                dn6 = number6 - startpos;
-                dn7 = number7 - startpos;
-                dn8 = number8 - startpos;
-                //////////////////////////////////////////////////////////////////////////
-                if (isPeriodicCell(para, level, number2, number1, number3, number5))
-                    continue;
-                //////////////////////////////////////////////////////////////////////////
-                if (neighborsAreFluid)
-                    cells.push_back(makeUbTuple(dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8));
-            }
-        }
-        WbWriterVtkXmlBinary::getInstance()->writeOctsWithNodeData(fname[part], nodes, cells, nodedatanames, nodedata);
-    }
-}
-
-void FileWriter::writeUnstrucuredGridMedianLT(std::shared_ptr<Parameter> para, int level, std::vector<std::string >& fname)
-{
     std::vector< UbTupleFloat3 > nodes;
     std::vector< UbTupleUInt8 > cells;
     //std::vector< UbTupleUInt8 > cells2;
-    std::vector< std::string > nodedatanames;
-    nodedatanames.push_back("pressMed");
-    nodedatanames.push_back("rhoMed");
-    nodedatanames.push_back("vx1Med");
-    nodedatanames.push_back("vx2Med");
-    nodedatanames.push_back("vx3Med");
-    nodedatanames.push_back("geo");
+    std::vector< std::string > nodeDataNames = getMedianNodeDataNames(para);
+    int startIndex = para->getDiffOn()? 1 : 0;
+
     unsigned int number1, number2, number3, number4, number5, number6, number7, number8;
     unsigned int dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8;
     bool neighborsFluid;
-    unsigned int startpos = 0;
-    unsigned int endpos = 0;
-    unsigned int sizeOfNodes = 0;
-    std::vector< std::vector< double > > nodedata(nodedatanames.size());
+    unsigned int startPosition;
+    unsigned int endPosition;
+    unsigned int sizeOfNodes;
+    std::vector< std::vector< double > > nodeData(nodeDataNames.size());
 
     //printf("\n test for if... \n");
     for (unsigned int part = 0; part < fname.size(); part++)
     {
         //printf("\n test in if I... \n");
         //////////////////////////////////////////////////////////////////////////
-        if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+        if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
         {
-            sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+            sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
         }
         else
         {
-            sizeOfNodes = para->getlimitOfNodesForVTK();
+            sizeOfNodes = para->getLimitOfNodesForVTK();
         }
         //////////////////////////////////////////////////////////////////////////
-        startpos = part * para->getlimitOfNodesForVTK();
-        endpos = startpos + sizeOfNodes;
+        startPosition = part * para->getLimitOfNodesForVTK();
+        endPosition = startPosition + sizeOfNodes;
         //////////////////////////////////////////////////////////////////////////
         cells.clear();
         nodes.resize(sizeOfNodes);
-        nodedata[0].resize(sizeOfNodes);
-        nodedata[1].resize(sizeOfNodes);
-        nodedata[2].resize(sizeOfNodes);
-        nodedata[3].resize(sizeOfNodes);
-        nodedata[4].resize(sizeOfNodes);
-        nodedata[5].resize(sizeOfNodes);
+        for (size_t i = 0; i < nodeDataNames.size(); i++)
+            nodeData[i].resize(sizeOfNodes);
         //////////////////////////////////////////////////////////////////////////
         //printf("\n test in if II... \n");
-        for (unsigned int pos = startpos; pos < endpos; pos++)
+        for (unsigned int pos = startPosition; pos < endPosition; pos++)
         {
             if (para->getParH(level)->typeOfGridNode[pos] == GEO_FLUID)
             {
@@ -481,16 +375,18 @@ void FileWriter::writeUnstrucuredGridMedianLT(std::shared_ptr<Parameter> para, i
                 double x3 = para->getParH(level)->coordinateZ[pos];
                 //////////////////////////////////////////////////////////////////////////
                 number1 = pos;
-                dn1 = pos - startpos;
+                dn1 = pos - startPosition;
                 neighborsFluid = true;
                 //////////////////////////////////////////////////////////////////////////
                 nodes[dn1] = (makeUbTuple((float)(x1), (float)(x2), (float)(x3)));
-                nodedata[0][dn1] = para->getParH(level)->press_SP_Med_Out[pos] / 3.0f * para->getDensityRatio() * para->getVelocityRatio() * para->getVelocityRatio();
-                nodedata[1][dn1] = para->getParH(level)->rho_SP_Med_Out[pos] / 3.0f * para->getDensityRatio() * para->getVelocityRatio() * para->getVelocityRatio();
-                nodedata[2][dn1] = para->getParH(level)->vx_SP_Med_Out[pos] * para->getVelocityRatio();
-                nodedata[3][dn1] = para->getParH(level)->vy_SP_Med_Out[pos] * para->getVelocityRatio();
-                nodedata[4][dn1] = para->getParH(level)->vz_SP_Med_Out[pos] * para->getVelocityRatio();
-                nodedata[5][dn1] = (double)para->getParH(level)->typeOfGridNode[pos];
+                if(para->getDiffOn())
+                    nodeData[0][dn1] = (double)para->getParH(level)->Conc_Med_Out[pos];
+                nodeData[startIndex    ][dn1] = para->getParH(level)->press_SP_Med_Out[pos] / 3.0f * para->getDensityRatio() * para->getVelocityRatio() * para->getVelocityRatio();
+                nodeData[startIndex + 1][dn1] = para->getParH(level)->rho_SP_Med_Out[pos] / 3.0f * para->getDensityRatio() * para->getVelocityRatio() * para->getVelocityRatio();
+                nodeData[startIndex + 2][dn1] = para->getParH(level)->vx_SP_Med_Out[pos] * para->getVelocityRatio();
+                nodeData[startIndex + 3][dn1] = para->getParH(level)->vy_SP_Med_Out[pos] * para->getVelocityRatio();
+                nodeData[startIndex + 4][dn1] = para->getParH(level)->vz_SP_Med_Out[pos] * para->getVelocityRatio();
+                nodeData[startIndex + 5][dn1] = (double)para->getParH(level)->typeOfGridNode[pos];
                 //////////////////////////////////////////////////////////////////////////
                 number2 = para->getParH(level)->neighborX[number1];
                 number3 = para->getParH(level)->neighborY[number2];
@@ -508,21 +404,21 @@ void FileWriter::writeUnstrucuredGridMedianLT(std::shared_ptr<Parameter> para, i
                     para->getParH(level)->typeOfGridNode[number7] != GEO_FLUID ||
                     para->getParH(level)->typeOfGridNode[number8] != GEO_FLUID)  neighborsFluid = false;
                 //////////////////////////////////////////////////////////////////////////
-                if (number2 > endpos ||
-                    number3 > endpos ||
-                    number4 > endpos ||
-                    number5 > endpos ||
-                    number6 > endpos ||
-                    number7 > endpos ||
-                    number8 > endpos)  neighborsFluid = false;
-                //////////////////////////////////////////////////////////////////////////
-                dn2 = number2 - startpos;
-                dn3 = number3 - startpos;
-                dn4 = number4 - startpos;
-                dn5 = number5 - startpos;
-                dn6 = number6 - startpos;
-                dn7 = number7 - startpos;
-                dn8 = number8 - startpos;
+                if (number2 > endPosition ||
+                    number3 > endPosition ||
+                    number4 > endPosition ||
+                    number5 > endPosition ||
+                    number6 > endPosition ||
+                    number7 > endPosition ||
+                    number8 > endPosition)  neighborsFluid = false;
+                //////////////////////////////////////////////////////////////////////////
+                dn2 = number2 - startPosition;
+                dn3 = number3 - startPosition;
+                dn4 = number4 - startPosition;
+                dn5 = number5 - startPosition;
+                dn6 = number6 - startPosition;
+                dn7 = number7 - startPosition;
+                dn8 = number8 - startPosition;
                 //////////////////////////////////////////////////////////////////////////
                 if (isPeriodicCell(para, level, number2, number1, number3, number5))
                     continue;
@@ -531,122 +427,8 @@ void FileWriter::writeUnstrucuredGridMedianLT(std::shared_ptr<Parameter> para, i
                 //////////////////////////////////////////////////////////////////////////
             }
         }
-        WbWriterVtkXmlBinary::getInstance()->writeOctsWithNodeData(fname[part], nodes, cells, nodedatanames, nodedata);
+        outFNames.push_back(WbWriterVtkXmlBinary::getInstance()->writeOctsWithNodeData(fname[part], nodes, cells, nodeDataNames, nodeData));
         //////////////////////////////////////////////////////////////////////////
     }
-}
-
-void FileWriter::writeUnstrucuredGridMedianLTConc(std::shared_ptr<Parameter> para, int level, std::vector<std::string >& fname)
-{
-    std::vector< UbTupleFloat3 > nodes;
-    std::vector< UbTupleUInt8 > cells;
-    std::vector< std::string > nodedatanames;
-    nodedatanames.push_back("concMed");
-    nodedatanames.push_back("pressMed");
-    nodedatanames.push_back("rhoMed");
-    nodedatanames.push_back("vx1Med");
-    nodedatanames.push_back("vx2Med");
-    nodedatanames.push_back("vx3Med");
-    nodedatanames.push_back("geo");
-    uint number1, number2, number3, number4, number5, number6, number7, number8;
-    uint dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8;
-    bool neighborsFluid;
-    uint startpos = 0;
-    uint endpos = 0;
-    uint sizeOfNodes = 0;
-    std::vector< std::vector< double > > nodedata(nodedatanames.size());
-
-    for (unsigned int part = 0; part < fname.size(); part++)
-    {
-        if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
-            sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
-        else
-            sizeOfNodes = para->getlimitOfNodesForVTK();
-        //////////////////////////////////////////////////////////////////////////
-        startpos = part * para->getlimitOfNodesForVTK();
-        endpos = startpos + sizeOfNodes;
-        //////////////////////////////////////////////////////////////////////////
-        cells.clear();
-        nodes.resize(sizeOfNodes);
-        nodedata[0].resize(sizeOfNodes);
-        nodedata[1].resize(sizeOfNodes);
-        nodedata[2].resize(sizeOfNodes);
-        nodedata[3].resize(sizeOfNodes);
-        nodedata[4].resize(sizeOfNodes);
-        nodedata[5].resize(sizeOfNodes);
-        nodedata[6].resize(sizeOfNodes);
-        //////////////////////////////////////////////////////////////////////////
-        for (unsigned int pos = startpos; pos < endpos; pos++)
-        {
-            if (para->getParH(level)->typeOfGridNode[pos] == GEO_FLUID)
-            {
-                //////////////////////////////////////////////////////////////////////////
-                double x1 = para->getParH(level)->coordinateX[pos];
-                double x2 = para->getParH(level)->coordinateY[pos];
-                double x3 = para->getParH(level)->coordinateZ[pos];
-                //////////////////////////////////////////////////////////////////////////
-                number1 = pos;
-                dn1 = pos - startpos;
-                neighborsFluid = true;
-                //////////////////////////////////////////////////////////////////////////
-                nodes[dn1] = (makeUbTuple((float)(x1), (float)(x2), (float)(x3)));
-                nodedata[0][dn1] = (double)para->getParH(level)->Conc_Med_Out[pos];
-                nodedata[1][dn1] = (double)para->getParH(level)->press_SP_Med_Out[pos] / 3.0f * para->getDensityRatio() * para->getVelocityRatio() * para->getVelocityRatio();
-                nodedata[2][dn1] = (double)para->getParH(level)->rho_SP_Med_Out[pos] / 3.0f * para->getDensityRatio() * para->getVelocityRatio() * para->getVelocityRatio();
-                nodedata[3][dn1] = (double)para->getParH(level)->vx_SP_Med_Out[pos] * para->getVelocityRatio();
-                nodedata[4][dn1] = (double)para->getParH(level)->vy_SP_Med_Out[pos] * para->getVelocityRatio();
-                nodedata[5][dn1] = (double)para->getParH(level)->vz_SP_Med_Out[pos] * para->getVelocityRatio();
-                nodedata[6][dn1] = (double)para->getParH(level)->typeOfGridNode[pos];
-                //////////////////////////////////////////////////////////////////////////
-                number2 = para->getParH(level)->neighborX[number1];
-                number3 = para->getParH(level)->neighborY[number2];
-                number4 = para->getParH(level)->neighborY[number1];
-                number5 = para->getParH(level)->neighborZ[number1];
-                number6 = para->getParH(level)->neighborZ[number2];
-                number7 = para->getParH(level)->neighborZ[number3];
-                number8 = para->getParH(level)->neighborZ[number4];
-                //////////////////////////////////////////////////////////////////////////
-                if (para->getParH(level)->typeOfGridNode[number2] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number3] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number4] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number5] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number6] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number7] != GEO_FLUID ||
-                    para->getParH(level)->typeOfGridNode[number8] != GEO_FLUID)  neighborsFluid = false;
-                //////////////////////////////////////////////////////////////////////////
-                if (number2 > endpos ||
-                    number3 > endpos ||
-                    number4 > endpos ||
-                    number5 > endpos ||
-                    number6 > endpos ||
-                    number7 > endpos ||
-                    number8 > endpos)  neighborsFluid = false;
-                //////////////////////////////////////////////////////////////////////////
-                dn2 = number2 - startpos;
-                dn3 = number3 - startpos;
-                dn4 = number4 - startpos;
-                dn5 = number5 - startpos;
-                dn6 = number6 - startpos;
-                dn7 = number7 - startpos;
-                dn8 = number8 - startpos;
-                //////////////////////////////////////////////////////////////////////////
-                if (isPeriodicCell(para, level, number2, number1, number3, number5))
-                    continue;
-                //////////////////////////////////////////////////////////////////////////
-                if (neighborsFluid)
-                    cells.push_back(makeUbTuple(dn1, dn2, dn3, dn4, dn5, dn6, dn7, dn8));
-                //////////////////////////////////////////////////////////////////////////
-            }
-        }
-        WbWriterVtkXmlBinary::getInstance()->writeOctsWithNodeData(fname[part], nodes, cells, nodedatanames, nodedata);
-        //////////////////////////////////////////////////////////////////////////
-    }
-}
-//////////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-
+    return outFNames;
+}
\ No newline at end of file
diff --git a/src/gpu/VirtualFluids_GPU/Output/FileWriter.h b/src/gpu/VirtualFluids_GPU/Output/FileWriter.h
index 2d7c176fa067ea86573849e90bd91dab259526b4..73794f957f573d9dc29f57adff4e15d1f6ba7e18 100644
--- a/src/gpu/VirtualFluids_GPU/Output/FileWriter.h
+++ b/src/gpu/VirtualFluids_GPU/Output/FileWriter.h
@@ -11,27 +11,26 @@
 
 class Parameter;
 class CudaMemoryManager;
-struct PN27;
 
 class FileWriter : public DataWriter
 {
 public:
-	void writeInit(std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager) override;
-	void writeTimestep(std::shared_ptr<Parameter> para, unsigned int timestep) override;
+    void writeInit(std::shared_ptr<Parameter> para, std::shared_ptr<CudaMemoryManager> cudaMemoryManager) override;
+    void writeTimestep(std::shared_ptr<Parameter> para, unsigned int timestep) override;
 
 private:
-	void writeTimestep(std::shared_ptr<Parameter> para, unsigned int timestep, int level) override;
-	//void writeParticle(Parameter* para, unsigned int t);
-    void writeUnstrucuredGridLT(std::shared_ptr<Parameter> para, int level,
+    void writeTimestep(std::shared_ptr<Parameter> para, unsigned int timestep, int level) override;
+    std::vector<std::string> writeUnstructuredGridLT(std::shared_ptr<Parameter> para, int level,
                                                          std::vector<std::string> &fname);
-	void writeUnstrucuredGridLTConc(std::shared_ptr<Parameter> para, int level, std::vector<std::string >& fname);
-	void writeUnstrucuredGridMedianLT(std::shared_ptr<Parameter> para, int level, std::vector<std::string >& fname);
-	void writeUnstrucuredGridMedianLTConc(std::shared_ptr<Parameter> para, int level, std::vector<std::string >& fname);
-	bool isPeriodicCell(std::shared_ptr<Parameter> para, int level, unsigned int number2, unsigned int number1, unsigned int number3, unsigned int number5);
+    std::vector<std::string> writeUnstructuredGridMedianLT(std::shared_ptr<Parameter> para, int level, std::vector<std::string >& fname);
+    bool isPeriodicCell(std::shared_ptr<Parameter> para, int level, unsigned int number2, unsigned int number1, unsigned int number3, unsigned int number5);
 
-    void writeCollectionFile( std::shared_ptr<Parameter> para, unsigned int timestep );
+    std::string writeCollectionFile( std::shared_ptr<Parameter> para, unsigned int timestep );
 
-    void writeCollectionFileMedian( std::shared_ptr<Parameter> para, unsigned int timestep );
+    std::string writeCollectionFileMedian( std::shared_ptr<Parameter> para, unsigned int timestep );
+
+    std::vector<std::string> getNodeDataNames(std::shared_ptr<Parameter> para);
+    std::vector<std::string> getMedianNodeDataNames(std::shared_ptr<Parameter> para);
 
     std::vector< std::string > fileNamesForCollectionFile;
     std::vector< std::string > fileNamesForCollectionFileMedian;
diff --git a/src/gpu/VirtualFluids_GPU/Output/QDebugWriter.hpp b/src/gpu/VirtualFluids_GPU/Output/QDebugWriter.hpp
index b24dab20be957fa27b9306d0bbabbec53694753c..d58526cab3b114e77bdb146053584795b05bac8a 100644
--- a/src/gpu/VirtualFluids_GPU/Output/QDebugWriter.hpp
+++ b/src/gpu/VirtualFluids_GPU/Output/QDebugWriter.hpp
@@ -33,8 +33,8 @@ namespace QDebugWriter
 				}
 			}
 			if (qKey > 0) {
-				real transportKey = *((real*)&qKey);
-				qNode.push_back(transportKey);
+				float transportKey = *((float*)&qKey);
+				qNode.push_back((real)transportKey);
 				qNode.push_back((real)k[j]);
 				qs.push_back(qNode);
 			}
diff --git a/src/gpu/VirtualFluids_GPU/Output/UnstructuredGridWriter.hpp b/src/gpu/VirtualFluids_GPU/Output/UnstructuredGridWriter.hpp
index cafe70205455ae8592c1efe86e4ba9de8e1ba170..5d5548ba7e64a23152126446e3c438da1c7e7653 100644
--- a/src/gpu/VirtualFluids_GPU/Output/UnstructuredGridWriter.hpp
+++ b/src/gpu/VirtualFluids_GPU/Output/UnstructuredGridWriter.hpp
@@ -197,16 +197,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-			if ( ((part+1)*para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+			if ( ((part+1)*para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -340,16 +340,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -479,16 +479,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -628,16 +628,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -771,16 +771,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -1342,16 +1342,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-			if ( ((part+1)*para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+			if ( ((part+1)*para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -1465,16 +1465,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -1595,16 +1595,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -1975,16 +1975,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -2080,16 +2080,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
@@ -2192,16 +2192,16 @@ namespace UnstructuredGridWriter
 			vxmax = 0;
 			//printf("\n test in if I... \n");
 			//////////////////////////////////////////////////////////////////////////
-            if (((part + 1) * para->getlimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
+            if (((part + 1) * para->getLimitOfNodesForVTK()) > (uint)para->getParH(level)->numberOfNodes)
 			{
-                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getlimitOfNodesForVTK());
+                sizeOfNodes = (uint)para->getParH(level)->numberOfNodes - (part * para->getLimitOfNodesForVTK());
 			}
 			else
 			{
-				sizeOfNodes = para->getlimitOfNodesForVTK();
+				sizeOfNodes = para->getLimitOfNodesForVTK();
 			}
 			//////////////////////////////////////////////////////////////////////////
-			startpos = part * para->getlimitOfNodesForVTK();
+			startpos = part * para->getLimitOfNodesForVTK();
 			endpos = startpos + sizeOfNodes;
 			//////////////////////////////////////////////////////////////////////////
 			cells.clear();
diff --git a/src/gpu/VirtualFluids_GPU/Parameter/CudaStreamManager.cpp b/src/gpu/VirtualFluids_GPU/Parameter/CudaStreamManager.cpp
index 3cc771e413134e90b0d09d8eeb6dfee791f8a1e2..c6db87138610a6c029a06e32b70f496dc2306a83 100644
--- a/src/gpu/VirtualFluids_GPU/Parameter/CudaStreamManager.cpp
+++ b/src/gpu/VirtualFluids_GPU/Parameter/CudaStreamManager.cpp
@@ -31,15 +31,14 @@
 #include <helper_cuda.h>
 #include <iostream>
 
-void CudaStreamManager::registerStream(CudaStreamIndex streamIndex)
+int CudaStreamManager::registerAndLaunchStream(CudaStreamIndex streamIndex)
 {   
-    if(streamIndex != CudaStreamIndex::Legacy)
-        cudaStreams.emplace(streamIndex, nullptr);
-}
-void CudaStreamManager::launchStreams()
-{
-    for (auto &stream : cudaStreams)
-        cudaStreamCreate(&stream.second);
+    if(streamIndex == CudaStreamIndex::Legacy) return 0;
+
+    cudaStream_t new_stream = nullptr;
+    cudaStreamCreate(&new_stream);
+    cudaStreams.emplace(streamIndex, new_stream);
+    return int(cudaStreams.count(streamIndex) - 1);
 }
 
 void CudaStreamManager::terminateStreams()
diff --git a/src/gpu/VirtualFluids_GPU/Parameter/CudaStreamManager.h b/src/gpu/VirtualFluids_GPU/Parameter/CudaStreamManager.h
index 631a945a653e6b4b60924a650e94b3873ebacc7d..98032ef16adebf56f10d8ed5e9c04bbf517876c3 100644
--- a/src/gpu/VirtualFluids_GPU/Parameter/CudaStreamManager.h
+++ b/src/gpu/VirtualFluids_GPU/Parameter/CudaStreamManager.h
@@ -1,28 +1,28 @@
 //=======================================================================================
-// ____          ____    __    ______     __________   __      __       __        __         
-// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
-//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
-//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
-//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
-//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
-//      \    \  |    |   ________________________________________________________________    
-//       \    \ |    |  |  ______________________________________________________________|   
-//        \    \|    |  |  |         __          __     __     __     ______      _______    
-//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
-//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+// ____          ____    __    ______     __________   __      __       __        __
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|
+//      \    \  |    |   ________________________________________________________________
+//       \    \ |    |  |  ______________________________________________________________|
+//        \    \|    |  |  |         __          __     __     __     ______      _______
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______
 //           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
-//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/
 //
-//  This file is part of VirtualFluids. VirtualFluids is free software: you can 
+//  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 
+//  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 
+//
+//  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/>.
 //
@@ -43,27 +43,26 @@ enum class CudaStreamIndex
         Precursor,
         ActuatorFarm
     };
+
 class CudaStreamManager
-{   
+{
 private:
     std::multimap<CudaStreamIndex, cudaStream_t> cudaStreams;
     cudaEvent_t startBulkKernel = NULL;
     cudaStream_t legacyStream = CU_STREAM_LEGACY;
 
-
 public:
-    void registerStream(CudaStreamIndex streamIndex);
-    void launchStreams();
+    int registerAndLaunchStream(CudaStreamIndex streamIndex);
     void terminateStreams();
-    cudaStream_t &getStream(CudaStreamIndex streamIndex, uint multiStreamIndex=0);
+    cudaStream_t &getStream(CudaStreamIndex streamIndex, uint multiStreamIndex = 0);
 
     bool streamIsRegistered(CudaStreamIndex streamIndex);
     // Events
     void createCudaEvents();
     void destroyCudaEvents();
 
-    void triggerStartBulkKernel(CudaStreamIndex streamIndex, uint multiStreamIndex=0);
-    void waitOnStartBulkKernelEvent(CudaStreamIndex streamIndex, uint multiStreamIndex=0);
+    void triggerStartBulkKernel(CudaStreamIndex streamIndex, uint multiStreamIndex = 0);
+    void waitOnStartBulkKernelEvent(CudaStreamIndex streamIndex, uint multiStreamIndex = 0);
 };
 
 #endif
diff --git a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp
index bf0d72448fb5a69c849d93749e24f29290cf9621..9044f69dccdc848192f62b02c737b8ec961d4ba8 100644
--- a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp
+++ b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.cpp
@@ -37,7 +37,15 @@
 #include <cstdlib>
 #include <optional>
 
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
+#pragma clang diagnostic ignored "-Wunused-but-set-parameter"
+#endif
 #include <curand_kernel.h>
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
 
 #include "StringUtilities/StringUtil.h"
 
@@ -1713,7 +1721,7 @@ unsigned int Parameter::getOutputCount()
 {
     return this->outputCount;
 }
-unsigned int Parameter::getlimitOfNodesForVTK()
+unsigned int Parameter::getLimitOfNodesForVTK()
 {
     return this->limitOfNodesForVTK;
 }
diff --git a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h
index 5944cf66caed4f680ff0480c7b7c39ff7d237aab..89398e063027fe062cce240e397eff59a67732c2 100644
--- a/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h
+++ b/src/gpu/VirtualFluids_GPU/Parameter/Parameter.h
@@ -700,7 +700,7 @@ public:
     real getEndXHotWall();
     unsigned int getStepEnsight();
     unsigned int getOutputCount();
-    unsigned int getlimitOfNodesForVTK();
+    unsigned int getLimitOfNodesForVTK();
     unsigned int getStartTurn();
     bool getEvenOrOdd(int level);
     bool getDiffOn();
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.cu b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.cu
index bcdd63657d13cd8a9dcef3372fe02760a337b057..f2d4b27a159c3f3687bd58933b55558ca08cd16d 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.cu
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/ActuatorFarm.cu
@@ -310,7 +310,7 @@ void ActuatorFarm::init(Parameter* para, GridProvider* gridProvider, CudaMemoryM
     this->initBladeVelocities(cudaMemoryManager);
     this->initBladeForces(cudaMemoryManager);
     this->initBoundingSpheres(para, cudaMemoryManager);
-    this->streamIndex = 0;
+    this->streamIndex = para->getStreamManager()->registerAndLaunchStream(CudaStreamIndex::ActuatorFarm);
 }
 
 void ActuatorFarm::interact(Parameter* para, CudaMemoryManager* cudaMemoryManager, int level, unsigned int t)
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/PreCollisionInteractor.h b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/PreCollisionInteractor.h
index 811045a32b18fd0f5d7f71be39b0dfec8982b352..90c434bd60e623175d5c8bfbbf23fa41f01e8a37 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/PreCollisionInteractor.h
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/PreCollisionInteractor.h
@@ -16,8 +16,6 @@ class CudaMemoryManager;
 
 class VIRTUALFLUIDS_GPU_EXPORT PreCollisionInteractor
 {
-private:
-    SPtr<Parameter> para;
 
 protected:
     PreCollisionInteractor()
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/PrecursorWriter.cu b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/PrecursorWriter.cu
index 99c60fd3d2aae2e796e0c95e624b9d5d33c30ef1..b1ebaf28edc7966074f7cc96e31bf8489ca8e4a9 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/PrecursorWriter.cu
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/PrecursorWriter.cu
@@ -208,7 +208,7 @@ void PrecursorWriter::init(Parameter* para, GridProvider* gridProvider, CudaMemo
         precursorStructs[level]->origin = makeUbTuple(lowestY, lowestZ);
         precursorStructs[level]->extent = makeUbTuple(0, ny-1, 0, nz-1);
         precursorStructs[level]->numberOfPointsInData = ny*nz;
-        precursorStructs[level]->numberOfTimestepsPerFile = min(para->getlimitOfNodesForVTK()/(ny*nz), maxtimestepsPerFile);
+        precursorStructs[level]->numberOfTimestepsPerFile = min(para->getLimitOfNodesForVTK()/(ny*nz), maxtimestepsPerFile);
         precursorStructs[level]->numberOfFilesWritten = 0;
         precursorStructs[level]->numberOfTimestepsBuffered = 0;
         
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlanarAverageProbe.cu b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlanarAverageProbe.cu
index e89d392b5d4bf5983f9bb47642fef81d0f06cc89..705b7173606d1956c50c59d5cc1f7635a4b7883b 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlanarAverageProbe.cu
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlanarAverageProbe.cu
@@ -16,9 +16,11 @@
 #include "DataStructureInitializer/GridProvider.h"
 #include "GPU/CudaMemoryManager.h"
 #include "GPU/GPU_Interface.h"
+#include "basics/constants/NumericConstants.h"
 
 #include <algorithm>
 
+using namespace vf::basics::constant;
 ///////////////////////////////////////////////////////////////////////////////////
 /// Functors for thrust reductions
 ///////////////////////////////////////////////////////////////////////////////////
@@ -307,7 +309,7 @@ void PlanarAverageProbe::calculateQuantities(SPtr<ProbeStruct> probeStruct, Para
         neighborInplane2 = para->getParD(level)->neighborY;
     }
 
-    bool doTmpAveraging = t_level>=(this->getTStartTmpAveraging()*pow(2,level));
+    bool doTmpAveraging = t_level>=(this->getTStartTmpAveraging()*exp2(level));
 
     // Pointer casts to use device arrays in thrust reductions
     thrust::device_ptr<uint> indices_thrust = thrust::device_pointer_cast(probeStruct->pointIndicesD);
@@ -317,7 +319,7 @@ void PlanarAverageProbe::calculateQuantities(SPtr<ProbeStruct> probeStruct, Para
     thrust::device_ptr<real> nut_thrust = thrust::device_pointer_cast(para->getParD(level)->turbViscosity);
 
     real N = (real)probeStruct->nIndices;
-    real n = (real)probeStruct->vals;
+    real invNumberOfTimestepsInTmpAvg = c1o1/real(probeStruct->timestepInTimeAverage+1);
     uint nPoints = probeStruct->nPoints;
     // Permutation iterators for direct iteration over the velocities of the planes
     typedef thrust::device_vector<real>::iterator valIterator;
@@ -353,17 +355,17 @@ void PlanarAverageProbe::calculateQuantities(SPtr<ProbeStruct> probeStruct, Para
 
             if(probeStruct->quantitiesH[int(Statistic::SpatioTemporalMeans)] && doTmpAveraging)
             {
-            uint arrOff = probeStruct->arrayOffsetsH[int(Statistic::SpatioTemporalMeans)];
-            real spatTmpMean_vx_old = probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+node];
-            real spatTmpMean_vy_old = probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node];
-            real spatTmpMean_vz_old = probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node];
-            real spatTmpMean_nut_old;
-            if(para->getUseTurbulentViscosity()) spatTmpMean_nut_old = probeStruct->quantitiesArrayH[(arrOff+3)*nPoints+node];;
-
-            probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+node] += (spatMean_vx-spatTmpMean_vx_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node] += (spatMean_vy-spatTmpMean_vy_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node] += (spatMean_vz-spatTmpMean_vz_old)/n;
-            if(para->getUseTurbulentViscosity()) probeStruct->quantitiesArrayH[(arrOff+3)*nPoints+node] += (spatMean_nut-spatTmpMean_nut_old)/n;
+                uint arrOff = probeStruct->arrayOffsetsH[int(Statistic::SpatioTemporalMeans)];
+                real spatTmpMean_vx_old = probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+node];
+                real spatTmpMean_vy_old = probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node];
+                real spatTmpMean_vz_old = probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node];
+                real spatTmpMean_nut_old;
+                if(para->getUseTurbulentViscosity()) spatTmpMean_nut_old = probeStruct->quantitiesArrayH[(arrOff+3)*nPoints+node];;
+
+                probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+node] += (spatMean_vx-spatTmpMean_vx_old)*invNumberOfTimestepsInTmpAvg;
+                probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node] += (spatMean_vy-spatTmpMean_vy_old)*invNumberOfTimestepsInTmpAvg;
+                probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node] += (spatMean_vz-spatTmpMean_vz_old)*invNumberOfTimestepsInTmpAvg;
+                if(para->getUseTurbulentViscosity()) probeStruct->quantitiesArrayH[(arrOff+3)*nPoints+node] += (spatMean_nut-spatTmpMean_nut_old)*invNumberOfTimestepsInTmpAvg;
 
             }
         
@@ -400,12 +402,12 @@ void PlanarAverageProbe::calculateQuantities(SPtr<ProbeStruct> probeStruct, Para
                     real spatTmpMean_vxvz_old = probeStruct->quantitiesArrayH[(arrOff+4)*nPoints+node];
                     real spatTmpMean_vyvz_old = probeStruct->quantitiesArrayH[(arrOff+5)*nPoints+node];
 
-                    probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+node] += (spatMean_vxvx-spatTmpMean_vxvx_old)/n;
-                    probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node] += (spatMean_vyvy-spatTmpMean_vyvy_old)/n;
-                    probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node] += (spatMean_vzvz-spatTmpMean_vzvz_old)/n;
-                    probeStruct->quantitiesArrayH[(arrOff+3)*nPoints+node] += (spatMean_vxvy-spatTmpMean_vxvy_old)/n;
-                    probeStruct->quantitiesArrayH[(arrOff+4)*nPoints+node] += (spatMean_vxvz-spatTmpMean_vxvz_old)/n;
-                    probeStruct->quantitiesArrayH[(arrOff+5)*nPoints+node] += (spatMean_vyvz-spatTmpMean_vyvz_old)/n;
+                    probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+node] += (spatMean_vxvx-spatTmpMean_vxvx_old)*invNumberOfTimestepsInTmpAvg;
+                    probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node] += (spatMean_vyvy-spatTmpMean_vyvy_old)*invNumberOfTimestepsInTmpAvg;
+                    probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node] += (spatMean_vzvz-spatTmpMean_vzvz_old)*invNumberOfTimestepsInTmpAvg;
+                    probeStruct->quantitiesArrayH[(arrOff+3)*nPoints+node] += (spatMean_vxvy-spatTmpMean_vxvy_old)*invNumberOfTimestepsInTmpAvg;
+                    probeStruct->quantitiesArrayH[(arrOff+4)*nPoints+node] += (spatMean_vxvz-spatTmpMean_vxvz_old)*invNumberOfTimestepsInTmpAvg;
+                    probeStruct->quantitiesArrayH[(arrOff+5)*nPoints+node] += (spatMean_vyvz-spatTmpMean_vyvz_old)*invNumberOfTimestepsInTmpAvg;
                 }
 
                 if(probeStruct->quantitiesH[int(Statistic::SpatialSkewness)])
@@ -435,9 +437,9 @@ void PlanarAverageProbe::calculateQuantities(SPtr<ProbeStruct> probeStruct, Para
                         real spatTmpMean_Sy_old = probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node];
                         real spatTmpMean_Sz_old = probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node];
 
-                        probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+node] += (spatMean_Sx-spatTmpMean_Sx_old)/n;
-                        probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node] += (spatMean_Sy-spatTmpMean_Sy_old)/n;
-                        probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node] += (spatMean_Sz-spatTmpMean_Sz_old)/n;
+                        probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+node] += (spatMean_Sx-spatTmpMean_Sx_old)*invNumberOfTimestepsInTmpAvg;
+                        probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node] += (spatMean_Sy-spatTmpMean_Sy_old)*invNumberOfTimestepsInTmpAvg;
+                        probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node] += (spatMean_Sz-spatTmpMean_Sz_old)*invNumberOfTimestepsInTmpAvg;
                     }
 
                     if(probeStruct->quantitiesH[int(Statistic::SpatialFlatness)])
@@ -464,9 +466,9 @@ void PlanarAverageProbe::calculateQuantities(SPtr<ProbeStruct> probeStruct, Para
                             real spatTmpMean_Fy_old = probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node];
                             real spatTmpMean_Fz_old = probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node];
 
-                            probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+node] += (spatMean_Fx-spatTmpMean_Fx_old)/n;
-                            probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node] += (spatMean_Fy-spatTmpMean_Fy_old)/n;
-                            probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node] += (spatMean_Fz-spatTmpMean_Fz_old)/n;
+                            probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+node] += (spatMean_Fx-spatTmpMean_Fx_old)*invNumberOfTimestepsInTmpAvg;
+                            probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+node] += (spatMean_Fy-spatTmpMean_Fy_old)*invNumberOfTimestepsInTmpAvg;
+                            probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+node] += (spatMean_Fz-spatTmpMean_Fz_old)*invNumberOfTimestepsInTmpAvg;
                         }
                     }
                 }
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlanarAverageProbe.h b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlanarAverageProbe.h
index 3d3533f74501e776f9150c83c9d9101a0be7ecbc..c2370231c0bc341ca9b3980578ce4aadc1b75c7a 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlanarAverageProbe.h
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlanarAverageProbe.h
@@ -90,6 +90,8 @@ private:
                     std::vector<real>& pointCoordsX_level, std::vector<real>& pointCoordsY_level, std::vector<real>& pointCoordsZ_level,
                     int level) override;
     void calculateQuantities(SPtr<ProbeStruct> probeStruct, Parameter* para, uint t, int level) override;
+    void getTaggedFluidNodes(Parameter *para, GridProvider* gridProvider) override {};
+
 
 private:
     real posX, posY, posZ;
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlaneProbe.cu b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlaneProbe.cu
index f55045505bff0e3b5b0b1426be4e9e1a3832d088..19f7f6c62ae7ac83c90fc2a7aff0e286a70063d1 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlaneProbe.cu
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PlaneProbe.cu
@@ -102,10 +102,23 @@ void PlaneProbe::findPoints(Parameter* para, GridProvider* gridProvider, std::ve
 void PlaneProbe::calculateQuantities(SPtr<ProbeStruct> probeStruct, Parameter* para, uint t, int level)
 {
     vf::cuda::CudaGrid grid = vf::cuda::CudaGrid(para->getParH(level)->numberofthreads, probeStruct->nPoints);
-    calcQuantitiesKernel<<<grid.grid, grid.threads>>>(  probeStruct->pointIndicesD, probeStruct->nPoints, probeStruct->vals,
-    para->getParD(level)->velocityX, para->getParD(level)->velocityY, para->getParD(level)->velocityZ, para->getParD(level)->rho, 
-    para->getParD(level)->neighborX, para->getParD(level)->neighborY, para->getParD(level)->neighborZ, 
-    probeStruct->quantitiesD, probeStruct->arrayOffsetsD, probeStruct->quantitiesArrayD);
+    calcQuantitiesKernel<<<grid.grid, grid.threads>>>(  probeStruct->pointIndicesD,
+                                                        probeStruct->nPoints,
+                                                        0,
+                                                        0,
+                                                        probeStruct->timestepInTimeAverage,
+                                                        probeStruct->nTimesteps,
+                                                        para->getParD(level)->velocityX,
+                                                        para->getParD(level)->velocityY,
+                                                        para->getParD(level)->velocityZ,
+                                                        para->getParD(level)->rho,
+                                                        para->getParD(level)->neighborX,
+                                                        para->getParD(level)->neighborY,
+                                                        para->getParD(level)->neighborZ,
+                                                        probeStruct->quantitiesD,
+                                                        probeStruct->arrayOffsetsD,
+                                                        probeStruct->quantitiesArrayD
+                                                        );
 }
 
 void PlaneProbe::getTaggedFluidNodes(Parameter *para, GridProvider* gridProvider)
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PointProbe.cu b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PointProbe.cu
index 89e1f6b87687ed42c079415a5340f1d385c8d62c..19c170608a606227d21c25791776bd3195b16e04 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PointProbe.cu
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PointProbe.cu
@@ -103,13 +103,22 @@ void PointProbe::findPoints(Parameter* para, GridProvider* gridProvider, std::ve
 void PointProbe::calculateQuantities(SPtr<ProbeStruct> probeStruct, Parameter* para, uint t, int level)
 {
     vf::cuda::CudaGrid grid = vf::cuda::CudaGrid(para->getParH(level)->numberofthreads, probeStruct->nPoints);
-    interpAndCalcQuantitiesKernel<<<grid.grid, grid.threads>>>(  probeStruct->pointIndicesD, probeStruct->nPoints, probeStruct->vals,
+    int oldTimestepInTimeseries = this->outputTimeSeries ? calcOldTimestep(probeStruct->timestepInTimeseries, probeStruct->lastTimestepInOldTimeseries) : 0;
+    int currentTimestep = this->outputTimeSeries ? probeStruct->timestepInTimeseries : 0;
+    interpAndCalcQuantitiesKernel<<<grid.grid, grid.threads>>>(  probeStruct->pointIndicesD, probeStruct->nPoints, oldTimestepInTimeseries, currentTimestep, probeStruct->timestepInTimeAverage, probeStruct->nTimesteps,
                                                 probeStruct->distXD, probeStruct->distYD, probeStruct->distZD,
                                                 para->getParD(level)->velocityX, para->getParD(level)->velocityY, para->getParD(level)->velocityZ, para->getParD(level)->rho, 
                                                 para->getParD(level)->neighborX, para->getParD(level)->neighborY, para->getParD(level)->neighborZ, 
                                                 probeStruct->quantitiesD, probeStruct->arrayOffsetsD, probeStruct->quantitiesArrayD);
 }
 
+void PointProbe::addProbePoint(real pointCoordX, real pointCoordY, real pointCoordZ)
+{
+    this->pointCoordsX.push_back(pointCoordX);
+    this->pointCoordsY.push_back(pointCoordY);
+    this->pointCoordsZ.push_back(pointCoordZ);
+}
+
 void PointProbe::addProbePointsFromList(std::vector<real>& _pointCoordsX, std::vector<real>& _pointCoordsY, std::vector<real>& _pointCoordsZ)
 {
     bool isSameLength = ( (_pointCoordsX.size()==_pointCoordsY.size()) && (_pointCoordsY.size()==_pointCoordsZ.size()));
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PointProbe.h b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PointProbe.h
index 08c359705f03b20fbd3276fe209b6ff4d782a5e5..b26211dc859bf4601b42a640d25e656b3552300b 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PointProbe.h
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/PointProbe.h
@@ -50,7 +50,8 @@ public:
         uint _tStartAvg,
         uint _tAvg,
         uint _tStartOut,
-        uint _tOut
+        uint _tOut,
+        bool _outputTimeseries = false
     ): Probe(_probeName, 
              _outputPath,
              _tStartAvg, 
@@ -59,9 +60,10 @@ public:
              _tStartOut, 
              _tOut,
              true,
-             false)
+             _outputTimeseries)
     {}
 
+    void addProbePoint(real pointCoordX, real pointCoordY, real pointCoordZ);
     void addProbePointsFromList(std::vector<real>& _pointCoordsX, std::vector<real>& _pointCoordsY, std::vector<real>& _pointCoordsZ);
     void addProbePointsFromXNormalPlane(real pos_x, real pos0_y, real pos0_z, real pos1_y, real pos1_z, uint n_y, uint n_z);
     void getTaggedFluidNodes(Parameter *para, GridProvider* gridProvider) override;
@@ -80,6 +82,8 @@ private:
 
 private:
     std::vector<real> pointCoordsX, pointCoordsY, pointCoordsZ; 
+    uint getNumberOfTimestepsInTimeseries(Parameter* para, int level) override { return outputTimeSeries ? tOut*exp2(level) : 1; }
+
 
 };
 
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/Probe.cu b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/Probe.cu
index a7a0e79c0bcbf0f7a9e13e879debfb378e23f69d..2be8743bb28e45234533cb63673a9aebd6b0cf10 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/Probe.cu
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/Probe.cu
@@ -47,69 +47,92 @@
 
 using namespace vf::basics::constant;
 
-__device__ void calculatePointwiseQuantities(uint n, real* quantityArray, bool* quantities, uint* quantityArrayOffsets, uint nPoints, uint node, real vx, real vy, real vz, real rho)
+__host__ __device__ int calcArrayIndex(int node, int nNodes, int timestep, int nTimesteps, int array)
+{
+    return node+nNodes*(timestep+nTimesteps*array);
+}
+
+uint calcOldTimestep(uint currentTimestep, uint lastTimestepInOldSeries)
+{
+    return currentTimestep > 0 ? currentTimestep - 1 : lastTimestepInOldSeries; 
+}
+
+__device__ void calculatePointwiseQuantities(
+    uint oldTimestepInTimeseries,
+    uint timestepInTimeseries,
+    uint timestepInAverage,
+    uint nTimesteps,
+    real* quantityArray,
+    bool* quantities,
+    uint* quantityArrayOffsets,
+    uint nPoints,
+    uint node,
+    real vx,
+    real vy,
+    real vz,
+    real rho)
 {
     //"https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Welford's_online_algorithm"
     // also has extensions for higher order and covariances
+    int n = timestepInAverage+1;
     real inv_n = 1/real(n);
 
-    if(quantities[int(Statistic::Instantaneous)])
+    if (quantities[int(Statistic::Instantaneous)])
     {
         uint arrOff = quantityArrayOffsets[int(Statistic::Instantaneous)];
-        quantityArray[(arrOff+0)*nPoints+node] = vx;
-        quantityArray[(arrOff+1)*nPoints+node] = vy;
-        quantityArray[(arrOff+2)*nPoints+node] = vz;
-        quantityArray[(arrOff+3)*nPoints+node] = rho;
+        quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 0)] = vx;
+        quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 1)] = vy;
+        quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 2)] = vz;
+        quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 3)] = rho;
     }
 
-    if(quantities[int(Statistic::Means)])
+    if (quantities[int(Statistic::Means)])
     {
-        
         uint arrOff = quantityArrayOffsets[int(Statistic::Means)];
-        real vx_m_old  = quantityArray[(arrOff+0)*nPoints+node];
-        real vy_m_old  = quantityArray[(arrOff+1)*nPoints+node];
-        real vz_m_old  = quantityArray[(arrOff+2)*nPoints+node];
-        real rho_m_old = quantityArray[(arrOff+3)*nPoints+node];
-
-        real vx_m_new  = ( (n-1)*vx_m_old + vx  )*inv_n;
-        real vy_m_new  = ( (n-1)*vy_m_old + vy  )*inv_n;
-        real vz_m_new  = ( (n-1)*vz_m_old + vz  )*inv_n;
-        real rho_m_new = ( (n-1)*rho_m_old+ rho )*inv_n;
-
-        quantityArray[(arrOff+0)*nPoints+node] = vx_m_new;
-        quantityArray[(arrOff+1)*nPoints+node] = vy_m_new;
-        quantityArray[(arrOff+2)*nPoints+node] = vz_m_new;
-        quantityArray[(arrOff+3)*nPoints+node] = rho_m_new;
-    
-        if(quantities[int(Statistic::Variances)])
+        real vx_m_old  = quantityArray[calcArrayIndex(node, nPoints, oldTimestepInTimeseries, nTimesteps, arrOff + 0)];
+        real vy_m_old  = quantityArray[calcArrayIndex(node, nPoints, oldTimestepInTimeseries, nTimesteps, arrOff + 1)];
+        real vz_m_old  = quantityArray[calcArrayIndex(node, nPoints, oldTimestepInTimeseries, nTimesteps, arrOff + 2)];
+        real rho_m_old = quantityArray[calcArrayIndex(node, nPoints, oldTimestepInTimeseries, nTimesteps, arrOff + 3)];
+
+        real vx_m_new  = ((n - 1) * vx_m_old  + vx)  * inv_n;
+        real vy_m_new  = ((n - 1) * vy_m_old  + vy)  * inv_n;
+        real vz_m_new  = ((n - 1) * vz_m_old  + vz)  * inv_n;
+        real rho_m_new = ((n - 1) * rho_m_old + rho) * inv_n;
+
+        quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 0)] = vx_m_new;
+        quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 1)] = vy_m_new;
+        quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 2)] = vz_m_new;
+        quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 3)] = rho_m_new;
+
+        if (quantities[int(Statistic::Variances)])
         {
             arrOff = quantityArrayOffsets[int(Statistic::Variances)];
 
-            real vx_var_old  = quantityArray[(arrOff+0)*nPoints+node];
-            real vy_var_old  = quantityArray[(arrOff+1)*nPoints+node];
-            real vz_var_old  = quantityArray[(arrOff+2)*nPoints+node];
-            real rho_var_old = quantityArray[(arrOff+3)*nPoints+node];
+            real vx_var_old  = quantityArray[calcArrayIndex(node, nPoints, oldTimestepInTimeseries, nTimesteps, arrOff + 0)];
+            real vy_var_old  = quantityArray[calcArrayIndex(node, nPoints, oldTimestepInTimeseries, nTimesteps, arrOff + 1)];
+            real vz_var_old  = quantityArray[calcArrayIndex(node, nPoints, oldTimestepInTimeseries, nTimesteps, arrOff + 2)];
+            real rho_var_old = quantityArray[calcArrayIndex(node, nPoints, oldTimestepInTimeseries, nTimesteps, arrOff + 3)];
 
-            real vx_var_new  = ( (n-1)*(vx_var_old )+(vx  - vx_m_old )*(vx  - vx_m_new ) )*inv_n;
-            real vy_var_new  = ( (n-1)*(vy_var_old )+(vy  - vy_m_old )*(vy  - vy_m_new ) )*inv_n;
-            real vz_var_new  = ( (n-1)*(vz_var_old )+(vz  - vz_m_old )*(vz  - vz_m_new ) )*inv_n;
-            real rho_var_new = ( (n-1)*(rho_var_old)+(rho - rho_m_old)*(rho - rho_m_new) )*inv_n;
+            real vx_var_new  = ((n - 1) * (vx_var_old)  + (vx  - vx_m_old)  * (vx  - vx_m_new))  * inv_n;
+            real vy_var_new  = ((n - 1) * (vy_var_old)  + (vy  - vy_m_old)  * (vy  - vy_m_new))  * inv_n;
+            real vz_var_new  = ((n - 1) * (vz_var_old)  + (vz  - vz_m_old)  * (vz  - vz_m_new))  * inv_n;
+            real rho_var_new = ((n - 1) * (rho_var_old) + (rho - rho_m_old) * (rho - rho_m_new)) * inv_n;
 
-            quantityArray[(arrOff+0)*nPoints+node] = vx_var_new;
-            quantityArray[(arrOff+1)*nPoints+node] = vy_var_new;
-            quantityArray[(arrOff+2)*nPoints+node] = vz_var_new;
-            quantityArray[(arrOff+3)*nPoints+node] = rho_var_new; 
+            quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 0)] = vx_var_new;
+            quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 1)] = vy_var_new;
+            quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 2)] = vz_var_new;
+            quantityArray[calcArrayIndex(node, nPoints, timestepInTimeseries, nTimesteps, arrOff + 3)] = rho_var_new;
         }
     }
 }
 
 __global__ void calcQuantitiesKernel(   uint* pointIndices,
-                                    uint nPoints, uint n,
+                                    uint nPoints, uint oldTimestepInTimeseries, uint timestepInTimeseries, uint timestepInAverage, uint nTimesteps,
                                     real* vx, real* vy, real* vz, real* rho,            
                                     uint* neighborX, uint* neighborY, uint* neighborZ,
                                     bool* quantities,
                                     uint* quantityArrayOffsets, real* quantityArray
-                                )
+                                    )
 {
     const uint x = threadIdx.x; 
     const uint y = blockIdx.x;
@@ -132,12 +155,12 @@ __global__ void calcQuantitiesKernel(   uint* pointIndices,
     u_interpZ = vz[k];
     rho_interp = rho[k];
 
-    calculatePointwiseQuantities(n, quantityArray, quantities, quantityArrayOffsets, nPoints, node, u_interpX, u_interpY, u_interpZ, rho_interp);
+    calculatePointwiseQuantities(oldTimestepInTimeseries, timestepInTimeseries, timestepInAverage, nTimesteps, quantityArray, quantities, quantityArrayOffsets, nPoints, node, u_interpX, u_interpY, u_interpZ, rho_interp);
 
 }
 
 __global__ void interpAndCalcQuantitiesKernel(   uint* pointIndices,
-                                    uint nPoints, uint n,
+                                    uint nPoints, uint oldTimestepInTimeseries, uint timestepInTimeseries, uint timestepInAverage, uint nTimesteps,
                                     real* distX, real* distY, real* distZ,
                                     real* vx, real* vy, real* vz, real* rho,            
                                     uint* neighborX, uint* neighborY, uint* neighborZ,
@@ -173,7 +196,7 @@ __global__ void interpAndCalcQuantitiesKernel(   uint* pointIndices,
     u_interpZ  = trilinearInterpolation( dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, vz );
     rho_interp = trilinearInterpolation( dW, dE, dN, dS, dT, dB, k, ke, kn, kt, kne, kte, ktn, ktne, rho );
 
-    calculatePointwiseQuantities(n, quantityArray, quantities, quantityArrayOffsets, nPoints, node, u_interpX, u_interpY, u_interpZ, rho_interp);
+    calculatePointwiseQuantities(oldTimestepInTimeseries, timestepInTimeseries, timestepInAverage, nTimesteps, quantityArray, quantities, quantityArrayOffsets, nPoints, node, u_interpX, u_interpY, u_interpZ, rho_interp);
 
 }
 
@@ -207,26 +230,28 @@ void Probe::init(Parameter* para, GridProvider* gridProvider, CudaMemoryManager*
                        pointCoordsX_level, pointCoordsY_level, pointCoordsZ_level,
                        level);
         
-        this->addProbeStruct(cudaMemoryManager, probeIndices_level, 
+        this->addProbeStruct(para, cudaMemoryManager, probeIndices_level, 
                             distX_level, distY_level, distZ_level, 
                             pointCoordsX_level, pointCoordsY_level, pointCoordsZ_level, 
                             level);
+
+        if(this->outputTimeSeries) timeseriesFileNames.push_back(this->writeTimeseriesHeader(para, level));
     }
 }
 
-void Probe::addProbeStruct(CudaMemoryManager* cudaMemoryManager, std::vector<int>& probeIndices,
-                                      std::vector<real>& distX, std::vector<real>& distY, std::vector<real>& distZ,   
-                                      std::vector<real>& pointCoordsX, std::vector<real>& pointCoordsY, std::vector<real>& pointCoordsZ,
-                                      int level)
+void Probe::addProbeStruct( Parameter* para, CudaMemoryManager* cudaMemoryManager, std::vector<int>& probeIndices,
+                            std::vector<real>& distX, std::vector<real>& distY, std::vector<real>& distZ,   
+                            std::vector<real>& pointCoordsX, std::vector<real>& pointCoordsY, std::vector<real>& pointCoordsZ,
+                            int level)
 {
     probeParams[level] = SPtr<ProbeStruct>(new ProbeStruct);
-    probeParams[level]->vals = 1;
+    probeParams[level]->nTimesteps = this->getNumberOfTimestepsInTimeseries(para, level);
     probeParams[level]->nPoints  = uint(pointCoordsX.size()); // Note, need to have both nPoints and nIndices because they differ in PlanarAverage
     probeParams[level]->nIndices = uint(probeIndices.size());
 
-    probeParams[level]->pointCoordsX = (real*)malloc(probeParams[level]->nPoints*sizeof(real));
-    probeParams[level]->pointCoordsY = (real*)malloc(probeParams[level]->nPoints*sizeof(real));
-    probeParams[level]->pointCoordsZ = (real*)malloc(probeParams[level]->nPoints*sizeof(real));
+    probeParams[level]->pointCoordsX = (real*)malloc(probeParams[level]->nPoints * sizeof(real));
+    probeParams[level]->pointCoordsY = (real*)malloc(probeParams[level]->nPoints * sizeof(real));
+    probeParams[level]->pointCoordsZ = (real*)malloc(probeParams[level]->nPoints * sizeof(real));
 
     std::copy(pointCoordsX.begin(), pointCoordsX.end(), probeParams[level]->pointCoordsX);
     std::copy(pointCoordsY.begin(), pointCoordsY.end(), probeParams[level]->pointCoordsY);
@@ -267,39 +292,57 @@ void Probe::addProbeStruct(CudaMemoryManager* cudaMemoryManager, std::vector<int
 
     cudaMemoryManager->cudaAllocProbeQuantityArray(this, level);
 
-    for(uint arr=0; arr<probeParams[level]->nArrays; arr++)
-    {
-        for( uint point=0; point<probeParams[level]->nPoints; point++)
-        {
-            probeParams[level]->quantitiesArrayH[arr*probeParams[level]->nPoints+point] = 0.0f;
-        }
-    }
+    std::fill_n(probeParams[level]->quantitiesArrayH, probeParams[level]->nArrays*probeParams[level]->nPoints*probeParams[level]->nTimesteps, c0o1);
+
     if(this->hasDeviceQuantityArray)
         cudaMemoryManager->cudaCopyProbeQuantityArrayHtoD(this, level);
+
 }
 
 void Probe::interact(Parameter* para, CudaMemoryManager* cudaMemoryManager, int level, uint t)
 {
     uint t_level = para->getTimeStep(level, t, false);
 
+    SPtr<ProbeStruct> probeStruct = this->getProbeStruct(level);
+
+    //!Skip empty probes
+    if(probeStruct->nPoints==0) return;
+
     //! if tAvg==1 the probe will be evaluated in every sub-timestep of each respective level
     //! else, the probe will only be evaluated in each synchronous time step tAvg
 
-    uint tAvg_level = this->tAvg==1? this->tAvg: this->tAvg*pow(2,level);          
+    uint level_coefficient = exp2(level);
 
-    if(max(int(t_level) - int(this->tStartAvg*pow(2,level)), -1) % tAvg_level==0)
+    uint tAvg_level = this->tAvg == 1 ? this->tAvg : this->tAvg * level_coefficient;
+    uint tOut_level = this->tOut * level_coefficient;
+    uint tStartOut_level = this->tStartOut * level_coefficient;
+    uint tStartAvg_level = this->tStartAvg * level_coefficient;
+
+    uint tAfterStartAvg = t_level - tStartAvg_level;
+    uint tAfterStartOut = t_level - tStartOut_level;
+
+    if( (t > this->tStartAvg) && (tAfterStartAvg % tAvg_level == 0))
     {
-        SPtr<ProbeStruct> probeStruct = this->getProbeStruct(level);
         this->calculateQuantities(probeStruct, para, t_level, level);
-        if(t_level>=(this->tStartTmpAveraging*pow(2,level))) probeStruct->vals++;
+
+        if(t > this->tStartTmpAveraging) probeStruct->timestepInTimeAverage++;
+        if(this->outputTimeSeries && (t_level >= tStartOut_level)) probeStruct->timestepInTimeseries++;
     }
 
     //! output only in synchronous timesteps
-    if(max(int(t_level) - int(this->tStartOut*pow(2,level)), -1) % int(this->tOut*pow(2,level)) == 0)
+    if( (t > this->tStartOut) && (tAfterStartOut % tOut_level == 0) )
     {   
         if(this->hasDeviceQuantityArray)
             cudaMemoryManager->cudaCopyProbeQuantityArrayDtoH(this, level);
         this->write(para, level, t);
+        
+        if(level == 0&& !this->outputTimeSeries) this->writeParallelFile(para, t);
+
+        if(this->outputTimeSeries)
+        {
+            probeStruct->lastTimestepInOldTimeseries = probeStruct->timestepInTimeseries > 0 ? probeStruct->timestepInTimeseries - 1: 0;
+            probeStruct->timestepInTimeseries = 0;
+        }
     }
 }
 
@@ -315,11 +358,6 @@ void Probe::free(Parameter* para, CudaMemoryManager* cudaMemoryManager)
     }
 }
 
-void Probe::getTaggedFluidNodes(Parameter *para, GridProvider* gridProvider)
-{
-    // Do nothing
-};
-
 
 void Probe::addStatistic(Statistic variable)
 {
@@ -335,22 +373,32 @@ void Probe::addStatistic(Statistic variable)
     }
 }
 
+template<typename T>
+std::string nameComponent(std::string name, T value)
+{
+    return "_" + name + "_" + StringUtil::toString<T>(value); 
+}
+
 std::string Probe::makeParallelFileName(int id, int t)
 {
-    return this->probeName + "_bin_ID_" + StringUtil::toString<int>(id) 
-                                           + "_t_" + StringUtil::toString<int>(t) 
-                                           + ".vtk";
+    return this->probeName + "_bin" + nameComponent<int>("ID", id) + nameComponent<int>("t", t) + ".vtk"; 
+
 }
 
 std::string Probe::makeGridFileName(int level, int id, int t, uint part)
 {
-    return this->probeName + "_bin_lev_" + StringUtil::toString<int>(level)
-                                         + "_ID_" + StringUtil::toString<int>(id)
-                                         + "_Part_" + StringUtil::toString<int>(part) 
-                                         + "_t_" + StringUtil::toString<int>(t) 
-                                         + ".vtk";
+    return this->probeName + "_bin" + nameComponent<int>("lev", level)
+                                    + nameComponent<int>("ID", id)
+                                    + nameComponent<int>("Part", part)
+                                    + nameComponent<int>("t", t) + ".vtk";
 }
 
+std::string Probe::makeTimeseriesFileName(int level, int id)
+{
+    return this->probeName + "_timeseries" + nameComponent<int>("lev", level)
+                                    + nameComponent<int>("ID", id)
+                                    + ".txt";
+}
 void Probe::addAllAvailableStatistics()
 {
     for( int var=0; var < int(Statistic::LAST); var++)
@@ -362,16 +410,23 @@ void Probe::addAllAvailableStatistics()
 
 void Probe::write(Parameter* para, int level, int t)
 {
-    int t_write = this->fileNameLU ? t: t/this->tOut; 
+    if(this->outputTimeSeries)
+    {
+        this->appendTimeseriesFile(para, level, t);
+    }
+    else
+    {
+        int t_write = this->fileNameLU ? t: t/this->tOut; 
 
-    const uint numberOfParts = this->getProbeStruct(level)->nPoints / para->getlimitOfNodesForVTK() + 1;
+        const uint numberOfParts = this->getProbeStruct(level)->nPoints / para->getLimitOfNodesForVTK() + 1;
 
-    std::vector<std::string> fnames;
-    for (uint i = 1; i <= numberOfParts; i++)
-	{
-        this->writeGridFile(para, level, t_write, i);
+        std::vector<std::string> fnames;
+        for (uint i = 1; i <= numberOfParts; i++)
+        {
+            this->writeGridFile(para, level, t_write, i);
+        }
     }
-    if(level == 0&& !this->outputTimeSeries) this->writeParallelFile(para, t);
+
 }
 
 void Probe::writeParallelFile(Parameter* para, int t)
@@ -398,8 +453,8 @@ void Probe::writeGridFile(Parameter* para, int level, int t, uint part)
 
     SPtr<ProbeStruct> probeStruct = this->getProbeStruct(level);
 
-    uint startpos = (part-1) * para->getlimitOfNodesForVTK();
-    uint sizeOfNodes = min(para->getlimitOfNodesForVTK(), probeStruct->nPoints - startpos);
+    uint startpos = (part-1) * para->getLimitOfNodesForVTK();
+    uint sizeOfNodes = min(para->getLimitOfNodesForVTK(), probeStruct->nPoints - startpos);
     uint endpos = startpos + sizeOfNodes;
 
     //////////////////////////////////////////////////////////////////////////
@@ -414,25 +469,28 @@ void Probe::writeGridFile(Parameter* para, int level, int t, uint part)
 
     for( auto it=nodedata.begin(); it!=nodedata.end(); it++) it->resize(sizeOfNodes);
 
-    for( int var=0; var < int(Statistic::LAST); var++){           
+    uint arrLen = probeStruct->nPoints;
+    int nTimesteps = probeStruct->nTimesteps;
+    int timestep = probeStruct->timestepInTimeseries;
+
+    for( int var=0; var < int(Statistic::LAST); var++)
+    {           
         if(this->quantities[var])
         {
-            Statistic statistic = static_cast<Statistic>(var);
-            real coeff;
 
+            Statistic statistic = static_cast<Statistic>(var);
             std::vector<PostProcessingVariable> postProcessingVariables = this->getPostProcessingVariables(statistic);
             uint n_arrs = uint(postProcessingVariables.size());
 
             uint arrOff = probeStruct->arrayOffsetsH[var];
-            uint arrLen = probeStruct->nPoints;
 
             for(uint arr=0; arr<n_arrs; arr++)
             {
-                coeff = postProcessingVariables[arr].conversionFactor(level);
+                real coeff = postProcessingVariables[arr].conversionFactor(level);
                 
                 for (uint pos = startpos; pos < endpos; pos++)
                 {
-                    nodedata[arrOff+arr][pos-startpos] = double(probeStruct->quantitiesArrayH[(arrOff+arr)*arrLen+pos]*coeff);
+                    nodedata[arrOff+arr][pos-startpos] = double(probeStruct->quantitiesArrayH[calcArrayIndex(pos, arrLen, timestep, nTimesteps, arrOff+arr)]*coeff);
                 }
             }
         }
@@ -441,6 +499,91 @@ void Probe::writeGridFile(Parameter* para, int level, int t, uint part)
     this->fileNamesForCollectionFile.push_back(fullName.substr(fullName.find_last_of('/') + 1));
 }
 
+std::string Probe::writeTimeseriesHeader(Parameter* para, int level)
+{
+/*
+File Layout:
+TimeseriesOutput
+Quantities: Quant1 Quant2 Quant3
+Positions:
+point1.x, point1.y, point1.z
+point2.x, point2.y, point2.z
+...
+t0 point1.quant1 point2.quant1 ... point1.quant2 point2.quant2 ...
+t1 point1.quant1 point2.quant1 ... point1.quant2 point2.quant2 ...
+*/
+    auto probeStruct = this->getProbeStruct(level);
+    std::string fname = this->outputPath + "/" + this->makeTimeseriesFileName(level, para->getMyProcessID());
+    std::ofstream out(fname.c_str(), std::ios::out | std::ios::binary);
+
+    if(!out.is_open()) throw std::runtime_error("Could not open timeseries file!");
+
+    out << "TimeseriesOutput \n";
+    out << "Quantities: ";
+    for(std::string name : getVarNames())
+        out << name << ", ";
+    out << "\n";
+    out << "Number of points in this file: \n";
+    out << probeStruct->nPoints << "\n";
+    out << "Positions: x, y, z\n";
+    for( uint i=0; i<probeStruct->nPoints; i++)
+        out << probeStruct->pointCoordsX[i] << ", " << probeStruct->pointCoordsY[i] << ", " << probeStruct->pointCoordsZ[i] << "\n";
+
+    out.close();
+
+    return fname;
+}
+
+void Probe::appendTimeseriesFile(Parameter* para, int level, int t)
+{
+    std::ofstream out(this->timeseriesFileNames[level], std::ios::app | std::ios::binary);
+
+    uint t_level = para->getTimeStep(level, t, false);
+    uint tAvg_level = this->tAvg==1 ? this->tAvg: this->tAvg*exp2(-level);
+
+    real dt = para->getTimeRatio()*tAvg_level;
+    auto probeStruct = this->getProbeStruct(level);
+
+    real t_start = ( t-this->tOut )*para->getTimeRatio();
+
+    int vals_per_timestep = probeStruct->nPoints*probeStruct->nArrays+1;
+
+    real* timestep_array = (real*) malloc(vals_per_timestep*sizeof(real));
+
+    for(uint timestep=0; timestep<probeStruct->timestepInTimeseries; timestep++)
+    {
+        int val = 0;
+        timestep_array[val] = t_start+timestep*dt;
+        val++;
+
+        for( int var=0; var < int(Statistic::LAST); var++)
+        {           
+            if(!this->quantities[var]) continue;
+            
+            Statistic statistic = static_cast<Statistic>(var);
+            std::vector<PostProcessingVariable> postProcessingVariables = this->getPostProcessingVariables(statistic);
+            uint n_arrs = uint(postProcessingVariables.size());
+
+            uint arrOff = probeStruct->arrayOffsetsH[var];
+
+            for(uint arr=0; arr<n_arrs; arr++)
+            {
+                real coeff = postProcessingVariables[arr].conversionFactor(level);
+                for(uint point=0; point<probeStruct->nPoints; point++)
+                {
+                    timestep_array[val] = probeStruct->quantitiesArrayH[calcArrayIndex(point, probeStruct->nPoints, timestep, probeStruct->nTimesteps, arrOff+arr)]*coeff;
+                    val++;
+                }
+            }
+            
+        }
+        out.write((char*) timestep_array, sizeof(real)*vals_per_timestep);
+    }
+    out.close();
+}
+
+
+
 std::vector<std::string> Probe::getVarNames()
 {
     std::vector<std::string> varNames;
@@ -454,4 +597,4 @@ std::vector<std::string> Probe::getVarNames()
         }
     }
     return varNames;
-}
\ No newline at end of file
+}
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/Probe.h b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/Probe.h
index aaf294e87d23c64707a16692b9337d6e9ff9c896..c7391e2a3d6b858facfd4fba094d7942f2bf4505 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/Probe.h
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/Probe.h
@@ -100,7 +100,11 @@ typedef struct PostProcessingVariable{
 } PostProcessingVariable;
 
 struct ProbeStruct{
-    uint nPoints, nIndices, nArrays, vals;
+    uint nPoints, nIndices, nArrays;
+    uint nTimesteps=1;
+    uint timestepInTimeseries=0;
+    uint timestepInTimeAverage=0;
+    uint lastTimestepInOldTimeseries=0;
     uint *pointIndicesH, *pointIndicesD;
     real *pointCoordsX, *pointCoordsY, *pointCoordsZ;
     bool hasDistances=false;
@@ -110,9 +114,10 @@ struct ProbeStruct{
     uint *arrayOffsetsH, *arrayOffsetsD;
     bool isEvenTAvg = true;
 };
+__host__ __device__ int calcArrayIndex(int node, int nNodes, int timestep, int nTimesteps, int array);
 
 __global__ void calcQuantitiesKernel(   uint* pointIndices,
-                                    uint nPoints, uint n,
+                                    uint nPoints, uint oldTimestepInTimeseries, uint timestepInTimeseries, uint timestepInAverage, uint nTimesteps,
                                     real* vx, real* vy, real* vz, real* rho,            
                                     uint* neighborX, uint* neighborY, uint* neighborZ,
                                     bool* quantities,
@@ -120,7 +125,7 @@ __global__ void calcQuantitiesKernel(   uint* pointIndices,
                                 );
 
 __global__ void interpAndCalcQuantitiesKernel(   uint* pointIndices,
-                                    uint nPoints, uint n,
+                                    uint nPoints, uint oldTimestepInTimeseries, uint timestepInTimeseries, uint timestepInAverage, uint nTimesteps,
                                     real* distX, real* distY, real* distZ,
                                     real* vx, real* vy, real* vz, real* rho,            
                                     uint* neighborX, uint* neighborY, uint* neighborZ,
@@ -128,6 +133,7 @@ __global__ void interpAndCalcQuantitiesKernel(   uint* pointIndices,
                                     uint* quantityArrayOffsets, real* quantityArray
                                 );
 
+uint calcOldTimestep(uint currentTimestep, uint lastTimestepInOldSeries);
 
 class Probe : public PreCollisionInteractor 
 {
@@ -135,13 +141,13 @@ public:
     Probe(
         const std::string _probeName,
         const std::string _outputPath,
-        uint _tStartAvg,
-        uint _tStartTmpAvg,
-        uint _tAvg,
-        uint _tStartOut,
-        uint _tOut,
-        bool _hasDeviceQuantityArray,
-        bool _outputTimeSeries
+        const uint _tStartAvg,
+        const uint _tStartTmpAvg,
+        const uint _tAvg,
+        const uint _tStartOut,
+        const uint _tOut,
+        const bool _hasDeviceQuantityArray,
+        const bool _outputTimeSeries
     ):  probeName(_probeName),
         outputPath(_outputPath),
         tStartAvg(_tStartAvg),
@@ -153,13 +159,12 @@ public:
         outputTimeSeries(_outputTimeSeries),        
         PreCollisionInteractor()
     {
-        if (_tStartOut<_tStartAvg)      throw std::runtime_error("Probe: tStartOut must be larger than tStartAvg!");
+        if (tStartOut < tStartAvg)      throw std::runtime_error("Probe: tStartOut must be larger than tStartAvg!");
     }
     
     void init(Parameter* para, GridProvider* gridProvider, CudaMemoryManager* cudaMemoryManager) override;
     void interact(Parameter* para, CudaMemoryManager* cudaMemoryManager, int level, uint t) override;
     void free(Parameter* para, CudaMemoryManager* cudaMemoryManager) override;
-    virtual void getTaggedFluidNodes(Parameter *para, GridProvider* gridProvider) override;
 
     SPtr<ProbeStruct> getProbeStruct(int level){ return this->probeParams[level]; }
 
@@ -170,7 +175,6 @@ public:
     uint getTStartTmpAveraging(){return this->tStartTmpAveraging;}
 
     void setFileNameToNOut(){this->fileNameLU = false;}
-    void setTStartTmpAveraging(uint _tStartTmpAveraging){this->tStartTmpAveraging = _tStartTmpAveraging;}
 
 protected:
     virtual WbWriterVtkXmlBinary* getWriter(){ return WbWriterVtkXmlBinary::getInstance(); };
@@ -185,7 +189,7 @@ private:
                        std::vector<real>& distX_level, std::vector<real>& distY_level, std::vector<real>& distZ_level,      
                        std::vector<real>& pointCoordsX_level, std::vector<real>& pointCoordsY_level, std::vector<real>& pointCoordsZ_level,
                        int level) = 0;
-    void addProbeStruct(CudaMemoryManager* cudaMemoryManager, std::vector<int>& probeIndices,
+    void addProbeStruct(Parameter* para, CudaMemoryManager* cudaMemoryManager, std::vector<int>& probeIndices,
                         std::vector<real>& distX, std::vector<real>& distY, std::vector<real>& distZ,   
                         std::vector<real>& pointCoordsX, std::vector<real>& pointCoordsY, std::vector<real>& pointCoordsZ,
                         int level);
@@ -194,10 +198,15 @@ private:
     virtual void write(Parameter* para, int level, int t);
     virtual void writeParallelFile(Parameter* para, int t);
     virtual void writeGridFile(Parameter* para, int level, int t, uint part);
+    std::string writeTimeseriesHeader(Parameter* para, int level);
+    void appendTimeseriesFile(Parameter* para, int level, int t);
 
     std::vector<std::string> getVarNames();
     std::string makeGridFileName(int level, int id, int t, uint part);
     std::string makeParallelFileName(int id, int t);
+    std::string makeTimeseriesFileName(int leve, int id);
+
+    virtual uint getNumberOfTimestepsInTimeseries(Parameter* para, int level){ return 1; }
 
 protected:
     const std::string probeName;
@@ -205,20 +214,19 @@ protected:
 
     std::vector<SPtr<ProbeStruct>> probeParams;
     bool quantities[int(Statistic::LAST)] = {};
-    bool hasDeviceQuantityArray;    //!> flag initiating memCopy in Point and PlaneProbe. Other probes are only based on thrust reduce functions and therefore dont need explict memCopy in interact()
-    bool outputTimeSeries;          //!> flag initiating overwrite of output vtk files, skipping collection files and limiting the length of the written data to the current time step (currently only used for WallModelProbe)
+    const bool hasDeviceQuantityArray;    //!> flag initiating memCopy in Point and PlaneProbe. Other probes are only based on thrust reduce functions and therefore dont need explict memCopy in interact()
+    const bool outputTimeSeries;        //!> flag initiating time series output in Point and WallModelProbe.
     std::vector<std::string> fileNamesForCollectionFile;
+    std::vector<std::string> timeseriesFileNames;
 
     bool fileNameLU = true; //!> if true, written file name contains time step in LU, else is the number of the written probe files
 
 protected:
-    uint tStartAvg;
-    uint tStartTmpAveraging; //!> only non-zero in PlanarAverageProbe and WallModelProbe to switch on Spatio-temporal averaging (while only doing spatial averaging for t<tStartTmpAveraging) 
-    uint tAvg;  //! for tAvg==1 the probe will be evaluated in every sub-timestep of each respective level, else, the probe will only be evaluated in each synchronous time step 
-    uint tStartOut;
-    uint tOut;
-
-    uint tProbe = 0; //!> counter for number of probe evaluations. Only used when outputting timeseries
+    const uint tStartAvg;
+    const uint tStartTmpAveraging; //!> only non-zero in PlanarAverageProbe and WallModelProbe to switch on Spatio-temporal averaging (while only doing spatial averaging for t<tStartTmpAveraging) 
+    const uint tAvg;  //! for tAvg==1 the probe will be evaluated in every sub-timestep of each respective level, else, the probe will only be evaluated in each synchronous time step 
+    const uint tStartOut;
+    const uint tOut;
 
     std::function<real(int)> velocityRatio;
     std::function<real(int)> densityRatio;
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/WallModelProbe.cu b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/WallModelProbe.cu
index 3341111c134ace7ca6ff64eeb7f87b38f8014656..f52c666c920a049012888e8e1b71578e68d3da31 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/WallModelProbe.cu
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/WallModelProbe.cu
@@ -10,63 +10,15 @@
 #include <thrust/device_vector.h>
 #include <thrust/reduce.h>
 #include <thrust/device_ptr.h>
-#include <thrust/inner_product.h>
 
 #include "Parameter/Parameter.h"
 #include "DataStructureInitializer/GridProvider.h"
 #include "GPU/CudaMemoryManager.h"
+#include "basics/constants/NumericConstants.h"
 
-
-///////////////////////////////////////////////////////////////////////////////////
-/// Functors for thrust reductions
-///////////////////////////////////////////////////////////////////////////////////
-
-template<typename T>
-struct pow2 : public thrust::unary_function<T,T>
-{
-  __host__ __device__ T operator()(const T &x) const
-  {
-    return x * x;
-  }
-};
-
-template<typename T>
-struct pow3 : public thrust::unary_function<T,T>
-{
-  __host__ __device__ T operator()(const T &x) const
-  {
-    return x * x * x;
-  }
-};
-
-template<typename T>
-struct pow4 : public thrust::unary_function<T,T>
-{
-  __host__ __device__ T operator()(const T &x) const
-  {
-    return x * x * x * x;
-  }
-};
-
-struct nth_moment
-{
-    const float mean;
-    const int n;
-
-    nth_moment(float _mean, int _n) : mean(_mean), n(_n) {}
-
-    __host__ __device__
-        float operator()(const float& x) const { 
-            
-            real fluctuation = x-mean;
-            real moment = fluctuation;
-            for(int i = 1; i<n; i++) moment *= fluctuation;
-            
-            return moment;
-        }
-};
-
-
+using namespace vf::basics::constant;
+typedef thrust::device_vector<real>::iterator valIterator;
+typedef thrust::device_vector<uint>::iterator indIterator;
 ///////////////////////////////////////////////////////////////////////////////////
 bool WallModelProbe::isAvailableStatistic(Statistic _variable)
 {
@@ -156,16 +108,10 @@ void WallModelProbe::findPoints(Parameter* para, GridProvider* gridProvider, std
                             int level)
 {
     if ( !para->getHasWallModelMonitor())                    throw std::runtime_error("WallModelProbe::findPoints(): !para->getHasWallModelMonitor() !");
-
-    real dt = para->getTimeRatio();
-    uint nt = uint((para->getTimestepEnd()-this->tStartAvg)/this->tAvg);
     
-    for(uint t=0; t<nt; t++)
-    {
-        pointCoordsX_level.push_back(dt*(t*this->tAvg)+this->tStartAvg); // x coord will serve as time in this probe
-        pointCoordsY_level.push_back(0);
-        pointCoordsZ_level.push_back(0);
-    }
+    pointCoordsX_level.push_back(0); 
+    pointCoordsY_level.push_back(0);
+    pointCoordsZ_level.push_back(0);
 
     if(this->evaluatePressureGradient)
     {
@@ -183,118 +129,109 @@ void WallModelProbe::findPoints(Parameter* para, GridProvider* gridProvider, std
 
 ///////////////////////////////////////////////////////////////////////////////////
 
+template<typename T>
+T spatial_mean(T* device_pointer, uint numberOfPoints)
+{
+    thrust::device_ptr<T> thrust_pointer = thrust::device_pointer_cast(device_pointer);
+    return thrust::reduce(thrust_pointer, thrust_pointer+numberOfPoints)/real(numberOfPoints);
+}
+
+template<typename T>
+T index_based_spatial_mean(T* device_pointer, thrust::device_ptr<uint> indeces_ptr, uint numberOfIndeces)
+{
+    thrust::device_ptr<T> thrust_pointer = thrust::device_pointer_cast(device_pointer);
+
+    thrust::permutation_iterator<valIterator, indIterator> iter_begin(thrust_pointer, indeces_ptr);
+    thrust::permutation_iterator<valIterator, indIterator> iter_end  (thrust_pointer, indeces_ptr+numberOfIndeces);
+    return thrust::reduce(iter_begin, iter_end)/real(numberOfIndeces);
+}
+
+template<typename T>
+T compute_and_save_mean(T* device_pointer, uint numberOfPoints, T* quantitiesArray, uint timestep, uint numberOfTimesteps, uint indexOfArray)
+{
+    T mean = spatial_mean(device_pointer, numberOfPoints);
+    quantitiesArray[calcArrayIndex(0, 1, timestep, numberOfTimesteps, indexOfArray)] = mean;
+    return mean;
+}
+
+template<typename T>
+T compute_and_save_index_based_mean(T* device_pointer, thrust::device_ptr<uint> indeces_ptr, uint numberOfIndices, T* quantitiesArray, uint timestep, uint numberOfTimesteps, uint indexOfArray)
+{
+    T mean = index_based_spatial_mean(device_pointer, indeces_ptr, numberOfIndices);
+    quantitiesArray[calcArrayIndex(0, 1, timestep, numberOfTimesteps, indexOfArray)] = mean;
+    return mean;
+}
+
+template<typename T>
+void temporal_average(T* quantitiesArray, T currentValue, uint currentTimestep, uint numberOfTimesteps, uint oldTimestep, uint indexOfArray, real invNumberOfAverages)
+{
+    T oldMean = quantitiesArray[calcArrayIndex(0, 1, oldTimestep, numberOfTimesteps, indexOfArray)];
+    quantitiesArray[calcArrayIndex(0, 1, currentTimestep, numberOfTimesteps, indexOfArray)] = oldMean + (currentValue-oldMean)*invNumberOfAverages;
+}
+
 void WallModelProbe::calculateQuantities(SPtr<ProbeStruct> probeStruct, Parameter* para, uint t, int level)
 {   
     bool doTmpAveraging = (t>this->getTStartTmpAveraging());
-    real N = para->getParD(level)->stressBC.numberOfBCnodes;
-    if(N<1) return; //Skipping levels without StressBC
-    real n = (real)probeStruct->vals;
-    int nPoints = probeStruct->nPoints;
-
-    // Pointer casts to use device arrays in thrust reductions
-    thrust::device_ptr<real> u_el_thrust    = thrust::device_pointer_cast(para->getParD(level)->stressBC.Vx);
-    thrust::device_ptr<real> v_el_thrust    = thrust::device_pointer_cast(para->getParD(level)->stressBC.Vy);
-    thrust::device_ptr<real> w_el_thrust    = thrust::device_pointer_cast(para->getParD(level)->stressBC.Vz);
-    thrust::device_ptr<real> u1_thrust      = thrust::device_pointer_cast(para->getParD(level)->stressBC.Vx1);
-    thrust::device_ptr<real> v1_thrust      = thrust::device_pointer_cast(para->getParD(level)->stressBC.Vy1);
-    thrust::device_ptr<real> w1_thrust      = thrust::device_pointer_cast(para->getParD(level)->stressBC.Vz1);
-    thrust::device_ptr<real> u_star_thrust  = thrust::device_pointer_cast(para->getParD(level)->wallModel.u_star);
-    thrust::device_ptr<real> Fx_thrust      = thrust::device_pointer_cast(para->getParD(level)->wallModel.Fx);
-    thrust::device_ptr<real> Fy_thrust      = thrust::device_pointer_cast(para->getParD(level)->wallModel.Fy);
-    thrust::device_ptr<real> Fz_thrust      = thrust::device_pointer_cast(para->getParD(level)->wallModel.Fz);
-    thrust::device_ptr<real> dpdx_thrust    = thrust::device_pointer_cast(para->getParD(level)->forceX_SP);
-    thrust::device_ptr<real> dpdy_thrust    = thrust::device_pointer_cast(para->getParD(level)->forceY_SP);
-    thrust::device_ptr<real> dpdz_thrust    = thrust::device_pointer_cast(para->getParD(level)->forceZ_SP);
+    uint numberOfStressBCPoints = para->getParD(level)->stressBC.numberOfBCnodes;
+    if(numberOfStressBCPoints<1) return; //Skipping levels without StressBC
+    uint timestep = probeStruct->timestepInTimeseries;
+    real inv_n = c1o1/real(probeStruct->timestepInTimeAverage+1);
+    uint oldTimestep = calcOldTimestep(timestep, probeStruct->lastTimestepInOldTimeseries);
 
     thrust::device_ptr<uint> indices_thrust = thrust::device_pointer_cast(probeStruct->pointIndicesD);
-    typedef thrust::device_vector<real>::iterator valIterator;
-    typedef thrust::device_vector<uint>::iterator indIterator;
-    thrust::permutation_iterator<valIterator, indIterator> dpdx_iter_begin(dpdx_thrust, indices_thrust);
-    thrust::permutation_iterator<valIterator, indIterator> dpdx_iter_end  (dpdx_thrust, indices_thrust+probeStruct->nIndices);
-    thrust::permutation_iterator<valIterator, indIterator> dpdy_iter_begin(dpdy_thrust, indices_thrust);
-    thrust::permutation_iterator<valIterator, indIterator> dpdy_iter_end  (dpdy_thrust, indices_thrust+probeStruct->nIndices);
-    thrust::permutation_iterator<valIterator, indIterator> dpdz_iter_begin(dpdz_thrust, indices_thrust);
-    thrust::permutation_iterator<valIterator, indIterator> dpdz_iter_end  (dpdz_thrust, indices_thrust+probeStruct->nIndices);
 
     if(probeStruct->quantitiesH[int(Statistic::SpatialMeans)])
     {
-        // Compute the instantaneous spatial means of the velocity moments 
-        real spatMean_u_el      = thrust::reduce(u_el_thrust, u_el_thrust+N)/N;
-        real spatMean_v_el      = thrust::reduce(v_el_thrust, v_el_thrust+N)/N;
-        real spatMean_w_el      = thrust::reduce(w_el_thrust, w_el_thrust+N)/N;
-        real spatMean_u1        = thrust::reduce(u1_thrust, u1_thrust+N)/N;
-        real spatMean_v1        = thrust::reduce(v1_thrust, v1_thrust+N)/N;
-        real spatMean_w1        = thrust::reduce(w1_thrust, w1_thrust+N)/N;
-        real spatMean_u_star    = thrust::reduce(u_star_thrust, u_star_thrust+N)/N;
-        real spatMean_Fx        = thrust::reduce(Fx_thrust, Fx_thrust+N)/N;
-        real spatMean_Fy        = thrust::reduce(Fy_thrust, Fy_thrust+N)/N;
-        real spatMean_Fz        = thrust::reduce(Fz_thrust, Fz_thrust+N)/N;
-
         uint arrOff = probeStruct->arrayOffsetsH[int(Statistic::SpatialMeans)];
-        probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+tProbe] = spatMean_u_el;
-        probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+tProbe] = spatMean_v_el;
-        probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+tProbe] = spatMean_w_el;
-        probeStruct->quantitiesArrayH[(arrOff+3)*nPoints+tProbe] = spatMean_u1;
-        probeStruct->quantitiesArrayH[(arrOff+4)*nPoints+tProbe] = spatMean_v1;
-        probeStruct->quantitiesArrayH[(arrOff+5)*nPoints+tProbe] = spatMean_w1;
-        probeStruct->quantitiesArrayH[(arrOff+6)*nPoints+tProbe] = spatMean_u_star;
-        probeStruct->quantitiesArrayH[(arrOff+7)*nPoints+tProbe] = spatMean_Fx;
-        probeStruct->quantitiesArrayH[(arrOff+8)*nPoints+tProbe] = spatMean_Fy;
-        probeStruct->quantitiesArrayH[(arrOff+9)*nPoints+tProbe] = spatMean_Fz;
+        // Compute the instantaneous spatial means of the velocity moments 
+        real spatMean_u_el      = compute_and_save_mean(para->getParD(level)->stressBC.Vx     , numberOfStressBCPoints, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+0);
+        real spatMean_v_el      = compute_and_save_mean(para->getParD(level)->stressBC.Vy     , numberOfStressBCPoints, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+1);
+        real spatMean_w_el      = compute_and_save_mean(para->getParD(level)->stressBC.Vz     , numberOfStressBCPoints, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+2);
+        real spatMean_u1        = compute_and_save_mean(para->getParD(level)->stressBC.Vx1    , numberOfStressBCPoints, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+3);
+        real spatMean_v1        = compute_and_save_mean(para->getParD(level)->stressBC.Vy1    , numberOfStressBCPoints, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+4);
+        real spatMean_w1        = compute_and_save_mean(para->getParD(level)->stressBC.Vz1    , numberOfStressBCPoints, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+5);
+        real spatMean_u_star    = compute_and_save_mean(para->getParD(level)->wallModel.u_star, numberOfStressBCPoints, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+6);
+        real spatMean_Fx        = compute_and_save_mean(para->getParD(level)->wallModel.Fx    , numberOfStressBCPoints, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+7);
+        real spatMean_Fy        = compute_and_save_mean(para->getParD(level)->wallModel.Fy    , numberOfStressBCPoints, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+8);
+        real spatMean_Fz        = compute_and_save_mean(para->getParD(level)->wallModel.Fz    , numberOfStressBCPoints, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+9);
 
         real spatMean_dpdx;
         real spatMean_dpdy;
         real spatMean_dpdz;
         if(this->evaluatePressureGradient)
         {
-            real N_fluid = (real)probeStruct->nIndices;
-            spatMean_dpdx      = thrust::reduce(dpdx_iter_begin, dpdx_iter_end)/N_fluid;
-            spatMean_dpdy      = thrust::reduce(dpdy_iter_begin, dpdy_iter_end)/N_fluid;
-            spatMean_dpdz      = thrust::reduce(dpdz_iter_begin, dpdz_iter_end)/N_fluid;
-            probeStruct->quantitiesArrayH[(arrOff+10)*nPoints+tProbe] = spatMean_dpdx;
-            probeStruct->quantitiesArrayH[(arrOff+11)*nPoints+tProbe] = spatMean_dpdy;
-            probeStruct->quantitiesArrayH[(arrOff+12)*nPoints+tProbe] = spatMean_dpdz;
+            spatMean_dpdx = compute_and_save_index_based_mean(para->getParD(level)->forceX_SP, indices_thrust, probeStruct->nIndices, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+10);
+            spatMean_dpdy = compute_and_save_index_based_mean(para->getParD(level)->forceY_SP, indices_thrust, probeStruct->nIndices, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+11);
+            spatMean_dpdz = compute_and_save_index_based_mean(para->getParD(level)->forceZ_SP, indices_thrust, probeStruct->nIndices, probeStruct->quantitiesArrayH, timestep, probeStruct->nTimesteps, arrOff+12);
         }
 
         if(probeStruct->quantitiesH[int(Statistic::SpatioTemporalMeans)] && doTmpAveraging)
         {
             uint arrOff = probeStruct->arrayOffsetsH[int(Statistic::SpatioTemporalMeans)];
-            real spatMean_u_el_old      = probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+tProbe-1];
-            real spatMean_v_el_old      = probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+tProbe-1];
-            real spatMean_w_el_old      = probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+tProbe-1];
-            real spatMean_u1_old        = probeStruct->quantitiesArrayH[(arrOff+3)*nPoints+tProbe-1];
-            real spatMean_v1_old        = probeStruct->quantitiesArrayH[(arrOff+4)*nPoints+tProbe-1];
-            real spatMean_w1_old        = probeStruct->quantitiesArrayH[(arrOff+5)*nPoints+tProbe-1];
-            real spatMean_u_star_old    = probeStruct->quantitiesArrayH[(arrOff+6)*nPoints+tProbe-1];
-            real spatMean_Fx_old        = probeStruct->quantitiesArrayH[(arrOff+7)*nPoints+tProbe-1];
-            real spatMean_Fy_old        = probeStruct->quantitiesArrayH[(arrOff+8)*nPoints+tProbe-1];
-            real spatMean_Fz_old        = probeStruct->quantitiesArrayH[(arrOff+9)*nPoints+tProbe-1];
-
-            probeStruct->quantitiesArrayH[(arrOff+0)*nPoints+tProbe] = spatMean_u_el_old + (spatMean_u_el-spatMean_u_el_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+1)*nPoints+tProbe] = spatMean_v_el_old + (spatMean_v_el-spatMean_v_el_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+2)*nPoints+tProbe] = spatMean_w_el_old + (spatMean_w_el-spatMean_w_el_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+3)*nPoints+tProbe] = spatMean_u1_old + (spatMean_u1-spatMean_u1_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+4)*nPoints+tProbe] = spatMean_v1_old + (spatMean_v1-spatMean_v1_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+5)*nPoints+tProbe] = spatMean_w1_old + (spatMean_w1-spatMean_w1_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+6)*nPoints+tProbe] = spatMean_u_star_old +(spatMean_u_star-spatMean_u_star_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+7)*nPoints+tProbe] = spatMean_Fx_old + (spatMean_Fx-spatMean_Fx_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+8)*nPoints+tProbe] = spatMean_Fy_old + (spatMean_Fy-spatMean_Fy_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+9)*nPoints+tProbe] = spatMean_Fz_old + (spatMean_Fz-spatMean_Fz_old)/n;
+            temporal_average(probeStruct->quantitiesArrayH, spatMean_u_el  , timestep, probeStruct->nTimesteps, oldTimestep, arrOff+0, inv_n);
+            temporal_average(probeStruct->quantitiesArrayH, spatMean_v_el  , timestep, probeStruct->nTimesteps, oldTimestep, arrOff+1, inv_n);
+            temporal_average(probeStruct->quantitiesArrayH, spatMean_w_el  , timestep, probeStruct->nTimesteps, oldTimestep, arrOff+2, inv_n);
+            temporal_average(probeStruct->quantitiesArrayH, spatMean_u1    , timestep, probeStruct->nTimesteps, oldTimestep, arrOff+3, inv_n);
+            temporal_average(probeStruct->quantitiesArrayH, spatMean_v1    , timestep, probeStruct->nTimesteps, oldTimestep, arrOff+4, inv_n);
+            temporal_average(probeStruct->quantitiesArrayH, spatMean_w1    , timestep, probeStruct->nTimesteps, oldTimestep, arrOff+5, inv_n);
+            temporal_average(probeStruct->quantitiesArrayH, spatMean_u_star, timestep, probeStruct->nTimesteps, oldTimestep, arrOff+6, inv_n);
+            temporal_average(probeStruct->quantitiesArrayH, spatMean_Fx    , timestep, probeStruct->nTimesteps, oldTimestep, arrOff+7, inv_n);
+            temporal_average(probeStruct->quantitiesArrayH, spatMean_Fy    , timestep, probeStruct->nTimesteps, oldTimestep, arrOff+8, inv_n);
+            temporal_average(probeStruct->quantitiesArrayH, spatMean_Fz    , timestep, probeStruct->nTimesteps, oldTimestep, arrOff+9, inv_n);
 
             if(this->evaluatePressureGradient)
             {
-            real spatMean_dpdx_old     = probeStruct->quantitiesArrayH[(arrOff+10)*nPoints+tProbe-1];
-            real spatMean_dpdy_old     = probeStruct->quantitiesArrayH[(arrOff+11)*nPoints+tProbe-1];
-            real spatMean_dpdz_old     = probeStruct->quantitiesArrayH[(arrOff+12)*nPoints+tProbe-1];
-            probeStruct->quantitiesArrayH[(arrOff+10)*nPoints+tProbe] = spatMean_dpdx_old + (spatMean_dpdx-spatMean_dpdx_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+11)*nPoints+tProbe] = spatMean_dpdy_old + (spatMean_dpdy-spatMean_dpdy_old)/n;
-            probeStruct->quantitiesArrayH[(arrOff+12)*nPoints+tProbe] = spatMean_dpdz_old + (spatMean_dpdz-spatMean_dpdz_old)/n;
+                temporal_average(probeStruct->quantitiesArrayH, spatMean_dpdx, timestep, probeStruct->nTimesteps, oldTimestep, arrOff+10, inv_n);
+                temporal_average(probeStruct->quantitiesArrayH, spatMean_dpdy, timestep, probeStruct->nTimesteps, oldTimestep, arrOff+11, inv_n);
+                temporal_average(probeStruct->quantitiesArrayH, spatMean_dpdz, timestep, probeStruct->nTimesteps, oldTimestep, arrOff+12, inv_n);
             }
         }    
     }
-        
-
-    this->tProbe += 1;
     getLastCudaError("WallModelProbe::calculateQuantities execution failed");
 }
 
+uint WallModelProbe::getNumberOfTimestepsInTimeseries(Parameter* para, int level)
+{
+    return this->tOut*exp2(level)/this->tAvg+1; 
+}
+
diff --git a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/WallModelProbe.h b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/WallModelProbe.h
index 4ea90f74c7a0d57af4995e1b5874234967f1e901..c912656d2dcbb9551b8a156f7fe9818de0f315a4 100644
--- a/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/WallModelProbe.h
+++ b/src/gpu/VirtualFluids_GPU/PreCollisionInteractor/Probes/WallModelProbe.h
@@ -81,6 +81,8 @@ private:
                     std::vector<real>& pointCoordsX_level, std::vector<real>& pointCoordsY_level, std::vector<real>& pointCoordsZ_level,
                     int level) override;
     void calculateQuantities(SPtr<ProbeStruct> probeStruct, Parameter* para, uint t, int level) override;
+    void getTaggedFluidNodes(Parameter *para, GridProvider* gridProvider) override {};
+    uint getNumberOfTimestepsInTimeseries(Parameter* para, int level) override;
 
 private:
     bool outputStress = false; //!> if true, output wall force is converted to a stress 
diff --git a/src/lbm/MacroscopicQuantities.h b/src/lbm/MacroscopicQuantities.h
index 5a93222a5efae2d1814411053360d66ef132d62c..e1b066a104874a95701ff3a77f6747884c5a54d7 100644
--- a/src/lbm/MacroscopicQuantities.h
+++ b/src/lbm/MacroscopicQuantities.h
@@ -53,6 +53,14 @@ inline __host__ __device__ real getIncompressibleVelocityX3(const real *const &f
             (((f[dir::DIR_0MP] - f[dir::DIR_0PM]) + (f[dir::DIR_0PP] - f[dir::DIR_0MM])) + ((f[dir::DIR_M0P] - f[dir::DIR_P0M]) + (f[dir::DIR_P0P] - f[dir::DIR_M0M]))) + (f[dir::DIR_00P] - f[dir::DIR_00M]));
 }
 
+inline __host__ __device__ void getIncompressibleMacroscopicValues(const real *const &f /*[27]*/, real &rho, real &vx1, real &vx2, real &vx3)
+{
+    rho = getDensity(f);
+    vx1 = getIncompressibleVelocityX1(f);
+    vx2 = getIncompressibleVelocityX2(f);
+    vx3 = getIncompressibleVelocityX3(f);
+}
+
 
 
 /*
@@ -75,6 +83,25 @@ inline __host__ __device__ real getCompressibleVelocityX3(const real *const &f27
     return getIncompressibleVelocityX3(f27) / (rho + basics::constant::c1o1);
 }
 
+inline __host__ __device__ void getCompressibleMacroscopicValues(const real *const &f /*[27]*/, real &drho, real& oneOverRho, real &vx1, real &vx2, real &vx3)
+{
+    drho = getDensity(f);
+    vx1 = getIncompressibleVelocityX1(f);
+    vx2 = getIncompressibleVelocityX2(f);
+    vx3 = getIncompressibleVelocityX3(f);
+    oneOverRho = vf::basics::constant::c1o1 / (drho + vf::basics::constant::c1o1);
+    vx1 *= oneOverRho;
+    vx2 *= oneOverRho;
+    vx3 *= oneOverRho;
+}
+
+inline __host__ __device__ void getCompressibleMacroscopicValues(const real *const &f /*[27]*/, real &drho, real &vx1, real &vx2, real &vx3)
+{
+    real oneOverRho;
+    getCompressibleMacroscopicValues(f, drho, oneOverRho, vx1, vx2, vx3);
+}
+
+
 /*
 * Pressure
 */
diff --git a/src/lbm/MacroscopicQuantitiesTests.cpp b/src/lbm/MacroscopicQuantitiesTests.cpp
index 382ec180e7a97749c4a005734a61f96ec7a146d5..b39387ae7ac741cc4dc36b4c58de4bad43052793 100644
--- a/src/lbm/MacroscopicQuantitiesTests.cpp
+++ b/src/lbm/MacroscopicQuantitiesTests.cpp
@@ -1,30 +1,43 @@
 #include <gmock/gmock.h>
+#include <array>
 
 #include "MacroscopicQuantities.h"
 #include "constants/D3Q27.h"
 
+#include <basics/tests/testUtilities.h>
+
 
 /*
 * given distributions, which are all one.
 */
-real f[27] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+// real f[27] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+
+class MacroscopicQuantitiesTest : public testing::Test {
+
+    void SetUp() override {
+       f = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+    }
+
+    public:
+    std::array<real, 27> f;
+};
 
 using namespace vf::lbm;
 
 
-TEST(MacroscopicQuantitiesTest, check_density)
+TEST_F(MacroscopicQuantitiesTest, check_density)
 {
-    const double density = getDensity(f);
+    const double density = getDensity(f.data());
 
     const double expected_density = 27.;
     ASSERT_THAT(density, testing::DoubleEq(expected_density));
 }
 
-TEST(MacroscopicQuantitiesTest, whenFsAreEqual_velocityInEachDirectionShouldBeZero)
+TEST_F(MacroscopicQuantitiesTest, whenFsAreEqual_velocityInEachDirectionShouldBeZero)
 {
-    const double velocityX1 = getIncompressibleVelocityX1(f);
-    const double velocityX2 = getIncompressibleVelocityX2(f);
-    const double velocityX3 = getIncompressibleVelocityX3(f);
+    const double velocityX1 = getIncompressibleVelocityX1(f.data());
+    const double velocityX2 = getIncompressibleVelocityX2(f.data());
+    const double velocityX3 = getIncompressibleVelocityX3(f.data());
 
     const double expected_velocity = 0.;
     EXPECT_THAT(velocityX1, testing::DoubleEq(expected_velocity));
@@ -32,13 +45,13 @@ TEST(MacroscopicQuantitiesTest, whenFsAreEqual_velocityInEachDirectionShouldBeZe
     EXPECT_THAT(velocityX3, testing::DoubleEq(expected_velocity));
 }
 
-TEST(MacroscopicQuantitiesTest, givenAllFsAreOne_when_Eis2_velocityInX1ShouldBeOne)
+TEST_F(MacroscopicQuantitiesTest, givenAllFsAreOne_when_Eis2_velocityInX1ShouldBeOne)
 {
     f[dir::DIR_P00] = 2.;
 
-    const double velocityX1 = getIncompressibleVelocityX1(f);
-    const double velocityX2 = getIncompressibleVelocityX2(f);
-    const double velocityX3 = getIncompressibleVelocityX3(f);
+    const double velocityX1 = getIncompressibleVelocityX1(f.data());
+    const double velocityX2 = getIncompressibleVelocityX2(f.data());
+    const double velocityX3 = getIncompressibleVelocityX3(f.data());
 
     const double expected_velocity_x1 = 1.;
     const double expected_velocity_x2 = 0.;
@@ -49,23 +62,41 @@ TEST(MacroscopicQuantitiesTest, givenAllFsAreOne_when_Eis2_velocityInX1ShouldBeO
     EXPECT_THAT(velocityX3, testing::DoubleEq(expected_velocity_x3));
 }
 
-TEST(MacroscopicQuantitiesTest, givenAllFsAreOne_when_Nis2_velocityInX2ShouldBeOne)
+TEST_F(MacroscopicQuantitiesTest, givenAllFsAreOne_when_Nis2_velocityInX2ShouldBeOne)
 {
     f[dir::DIR_0P0] = 2.;
 
-    const double velocity = getIncompressibleVelocityX2(f);
+    const double velocity = getIncompressibleVelocityX2(f.data());
 
     const double expected_velocity = 1.;
     ASSERT_THAT(velocity, testing::DoubleEq(expected_velocity));
 }
 
 
-TEST(MacroscopicQuantitiesTest, givenAllFsAreOne_when_Tis2_velocityInX3ShouldBeOne)
+TEST_F(MacroscopicQuantitiesTest, givenAllFsAreOne_when_Tis2_velocityInX3ShouldBeOne)
 {
     f[dir::DIR_00P] = 2.;
 
-    const double velocity = getIncompressibleVelocityX3(f);
+    const double velocity = getIncompressibleVelocityX3(f.data());
 
     const double expected_velocity = 1.;
     ASSERT_THAT(velocity, testing::DoubleEq(expected_velocity));
 }
+
+TEST_F(MacroscopicQuantitiesTest, givenAllFsAreOne_checkCompressibleValues)
+{
+    f[dir::DIR_P00] = 2.;
+
+    real rho{0}, vx1{0}, vx2{0}, vx3{0};
+    getCompressibleMacroscopicValues(f.data(), rho, vx1, vx2, vx3);
+
+    std::cout << getIncompressibleVelocityX1(f.data()) << std::endl;
+
+    const real expected_rho = 28.;
+    const real expected_velocity = (1. / (1 + expected_rho));
+
+    EXPECT_THAT(rho, RealEq(expected_rho));
+    EXPECT_THAT(vx1, RealEq(expected_velocity));
+    EXPECT_THAT(vx2, RealEq(0.));
+    EXPECT_THAT(vx3, RealEq(0.));
+}
diff --git a/src/lbm/refinement/Coefficients.h b/src/lbm/refinement/Coefficients.h
new file mode 100644
index 0000000000000000000000000000000000000000..441c2567327c34b67c52754e33c5087a4d3d253b
--- /dev/null
+++ b/src/lbm/refinement/Coefficients.h
@@ -0,0 +1,436 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  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/>.
+//
+//=======================================================================================
+#ifndef LBM_SCALING_HELPER_FUNCTIONS_H
+#define LBM_SCALING_HELPER_FUNCTIONS_H
+
+#ifndef __host__
+#define __host__
+#endif
+#ifndef __device__
+#define __device__
+#endif
+
+
+#include "lbm/constants/D3Q27.h"
+#include <basics/constants/NumericConstants.h>
+
+#include "lbm/KernelParameter.h"
+#include "lbm/MacroscopicQuantities.h"
+
+
+using namespace vf::basics::constant;
+using namespace vf::lbm::dir;
+
+namespace vf::lbm
+{
+
+// The Coefficients struct needs be created like this:
+// Coefficients coeffs;
+// MomentsOnSourceNodeSet momentsSet;
+// momentsSet.calculatePPP(f, omega);
+// ... and so on
+// Coefficients coeffs;
+// momentsSet.calculateCoefficients(coeffs);
+
+// Coefficient which are used in the interpolation
+struct Coefficients
+{
+    real a000, a100, a010, a001, a200, a020, a002, a110, a101, a011;
+    real b000, b100, b010, b001, b200, b020, b002, b110, b101, b011;
+    real c000, c100, c010, c001, c200, c020, c002, c110, c101, c011;
+    real d000, d100, d010, d001, d110, d101, d011;
+    real a111, b111, c111, d111;
+    real LaplaceRho;
+};
+
+
+// Private struct - is only used within the MomentsOnSourceNodeSet
+struct MomentsOnSourceNode 
+{
+    real drho;
+    real velocityX;
+    real velocityY;
+    real velocityZ;
+    real kxyFromfcNEQ;
+    real kyzFromfcNEQ;
+    real kxzFromfcNEQ;
+    real kxxMyyFromfcNEQ;
+    real kxxMzzFromfcNEQ;
+
+    __host__ __device__ void calculate(const real* const f, const real omega)
+    {
+        // const real f_000 = f[dir::DIR_000];
+        const real fP00 = f[dir::DIR_P00];
+        const real fM00 = f[dir::DIR_M00];
+        const real f0P0 = f[dir::DIR_0P0];
+        const real f0M0 = f[dir::DIR_0M0];
+        const real f00P = f[dir::DIR_00P];
+        const real f00M = f[dir::DIR_00M];
+        const real fPP0 = f[dir::DIR_PP0];
+        const real fMM0 = f[dir::DIR_MM0];
+        const real fPM0 = f[dir::DIR_PM0];
+        const real fMP0 = f[dir::DIR_MP0];
+        const real fP0P = f[dir::DIR_P0P];
+        const real fM0M = f[dir::DIR_M0M];
+        const real fP0M = f[dir::DIR_P0M];
+        const real fM0P = f[dir::DIR_M0P];
+        const real f0PP = f[dir::DIR_0PP];
+        const real f0MM = f[dir::DIR_0MM];
+        const real f0PM = f[dir::DIR_0PM];
+        const real f0MP = f[dir::DIR_0MP];
+        const real fPPP = f[dir::DIR_PPP];
+        const real fMPP = f[dir::DIR_MPP];
+        const real fPMP = f[dir::DIR_PMP];
+        const real fMMP = f[dir::DIR_MMP];
+        const real fPPM = f[dir::DIR_PPM];
+        const real fMPM = f[dir::DIR_MPM];
+        const real fPMM = f[dir::DIR_PMM];
+        const real fMMM = f[dir::DIR_MMM];
+
+        real oneOverRho;
+        getCompressibleMacroscopicValues(f, this->drho, oneOverRho, this->velocityX, this->velocityY, this->velocityZ);
+
+        ////////////////////////////////////////////////////////////////////////////////////
+        //! - Calculate second order moments for interpolation
+        //!
+        // example: kxxMzz: moment, second derivative in x direction minus the second derivative in z direction
+
+        this->kxyFromfcNEQ = -c3o1 * omega *
+                    ((fMM0 + fMMM + fMMP - fMP0 - fMPM - fMPP - fPM0 - fPMM - fPMP + fPP0 + fPPM + fPPP) *
+                        oneOverRho -
+                        ((this->velocityX * this->velocityY)));
+        this->kyzFromfcNEQ = -c3o1 * omega *
+                    ((f0MM + fPMM + fMMM - f0MP - fPMP - fMMP - f0PM - fPPM - fMPM + f0PP + fPPP + fMPP) *
+                        oneOverRho -
+                        ((this->velocityY * this->velocityZ)));
+        this->kxzFromfcNEQ = -c3o1 * omega *
+                    ((fM0M + fMMM + fMPM - fM0P - fMMP - fMPP - fP0M - fPMM - fPPM + fP0P + fPMP + fPPP) *
+                        oneOverRho -
+                        ((this->velocityX * this->velocityZ)));
+        this->kxxMyyFromfcNEQ = -c3o2 * omega *
+                        ((fM0M + fM00 + fM0P - f0MM - f0M0 - f0MP - f0PM - f0P0 - f0PP + fP0M + fP00 + fP0P) *
+                        oneOverRho -
+                        ((this->velocityX * this->velocityX - this->velocityY * this->velocityY)));
+        this->kxxMzzFromfcNEQ = -c3o2 * omega *
+                        ((fMM0 + fM00 + fMP0 - f0MM - f0MP - f00M - f00P - f0PM - f0PP + fPM0 + fP00 + fPP0) *
+                        oneOverRho -
+                        ((this->velocityX * this->velocityX - this->velocityZ * this->velocityZ)));
+    }
+
+};
+
+class MomentsOnSourceNodeSet
+{
+private:
+    vf::lbm::MomentsOnSourceNode momentsPPP;
+    vf::lbm::MomentsOnSourceNode momentsMPP;
+    vf::lbm::MomentsOnSourceNode momentsPMP;
+    vf::lbm::MomentsOnSourceNode momentsMMP;
+    vf::lbm::MomentsOnSourceNode momentsPPM;
+    vf::lbm::MomentsOnSourceNode momentsMPM;
+    vf::lbm::MomentsOnSourceNode momentsPMM;
+    vf::lbm::MomentsOnSourceNode momentsMMM;
+
+public:
+    __host__ __device__ void calculatePPP(const real *const f, const real omega)
+    {
+        momentsPPP.calculate(f, omega);
+    }
+
+    __host__ __device__ void calculateMPP(const real *const f, const real omega)
+    {
+        momentsMPP.calculate(f, omega);
+    }
+
+    __host__ __device__ void calculatePMP(const real *const f, const real omega)
+    {
+        momentsPMP.calculate(f, omega);
+    }
+
+    __host__ __device__ void calculateMMP(const real *const f, const real omega)
+    {
+        momentsMMP.calculate(f, omega);
+    }
+
+    __host__ __device__ void calculatePPM(const real *const f, const real omega)
+    {
+        momentsPPM.calculate(f, omega);
+    }
+
+    __host__ __device__ void calculateMPM(const real *const f, const real omega)
+    {
+        momentsMPM.calculate(f, omega);
+    }
+
+    __host__ __device__ void calculatePMM(const real *const f, const real omega)
+    {
+        momentsPMM.calculate(f, omega);
+    }
+
+    __host__ __device__ void calculateMMM(const real *const f, const real omega)
+    {
+        momentsMMM.calculate(f, omega);
+    }
+
+    __host__ __device__ void calculateCoefficients(Coefficients &coefficients, real xoff, real yoff, real zoff) const
+    {
+        real& a000 = coefficients.a000;
+        real& b000 = coefficients.b000;
+        real& c000 = coefficients.c000;
+        real& d000 = coefficients.d000;
+
+        real& a100 = coefficients.a100;
+        real& b100 = coefficients.b100;
+        real& c100 = coefficients.c100;
+        real& d100 = coefficients.d100;
+
+        real& a010 = coefficients.a010;
+        real& b010 = coefficients.b010;
+        real& c010 = coefficients.c010;
+        real& d010 = coefficients.d010;
+
+        real& a001 = coefficients.a001;
+        real& b001 = coefficients.b001;
+        real& c001 = coefficients.c001;
+        real& d001 = coefficients.d001;
+
+        real& d110 = coefficients.d110, &d101 = coefficients.d101, &d011 = coefficients.d011;
+        
+        real& a200 = coefficients.a200, &a020 = coefficients.a020, &a002 = coefficients.a002;
+        real& b200 = coefficients.b200, &b020 = coefficients.b020, &b002 = coefficients.b002;
+        real& c200 = coefficients.c200, &c020 = coefficients.c020, &c002 = coefficients.c002;
+
+        real& a110 = coefficients.a110, &a101 = coefficients.a101, &a011 = coefficients.a011;
+        real& b110 = coefficients.b110, &b101 = coefficients.b101, &b011 = coefficients.b011;
+        real& c110 = coefficients.c110, &c101 = coefficients.c101, &c011 = coefficients.c011;
+
+        real &a111 = coefficients.a111, &b111 = coefficients.b111, &c111 = coefficients.c111, &d111 = coefficients.d111;
+
+        real &LaplaceRho = coefficients.LaplaceRho;
+
+        const real xoffsq = xoff * xoff;
+        const real yoffsq = yoff * yoff;
+        const real zoffsq = zoff * zoff;
+
+        const real drhoPPP = momentsPPP.drho, vx1PPP = momentsPPP.velocityX, vx2PPP = momentsPPP.velocityY, vx3PPP = momentsPPP.velocityZ;
+        const real drhoMPP = momentsMPP.drho, vx1MPP = momentsMPP.velocityX, vx2MPP = momentsMPP.velocityY, vx3MPP = momentsMPP.velocityZ;
+        const real drhoPMP = momentsPMP.drho, vx1PMP = momentsPMP.velocityX, vx2PMP = momentsPMP.velocityY, vx3PMP = momentsPMP.velocityZ;
+        const real drhoMMP = momentsMMP.drho, vx1MMP = momentsMMP.velocityX, vx2MMP = momentsMMP.velocityY, vx3MMP = momentsMMP.velocityZ;
+        const real drhoPPM = momentsPPM.drho, vx1PPM = momentsPPM.velocityX, vx2PPM = momentsPPM.velocityY, vx3PPM = momentsPPM.velocityZ;
+        const real drhoMPM = momentsMPM.drho, vx1MPM = momentsMPM.velocityX, vx2MPM = momentsMPM.velocityY, vx3MPM = momentsMPM.velocityZ;
+        const real drhoPMM = momentsPMM.drho, vx1PMM = momentsPMM.velocityX, vx2PMM = momentsPMM.velocityY, vx3PMM = momentsPMM.velocityZ;
+        const real drhoMMM = momentsMMM.drho, vx1MMM = momentsMMM.velocityX, vx2MMM = momentsMMM.velocityY, vx3MMM = momentsMMM.velocityZ;
+
+        // second order moments at the source nodes
+        const real kxyFromfcNEQPPP = momentsPPP.kxyFromfcNEQ, kyzFromfcNEQPPP = momentsPPP.kyzFromfcNEQ, kxzFromfcNEQPPP = momentsPPP.kxzFromfcNEQ, kxxMyyFromfcNEQPPP = momentsPPP.kxxMyyFromfcNEQ, kxxMzzFromfcNEQPPP = momentsPPP.kxxMzzFromfcNEQ;
+        const real kxyFromfcNEQMPP = momentsMPP.kxyFromfcNEQ, kyzFromfcNEQMPP = momentsMPP.kyzFromfcNEQ, kxzFromfcNEQMPP = momentsMPP.kxzFromfcNEQ, kxxMyyFromfcNEQMPP = momentsMPP.kxxMyyFromfcNEQ, kxxMzzFromfcNEQMPP = momentsMPP.kxxMzzFromfcNEQ;
+        const real kxyFromfcNEQPMP = momentsPMP.kxyFromfcNEQ, kyzFromfcNEQPMP = momentsPMP.kyzFromfcNEQ, kxzFromfcNEQPMP = momentsPMP.kxzFromfcNEQ, kxxMyyFromfcNEQPMP = momentsPMP.kxxMyyFromfcNEQ, kxxMzzFromfcNEQPMP = momentsPMP.kxxMzzFromfcNEQ;
+        const real kxyFromfcNEQMMP = momentsMMP.kxyFromfcNEQ, kyzFromfcNEQMMP = momentsMMP.kyzFromfcNEQ, kxzFromfcNEQMMP = momentsMMP.kxzFromfcNEQ, kxxMyyFromfcNEQMMP = momentsMMP.kxxMyyFromfcNEQ, kxxMzzFromfcNEQMMP = momentsMMP.kxxMzzFromfcNEQ;
+        const real kxyFromfcNEQPPM = momentsPPM.kxyFromfcNEQ, kyzFromfcNEQPPM = momentsPPM.kyzFromfcNEQ, kxzFromfcNEQPPM = momentsPPM.kxzFromfcNEQ, kxxMyyFromfcNEQPPM = momentsPPM.kxxMyyFromfcNEQ, kxxMzzFromfcNEQPPM = momentsPPM.kxxMzzFromfcNEQ;
+        const real kxyFromfcNEQMPM = momentsMPM.kxyFromfcNEQ, kyzFromfcNEQMPM = momentsMPM.kyzFromfcNEQ, kxzFromfcNEQMPM = momentsMPM.kxzFromfcNEQ, kxxMyyFromfcNEQMPM = momentsMPM.kxxMyyFromfcNEQ, kxxMzzFromfcNEQMPM = momentsMPM.kxxMzzFromfcNEQ;
+        const real kxyFromfcNEQPMM = momentsPMM.kxyFromfcNEQ, kyzFromfcNEQPMM = momentsPMM.kyzFromfcNEQ, kxzFromfcNEQPMM = momentsPMM.kxzFromfcNEQ, kxxMyyFromfcNEQPMM = momentsPMM.kxxMyyFromfcNEQ, kxxMzzFromfcNEQPMM = momentsPMM.kxxMzzFromfcNEQ;
+        const real kxyFromfcNEQMMM = momentsMMM.kxyFromfcNEQ, kyzFromfcNEQMMM = momentsMMM.kyzFromfcNEQ, kxzFromfcNEQMMM = momentsMMM.kxzFromfcNEQ, kxxMyyFromfcNEQMMM = momentsMMM.kxxMyyFromfcNEQ, kxxMzzFromfcNEQMMM = momentsMMM.kxxMzzFromfcNEQ;
+
+        a000 = c1o64 * (
+                c2o1 * (
+                ((kxyFromfcNEQMMM - kxyFromfcNEQPPP) + (kxyFromfcNEQMMP - kxyFromfcNEQPPM)) + ((kxyFromfcNEQPMM - kxyFromfcNEQMPP) + (kxyFromfcNEQPMP - kxyFromfcNEQMPM)) + 
+                ((kxzFromfcNEQMMM - kxzFromfcNEQPPP) + (kxzFromfcNEQPPM - kxzFromfcNEQMMP)) + ((kxzFromfcNEQPMM - kxzFromfcNEQMPP) + (kxzFromfcNEQMPM - kxzFromfcNEQPMP)) + 
+                ((vx2PPP + vx2MMM) + (vx2PPM + vx2MMP)) - ((vx2MPP + vx2PMM) + (vx2MPM + vx2PMP)) + 
+                ((vx3PPP + vx3MMM) - (vx3PPM + vx3MMP)) + ((vx3PMP + vx3MPM) - (vx3MPP + vx3PMM))) + 
+                c8o1 * (((vx1PPP + vx1MMM) + (vx1PPM + vx1MMP)) + ((vx1MPP + vx1PMM) + (vx1PMP + vx1MPM))) +
+                ((kxxMyyFromfcNEQMMM - kxxMyyFromfcNEQPPP) + (kxxMyyFromfcNEQMMP - kxxMyyFromfcNEQPPM)) + 
+                ((kxxMyyFromfcNEQMPP - kxxMyyFromfcNEQPMM) + (kxxMyyFromfcNEQMPM - kxxMyyFromfcNEQPMP)) +
+                ((kxxMzzFromfcNEQMMM - kxxMzzFromfcNEQPPP) + (kxxMzzFromfcNEQMMP - kxxMzzFromfcNEQPPM)) + 
+                ((kxxMzzFromfcNEQMPP - kxxMzzFromfcNEQPMM) + (kxxMzzFromfcNEQMPM - kxxMzzFromfcNEQPMP)));
+        b000 = c1o64 * (
+                c2o1 * (
+                ((kxxMyyFromfcNEQPPP - kxxMyyFromfcNEQMMM) + (kxxMyyFromfcNEQPPM - kxxMyyFromfcNEQMMP)) + 
+                ((kxxMyyFromfcNEQMPP - kxxMyyFromfcNEQPMM) + (kxxMyyFromfcNEQMPM - kxxMyyFromfcNEQPMP)) + 
+                ((kxyFromfcNEQMMM - kxyFromfcNEQPPP) + (kxyFromfcNEQMMP - kxyFromfcNEQPPM)) + 
+                ((kxyFromfcNEQMPP - kxyFromfcNEQPMM) + (kxyFromfcNEQMPM - kxyFromfcNEQPMP)) + 
+                ((kyzFromfcNEQMMM - kyzFromfcNEQPPP) + (kyzFromfcNEQPPM - kyzFromfcNEQMMP)) + 
+                ((kyzFromfcNEQPMM - kyzFromfcNEQMPP) + (kyzFromfcNEQMPM - kyzFromfcNEQPMP)) + 
+                ((vx1PPP + vx1MMM) + (vx1PPM + vx1MMP)) - ((vx1MPM + vx1MPP) + (vx1PMM + vx1PMP)) + 
+                ((vx3PPP + vx3MMM) - (vx3PPM + vx3MMP)) + ((vx3MPP + vx3PMM) - (vx3MPM + vx3PMP))) + 
+                c8o1 * (((vx2PPP + vx2MMM) + (vx2PPM + vx2MMP)) + ((vx2MPP + vx2PMM) + (vx2MPM + vx2PMP))) + 
+                ((kxxMzzFromfcNEQMMM - kxxMzzFromfcNEQPPP) + (kxxMzzFromfcNEQMMP - kxxMzzFromfcNEQPPM)) +
+                ((kxxMzzFromfcNEQPMM - kxxMzzFromfcNEQMPP) + (kxxMzzFromfcNEQPMP - kxxMzzFromfcNEQMPM)));
+        c000 = c1o64 * ( 
+                c2o1 * (
+                ((kxxMzzFromfcNEQPPP - kxxMzzFromfcNEQMMM) + (kxxMzzFromfcNEQMMP - kxxMzzFromfcNEQPPM)) + 
+                ((kxxMzzFromfcNEQMPP - kxxMzzFromfcNEQPMM) + (kxxMzzFromfcNEQPMP - kxxMzzFromfcNEQMPM)) + 
+                ((kxzFromfcNEQMMM - kxzFromfcNEQPPP) + (kxzFromfcNEQMMP - kxzFromfcNEQPPM)) + 
+                ((kxzFromfcNEQMPP - kxzFromfcNEQPMM) + (kxzFromfcNEQMPM - kxzFromfcNEQPMP)) + 
+                ((kyzFromfcNEQMMM - kyzFromfcNEQPPP) + (kyzFromfcNEQMMP - kyzFromfcNEQPPM)) + 
+                ((kyzFromfcNEQPMM - kyzFromfcNEQMPP) + (kyzFromfcNEQPMP - kyzFromfcNEQMPM)) + 
+                ((vx1PPP + vx1MMM) - (vx1MMP + vx1PPM)) + ((vx1MPM + vx1PMP) - (vx1MPP + vx1PMM)) + 
+                ((vx2PPP + vx2MMM) - (vx2MMP + vx2PPM)) + ((vx2MPP + vx2PMM) - (vx2MPM + vx2PMP))) + 
+                c8o1 * (((vx3PPP + vx3MMM) + (vx3PPM + vx3MMP)) + ((vx3PMM + vx3MPP) + (vx3PMP + vx3MPM))) +
+                ((kxxMyyFromfcNEQMMM - kxxMyyFromfcNEQPPP) + (kxxMyyFromfcNEQPPM - kxxMyyFromfcNEQMMP)) + 
+                ((kxxMyyFromfcNEQPMM - kxxMyyFromfcNEQMPP) + (kxxMyyFromfcNEQMPM - kxxMyyFromfcNEQPMP)));
+
+        a100 = c1o4 * (((vx1PPP - vx1MMM) + (vx1PPM - vx1MMP)) + ((vx1PMM - vx1MPP) + (vx1PMP - vx1MPM)));
+        b100 = c1o4 * (((vx2PPP - vx2MMM) + (vx2PPM - vx2MMP)) + ((vx2PMM - vx2MPP) + (vx2PMP - vx2MPM)));
+        c100 = c1o4 * (((vx3PPP - vx3MMM) + (vx3PPM - vx3MMP)) + ((vx3PMM - vx3MPP) + (vx3PMP - vx3MPM)));
+
+        a200 = c1o16 * ( 
+                c2o1 * (
+                ((vx2PPP + vx2MMM) + (vx2PPM - vx2MPP)) + ((vx2MMP - vx2PMM) - (vx2MPM + vx2PMP)) + 
+                ((vx3PPP + vx3MMM) - (vx3PPM + vx3MPP)) + ((vx3MPM + vx3PMP) - (vx3MMP + vx3PMM))) + 
+                ((kxxMyyFromfcNEQPPP - kxxMyyFromfcNEQMMM) + (kxxMyyFromfcNEQPPM - kxxMyyFromfcNEQMMP)) + 
+                ((kxxMyyFromfcNEQPMM - kxxMyyFromfcNEQMPP) + (kxxMyyFromfcNEQPMP - kxxMyyFromfcNEQMPM)) + 
+                ((kxxMzzFromfcNEQPPP - kxxMzzFromfcNEQMMM) + (kxxMzzFromfcNEQPPM - kxxMzzFromfcNEQMMP)) + 
+                ((kxxMzzFromfcNEQPMM - kxxMzzFromfcNEQMPP) + (kxxMzzFromfcNEQPMP - kxxMzzFromfcNEQMPM)));
+        b200 = c1o8 * (
+                c2o1 * (
+                -((vx1PPP + vx1MMM) + (vx1PPM + vx1MMP)) + ((vx1MPP + vx1PMM) + (vx1MPM + vx1PMP))) +
+                ((kxyFromfcNEQPPP - kxyFromfcNEQMMM) + (kxyFromfcNEQPPM - kxyFromfcNEQMMP)) + 
+                ((kxyFromfcNEQPMM - kxyFromfcNEQMPP) + (kxyFromfcNEQPMP - kxyFromfcNEQMPM)));
+        c200 = c1o8 * (
+                c2o1 * (
+                ((vx1PPM + vx1MMP) - (vx1PPP + vx1MMM)) + ((vx1MPP + vx1PMM) - (vx1MPM + vx1PMP))) +
+                ((kxzFromfcNEQPPP - kxzFromfcNEQMMM) + (kxzFromfcNEQPPM - kxzFromfcNEQMMP)) + 
+                ((kxzFromfcNEQPMM - kxzFromfcNEQMPP) + (kxzFromfcNEQPMP - kxzFromfcNEQMPM)));
+
+        a010 = c1o4 * (((vx1PPP - vx1MMM) + (vx1PPM - vx1MMP)) + ((vx1MPP - vx1PMM) + (vx1MPM - vx1PMP)));
+        b010 = c1o4 * (((vx2PPP - vx2MMM) + (vx2PPM - vx2MMP)) + ((vx2MPP - vx2PMM) + (vx2MPM - vx2PMP)));
+        c010 = c1o4 * (((vx3PPP - vx3MMM) + (vx3PPM - vx3MMP)) + ((vx3MPP - vx3PMM) + (vx3MPM - vx3PMP)));
+
+        a020 = c1o8 * (
+                c2o1 * (-((vx2PPP + vx2MMM) + (vx2MMP + vx2PPM)) + ((vx2MPP + vx2PMM) + (vx2MPM + vx2PMP))) +
+                ((kxyFromfcNEQPPP - kxyFromfcNEQMMM) + (kxyFromfcNEQPPM - kxyFromfcNEQMMP)) + 
+                ((kxyFromfcNEQMPP - kxyFromfcNEQPMM) + (kxyFromfcNEQMPM - kxyFromfcNEQPMP)));
+        b020 = c1o16 * (
+                c2o1 * (
+                ((kxxMyyFromfcNEQMMM - kxxMyyFromfcNEQPPP) + (kxxMyyFromfcNEQMMP - kxxMyyFromfcNEQPPM)) +
+                ((kxxMyyFromfcNEQPMM - kxxMyyFromfcNEQMPP) + (kxxMyyFromfcNEQPMP - kxxMyyFromfcNEQMPM)) +
+                ((vx1PPP + vx1MMM) + (vx1PPM + vx1MMP)) - ((vx1MPP + vx1PMM) + (vx1PMP + vx1MPM)) + 
+                ((vx3PPP + vx3MMM) - (vx3PPM + vx3MMP)) + ((vx3MPP + vx3PMM) - (vx3MPM + vx3PMP))) +
+                ((kxxMzzFromfcNEQPPP - kxxMzzFromfcNEQMMM) + (kxxMzzFromfcNEQPPM - kxxMzzFromfcNEQMMP)) + 
+                ((kxxMzzFromfcNEQMPP - kxxMzzFromfcNEQPMM) + (kxxMzzFromfcNEQMPM - kxxMzzFromfcNEQPMP)));
+        c020 = c1o8 * (
+                c2o1 * (((vx2MMP + vx2PPM) - (vx2PPP + vx2MMM)) + ((vx2PMP + vx2MPM) - (vx2MPP + vx2PMM))) +
+                ((kyzFromfcNEQPPP - kyzFromfcNEQMMM) + (kyzFromfcNEQPPM - kyzFromfcNEQMMP)) +
+                ((kyzFromfcNEQMPP - kyzFromfcNEQPMM) + (kyzFromfcNEQMPM - kyzFromfcNEQPMP)));
+
+        a001 = c1o4 * (((vx1PPP - vx1MMM) + (vx1MMP - vx1PPM)) + ((vx1MPP - vx1PMM) + (vx1PMP - vx1MPM)));
+        b001 = c1o4 * (((vx2PPP - vx2MMM) + (vx2MMP - vx2PPM)) + ((vx2MPP - vx2PMM) + (vx2PMP - vx2MPM)));
+        c001 = c1o4 * (((vx3PPP - vx3MMM) + (vx3MMP - vx3PPM)) + ((vx3MPP - vx3PMM) + (vx3PMP - vx3MPM)));
+
+        a002 = c1o8 * (
+                c2o1 * (((vx3PPM + vx3MMP) - (vx3PPP + vx3MMM)) + ((vx3MPP + vx3PMM) - (vx3PMP + vx3MPM))) +
+                        ((kxzFromfcNEQPPP - kxzFromfcNEQMMM) + (kxzFromfcNEQMMP - kxzFromfcNEQPPM)) +
+                        ((kxzFromfcNEQPMP - kxzFromfcNEQMPM) + (kxzFromfcNEQMPP - kxzFromfcNEQPMM)));
+        b002 = c1o8 * (
+                c2o1 * (((vx3PPM + vx3MMP) - (vx3PPP + vx3MMM)) + ((vx3MPM + vx3PMP) - (vx3PMM + vx3MPP))) + 
+                        ((kyzFromfcNEQPPP - kyzFromfcNEQMMM) + (kyzFromfcNEQMMP - kyzFromfcNEQPPM)) + 
+                        ((kyzFromfcNEQPMP - kyzFromfcNEQMPM) + (kyzFromfcNEQMPP - kyzFromfcNEQPMM)));
+        c002 = c1o16 * (
+                c2o1 * (
+                ((kxxMzzFromfcNEQMMM - kxxMzzFromfcNEQPPP) + (kxxMzzFromfcNEQPPM - kxxMzzFromfcNEQMMP)) + 
+                ((kxxMzzFromfcNEQMPM - kxxMzzFromfcNEQPMP) + (kxxMzzFromfcNEQPMM - kxxMzzFromfcNEQMPP)) + 
+                ((vx1PPP + vx1MMM) - (vx1MMP + vx1PPM)) + ((vx1MPM + vx1PMP) - (vx1PMM + vx1MPP)) + 
+                ((vx2PPP + vx2MMM) - (vx2MMP + vx2PPM)) + ((vx2PMM + vx2MPP) - (vx2MPM + vx2PMP))) + 
+                ((kxxMyyFromfcNEQPPP - kxxMyyFromfcNEQMMM) + (kxxMyyFromfcNEQMMP - kxxMyyFromfcNEQPPM)) +
+                ((kxxMyyFromfcNEQPMP - kxxMyyFromfcNEQMPM) + (kxxMyyFromfcNEQMPP - kxxMyyFromfcNEQPMM)));
+
+        a110 = c1o2 * (((vx1PPP + vx1MMM) + (vx1MMP + vx1PPM)) - ((vx1MPM + vx1PMP) + (vx1PMM + vx1MPP)));
+        b110 = c1o2 * (((vx2PPP + vx2MMM) + (vx2MMP + vx2PPM)) - ((vx2MPM + vx2PMP) + (vx2PMM + vx2MPP)));
+        c110 = c1o2 * (((vx3PPP + vx3MMM) + (vx3MMP + vx3PPM)) - ((vx3MPM + vx3PMP) + (vx3PMM + vx3MPP)));
+
+        a101 = c1o2 * (((vx1PPP + vx1MMM) - (vx1MMP + vx1PPM)) + ((vx1MPM + vx1PMP) - (vx1PMM + vx1MPP)));
+        b101 = c1o2 * (((vx2PPP + vx2MMM) - (vx2MMP + vx2PPM)) + ((vx2MPM + vx2PMP) - (vx2PMM + vx2MPP)));
+        c101 = c1o2 * (((vx3PPP + vx3MMM) - (vx3MMP + vx3PPM)) + ((vx3MPM + vx3PMP) - (vx3PMM + vx3MPP)));
+        
+        a011 = c1o2 * (((vx1PPP + vx1MMM) - (vx1MMP + vx1PPM)) + ((vx1PMM + vx1MPP) - (vx1MPM + vx1PMP)));
+        b011 = c1o2 * (((vx2PPP + vx2MMM) - (vx2MMP + vx2PPM)) + ((vx2PMM + vx2MPP) - (vx2MPM + vx2PMP)));
+        c011 = c1o2 * (((vx3PPP + vx3MMM) - (vx3MMP + vx3PPM)) + ((vx3PMM + vx3MPP) - (vx3MPM + vx3PMP)));
+
+        a111 = ((vx1PPP - vx1MMM) + (vx1MMP - vx1PPM)) + ((vx1MPM - vx1PMP) + (vx1PMM - vx1MPP));
+        b111 = ((vx2PPP - vx2MMM) + (vx2MMP - vx2PPM)) + ((vx2MPM - vx2PMP) + (vx2PMM - vx2MPP));
+        c111 = ((vx3PPP - vx3MMM) + (vx3MMP - vx3PPM)) + ((vx3MPM - vx3PMP) + (vx3PMM - vx3MPP));
+
+        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        //!- Calculate coefficients for the polynomial interpolation of the pressure
+        //! 
+        LaplaceRho = 
+            ((xoff != c0o1) || (yoff != c0o1) || (zoff != c0o1))
+            ? c0o1 : -c3o1 * (a100 * a100 + b010 * b010 + c001 * c001) - c6o1 * (b100 * a010 + c100 * a001 + c010 * b001);
+        d000 = c1o8 * (((drhoPPP + drhoMMM) + (drhoPPM + drhoMMP)) + ((drhoPMM + drhoMPP) + (drhoPMP + drhoMPM)));
+        d100 = c1o4 * (((drhoPPP - drhoMMM) + (drhoPPM - drhoMMP)) + ((drhoPMM - drhoMPP) + (drhoPMP - drhoMPM)));
+        d010 = c1o4 * (((drhoPPP - drhoMMM) + (drhoPPM - drhoMMP)) + ((drhoMPP - drhoPMM) + (drhoMPM - drhoPMP)));
+        d001 = c1o4 * (((drhoPPP - drhoMMM) + (drhoMMP - drhoPPM)) + ((drhoMPP - drhoPMM) + (drhoPMP - drhoMPM)));
+        d110 = c1o2 * (((drhoPPP + drhoMMM) + (drhoPPM + drhoMMP)) - ((drhoPMM + drhoMPP) + (drhoPMP + drhoMPM)));
+        d101 = c1o2 * (((drhoPPP + drhoMMM) - (drhoPPM + drhoMMP)) + ((drhoPMP + drhoMPM) - (drhoPMM + drhoMPP)));
+        d011 = c1o2 * (((drhoPPP + drhoMMM) - (drhoPPM + drhoMMP)) + ((drhoPMM + drhoMPP) - (drhoPMP + drhoMPM)));
+
+        d111 = (((drhoPPP - drhoMMM) + (drhoMMP - drhoPPM)) + ((drhoPMM - drhoMPP) + (drhoMPM - drhoPMP)));
+
+        //////////////////////////////////////////////////////////////////////////
+        //! - Extrapolation for refinement in to the wall (polynomial coefficients)
+        //!
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        //
+        // x------x
+        // |      |
+        // |   ---+--->X
+        // |      |  |
+        // x------x  |
+        //          offset-vector
+        //
+        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+        a000 = a000 + xoff * a100 + yoff * a010 + zoff * a001 + xoffsq * a200 + yoffsq * a020 + zoffsq * a002 +
+            xoff * yoff * a110 + xoff * zoff * a101 + yoff * zoff * a011;
+        a100 = a100 + c2o1 * xoff * a200 + yoff * a110 + zoff * a101;
+        a010 = a010 + c2o1 * yoff * a020 + xoff * a110 + zoff * a011;
+        a001 = a001 + c2o1 * zoff * a002 + xoff * a101 + yoff * a011;
+        b000 = b000 + xoff * b100 + yoff * b010 + zoff * b001 + xoffsq * b200 + yoffsq * b020 + zoffsq * b002 +
+                xoff * yoff * b110 + xoff * zoff * b101 + yoff * zoff * b011;
+        b100 = b100 + c2o1 * xoff * b200 + yoff * b110 + zoff * b101;
+        b010 = b010 + c2o1 * yoff * b020 + xoff * b110 + zoff * b011;
+        b001 = b001 + c2o1 * zoff * b002 + xoff * b101 + yoff * b011;
+        c000 = c000 + xoff * c100 + yoff * c010 + zoff * c001 + xoffsq * c200 + yoffsq * c020 + zoffsq * c002 +
+                xoff * yoff * c110 + xoff * zoff * c101 + yoff * zoff * c011;
+        c100 = c100 + c2o1 * xoff * c200 + yoff * c110 + zoff * c101;
+        c010 = c010 + c2o1 * yoff * c020 + xoff * c110 + zoff * c011;
+        c001 = c001 + c2o1 * zoff * c002 + xoff * c101 + yoff * c011;
+        d000 = d000 + xoff * d100 + yoff * d010 + zoff * d001 + 
+                xoff * yoff * d110 + xoff * zoff * d101 + yoff * zoff * d011;
+
+        d100 = d100 + yoff * d110 + zoff * d101;
+        d010 = d010 + xoff * d110 + zoff * d011;
+        d001 = d001 + xoff * d101 + yoff * d011;
+    }
+
+};
+
+}
+
+#endif
diff --git a/src/lbm/refinement/InterpolationCF.h b/src/lbm/refinement/InterpolationCF.h
new file mode 100644
index 0000000000000000000000000000000000000000..82b8df256ce8ebecdc37e202e0dbe763331a1a65
--- /dev/null
+++ b/src/lbm/refinement/InterpolationCF.h
@@ -0,0 +1,310 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  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/>.
+//
+//=======================================================================================
+#ifndef LBM_INTERPOLATION_CF_H
+#define LBM_INTERPOLATION_CF_H
+
+#ifndef __host__
+#define __host__
+#endif
+#ifndef __device__
+#define __device__
+#endif
+
+#include <basics/constants/NumericConstants.h>
+
+#include "lbm/constants/D3Q27.h"
+
+#include "lbm/KernelParameter.h"
+#include "lbm/Chimera.h"
+
+#include "lbm/refinement/Coefficients.h"
+
+using namespace vf::basics::constant;
+using namespace vf::lbm::dir;
+
+namespace vf::lbm
+{
+
+inline __host__ __device__ void interpolateCF(real* const f, const real& omegaF, const real& epsnew, const Coefficients &coefficients, const real& x, const real& y, const real& z)
+{
+    const real useNEQ = c1o1;
+
+    const real kxyAverage    = c0o1;
+    const real kyzAverage    = c0o1;
+    const real kxzAverage    = c0o1;
+    const real kxxMyyAverage = c0o1;
+    const real kxxMzzAverage = c0o1;
+
+    const real& a000 = coefficients.a000;
+    const real& b000 = coefficients.b000;
+    const real& c000 = coefficients.c000;
+    const real& d000 = coefficients.d000;
+
+    const real& a100 = coefficients.a100;
+    const real& b100 = coefficients.b100;
+    const real& c100 = coefficients.c100;
+    const real& d100 = coefficients.d100;
+
+    const real& a010 = coefficients.a010;
+    const real& b010 = coefficients.b010;
+    const real& c010 = coefficients.c010;
+    const real& d010 = coefficients.d010;
+
+    const real& a001 = coefficients.a001;
+    const real& b001 = coefficients.b001;
+    const real& c001 = coefficients.c001;
+    const real& d001 = coefficients.d001;
+
+    const real& d110 = coefficients.d110, &d101 = coefficients.d101, &d011 = coefficients.d011;
+    
+    const real& a200 = coefficients.a200, &a020 = coefficients.a020, &a002 = coefficients.a002;
+    const real& b200 = coefficients.b200, &b020 = coefficients.b020, &b002 = coefficients.b002;
+    const real& c200 = coefficients.c200, &c020 = coefficients.c020, &c002 = coefficients.c002;
+
+    const real& a110 = coefficients.a110, &a101 = coefficients.a101, &a011 = coefficients.a011;
+    const real& b110 = coefficients.b110, &b101 = coefficients.b101, &b011 = coefficients.b011;
+    const real& c110 = coefficients.c110, &c101 = coefficients.c101, &c011 = coefficients.c011;
+
+    const real &a111 = coefficients.a111, &b111 = coefficients.b111, &c111 = coefficients.c111, &d111 = coefficients.d111;
+
+    const real &LaplaceRho = coefficients.LaplaceRho;
+
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //! - Set all moments to zero
+    //!      
+    real m111 = c0o1;
+    real m211 = c0o1;
+    real m011 = c0o1;
+    real m121 = c0o1;
+    real m101 = c0o1;
+    real m112 = c0o1;
+    real m110 = c0o1;
+    real m221 = c0o1;
+    real m001 = c0o1;
+    real m201 = c0o1;
+    real m021 = c0o1;
+    real m212 = c0o1;
+    real m010 = c0o1;
+    real m210 = c0o1;
+    real m012 = c0o1;
+    real m122 = c0o1;
+    real m100 = c0o1;
+    real m120 = c0o1;
+    real m102 = c0o1;
+    real m222 = c0o1;
+    real m022 = c0o1;
+    real m202 = c0o1;
+    real m002 = c0o1;
+    real m220 = c0o1;
+    real m020 = c0o1;
+    real m200 = c0o1;
+    real m000 = c0o1;
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //! - Define aliases to use the same variable for the distributions (f's):
+    //!
+    real& f000 = m111;
+    real& fP00 = m211;
+    real& fM00 = m011;
+    real& f0P0 = m121;
+    real& f0M0 = m101;
+    real& f00P = m112;
+    real& f00M = m110;
+    real& fPP0 = m221;
+    real& fMM0 = m001;
+    real& fPM0 = m201;
+    real& fMP0 = m021;
+    real& fP0P = m212;
+    real& fM0M = m010;
+    real& fP0M = m210;
+    real& fM0P = m012;
+    real& f0PP = m122;
+    real& f0MM = m100;
+    real& f0PM = m120;
+    real& f0MP = m102;
+    real& fPPP = m222;
+    real& fMPP = m022;
+    real& fPMP = m202;
+    real& fMMP = m002;
+    real& fPPM = m220;
+    real& fMPM = m020;
+    real& fPMM = m200;
+    real& fMMM = m000;
+
+
+    ////////////////////////////////////////////////////////////////////////////////
+    //! - Set macroscopic values on destination node (zeroth and first order moments)
+    //!
+    real press = d000 + x * d100 + y * d010 + z * d001 +
+                 x * y * d110 + x * z * d101 + y * z * d011 + x * y * z * d111 + c3o1 * x * x * LaplaceRho;
+    real vvx   = a000 + x * a100 + y * a010 + z * a001 +
+                 x * x * a200 + y * y * a020 + z * z * a002 +
+                 x * y * a110 + x * z * a101 + y * z * a011 + x * y * z * a111;
+    real vvy   = b000 + x * b100 + y * b010 + z * b001 +
+                 x * x * b200 + y * y * b020 + z * z * b002 +
+                 x * y * b110 + x * z * b101 + y * z * b011 + x * y * z * b111;
+    real vvz   = c000 + x * c100 + y * c010 + z * c001 +
+                 x * x * c200 + y * y * c020 + z * z * c002 +
+                 x * y * c110 + x * z * c101 + y * z * c011 + x * y * z * c111;
+
+    m000 = press; // m000 is press, if drho is interpolated directly
+
+    ////////////////////////////////////////////////////////////////////////////////
+    //! - Set moments (second to sixth order) on destination node
+    //!
+    // linear combinations for second order moments
+    real mxxPyyPzz = m000;
+
+    real mxxMyy = -c2o3 * (a100 - b010 + kxxMyyAverage + c2o1 * a200 * x - b110 * x + a110 * y
+                  -c2o1 * b020 * y + a101 * z - b011 * z - b111 * x * z + a111 * y * z) * epsnew/ omegaF * (c1o1 + press);
+    real mxxMzz = -c2o3 * (a100 - c001 + kxxMzzAverage + c2o1 * a200 * x - c101 * x + a110 * y
+                  -c011 * y - c111 * x * y + a101 * z - c2o1 * c002 * z + a111 * y * z) * epsnew/ omegaF * (c1o1 + press);
+
+    m011 = -c1o3 * (b001 + c010 + kyzAverage + b101 * x + c110 * x + b011 * y + c2o1 * c020 * y
+            + b111 * x * y + c2o1 * b002 * z + c011 * z + c111 * x * z) * epsnew / omegaF * (c1o1 + press);
+    m101 = -c1o3 * (a001 + c100 + kxzAverage + a101 * x + c2o1 * c200 * x + a011 * y + c110 * y
+            + a111 * x * y + c2o1 * a002 * z + c101 * z + c111 * y * z) * epsnew / omegaF * (c1o1 + press);
+    m110 = -c1o3 * (a010 + b100 + kxyAverage + a110 * x + c2o1 * b200 * x + c2o1 * a020 * y
+            + b110 * y + a011 * z + b101 * z + a111 * x * z + b111 * y * z) * epsnew / omegaF * (c1o1 + press);
+
+    m200 = c1o3 * (        mxxMyy +        mxxMzz + mxxPyyPzz) * useNEQ;
+    m020 = c1o3 * (-c2o1 * mxxMyy +        mxxMzz + mxxPyyPzz) * useNEQ;
+    m002 = c1o3 * (        mxxMyy - c2o1 * mxxMzz + mxxPyyPzz) * useNEQ;
+
+    // linear combinations for third order moments
+    m111 = c0o1;
+
+    real mxxyPyzz = c0o1;
+    real mxxyMyzz = c0o1;
+    real mxxzPyyz = c0o1;
+    real mxxzMyyz = c0o1;
+    real mxyyPxzz = c0o1;
+    real mxyyMxzz = c0o1;
+
+    m210 = ( mxxyMyzz + mxxyPyzz) * c1o2;
+    m012 = (-mxxyMyzz + mxxyPyzz) * c1o2;
+    m201 = ( mxxzMyyz + mxxzPyyz) * c1o2;
+    m021 = (-mxxzMyyz + mxxzPyyz) * c1o2;
+    m120 = ( mxyyMxzz + mxyyPxzz) * c1o2;
+    m102 = (-mxyyMxzz + mxyyPxzz) * c1o2;
+
+    // fourth order moments
+    m022 = m000 * c1o9;
+    m202 = m022;
+    m220 = m022;
+
+    // fifth order moments
+
+    // sixth order moment
+    m222 = m000 * c1o27;
+
+    real vxsq = vvx * vvx;
+    real vysq = vvy * vvy;
+    real vzsq = vvz * vvz;
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //! - Chimera transform from central moments to well conditioned distributions as defined in Appendix J in
+    //! <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> see also Eq. (88)-(96) in <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>
+    //!
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    // X - Dir
+    backwardInverseChimeraWithK(m000, m100, m200, vvx, vxsq, c1o1, c1o1);
+    backwardChimera(            m010, m110, m210, vvx, vxsq);
+    backwardInverseChimeraWithK(m020, m120, m220, vvx, vxsq, c3o1, c1o3);
+    backwardChimera(            m001, m101, m201, vvx, vxsq);
+    backwardChimera(            m011, m111, m211, vvx, vxsq);
+    backwardChimera(            m021, m121, m221, vvx, vxsq);
+    backwardInverseChimeraWithK(m002, m102, m202, vvx, vxsq, c3o1, c1o3);
+    backwardChimera(            m012, m112, m212, vvx, vxsq);
+    backwardInverseChimeraWithK(m022, m122, m222, vvx, vxsq, c9o1, c1o9);
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    // Y - Dir
+    backwardInverseChimeraWithK(m000, m010, m020, vvy, vysq, c6o1, c1o6);
+    backwardChimera(            m001, m011, m021, vvy, vysq);
+    backwardInverseChimeraWithK(m002, m012, m022, vvy, vysq, c18o1, c1o18);
+    backwardInverseChimeraWithK(m100, m110, m120, vvy, vysq, c3o2, c2o3);
+    backwardChimera(            m101, m111, m121, vvy, vysq);
+    backwardInverseChimeraWithK(m102, m112, m122, vvy, vysq, c9o2, c2o9);
+    backwardInverseChimeraWithK(m200, m210, m220, vvy, vysq, c6o1, c1o6);
+    backwardChimera(            m201, m211, m221, vvy, vysq);
+    backwardInverseChimeraWithK(m202, m212, m222, vvy, vysq, c18o1, c1o18);
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    // Z - Dir
+    backwardInverseChimeraWithK(m000, m001, m002, vvz, vzsq, c36o1, c1o36);
+    backwardInverseChimeraWithK(m010, m011, m012, vvz, vzsq, c9o1,  c1o9);
+    backwardInverseChimeraWithK(m020, m021, m022, vvz, vzsq, c36o1, c1o36);
+    backwardInverseChimeraWithK(m100, m101, m102, vvz, vzsq, c9o1,  c1o9);
+    backwardInverseChimeraWithK(m110, m111, m112, vvz, vzsq, c9o4,  c4o9);
+    backwardInverseChimeraWithK(m120, m121, m122, vvz, vzsq, c9o1,  c1o9);
+    backwardInverseChimeraWithK(m200, m201, m202, vvz, vzsq, c36o1, c1o36);
+    backwardInverseChimeraWithK(m210, m211, m212, vvz, vzsq, c9o1,  c1o9);
+    backwardInverseChimeraWithK(m220, m221, m222, vvz, vzsq, c36o1, c1o36);
+
+    f[DIR_000] = f000;
+    f[DIR_P00] = fP00;
+    f[DIR_M00] = fM00;
+    f[DIR_0P0] = f0P0;
+    f[DIR_0M0] = f0M0;
+    f[DIR_00P] = f00P;
+    f[DIR_00M] = f00M;
+    f[DIR_PP0] = fPP0;
+    f[DIR_MM0] = fMM0;
+    f[DIR_PM0] = fPM0;
+    f[DIR_MP0] = fMP0;
+    f[DIR_P0P] = fP0P;
+    f[DIR_M0M] = fM0M;
+    f[DIR_P0M] = fP0M;
+    f[DIR_M0P] = fM0P;
+    f[DIR_0PP] = f0PP;
+    f[DIR_0MM] = f0MM;
+    f[DIR_0PM] = f0PM;
+    f[DIR_0MP] = f0MP;
+    f[DIR_PPP] = fPPP;
+    f[DIR_MPP] = fMPP;
+    f[DIR_PMP] = fPMP;
+    f[DIR_MMP] = fMMP;
+    f[DIR_PPM] = fPPM;
+    f[DIR_MPM] = fMPM;
+    f[DIR_PMM] = fPMM;
+    f[DIR_MMM] = fMMM;
+}
+
+
+
+}
+
+#endif
diff --git a/src/lbm/refinement/InterpolationFC.h b/src/lbm/refinement/InterpolationFC.h
new file mode 100644
index 0000000000000000000000000000000000000000..f3e6384476033880c40b4b6f4c73890ba1e33ae7
--- /dev/null
+++ b/src/lbm/refinement/InterpolationFC.h
@@ -0,0 +1,265 @@
+//=======================================================================================
+// ____          ____    __    ______     __________   __      __       __        __         
+// \    \       |    |  |  |  |   _   \  |___    ___| |  |    |  |     /  \      |  |        
+//  \    \      |    |  |  |  |  |_)   |     |  |     |  |    |  |    /    \     |  |        
+//   \    \     |    |  |  |  |   _   /      |  |     |  |    |  |   /  /\  \    |  |        
+//    \    \    |    |  |  |  |  | \  \      |  |     |   \__/   |  /  ____  \   |  |____    
+//     \    \   |    |  |__|  |__|  \__\     |__|      \________/  /__/    \__\  |_______|   
+//      \    \  |    |   ________________________________________________________________    
+//       \    \ |    |  |  ______________________________________________________________|   
+//        \    \|    |  |  |         __          __     __     __     ______      _______    
+//         \         |  |  |_____   |  |        |  |   |  |   |  |   |   _  \    /  _____)   
+//          \        |  |   _____|  |  |        |  |   |  |   |  |   |  | \  \   \_______    
+//           \       |  |  |        |  |_____   |   \_/   |   |  |   |  |_/  /    _____  |
+//            \ _____|  |__|        |________|   \_______/    |__|   |______/    (_______/   
+//
+//  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/>.
+//
+//=======================================================================================
+#ifndef LBM_INTERPOLATION_FC_H
+#define LBM_INTERPOLATION_FC_H
+
+#ifndef __host__
+#define __host__
+#endif
+#ifndef __device__
+#define __device__
+#endif
+
+#include <basics/constants/NumericConstants.h>
+
+#include "lbm/constants/D3Q27.h"
+#include "lbm/KernelParameter.h"
+#include "lbm/Chimera.h"
+
+#include "lbm/refinement/Coefficients.h"
+
+using namespace vf::basics::constant;
+using namespace vf::lbm::dir;
+
+namespace vf::lbm
+{
+
+inline __host__ __device__ void interpolateFC(real* const f, const real epsnew, const real omegaC, const Coefficients& coefficients)
+{
+
+    const real kxyAverage    = c0o1;
+    const real kyzAverage    = c0o1;
+    const real kxzAverage    = c0o1;
+    const real kxxMyyAverage = c0o1;
+    const real kxxMzzAverage = c0o1;
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //! - Set all moments to zero
+    //!
+    real m111 = c0o1;
+    real m211 = c0o1;
+    real m011 = c0o1;
+    real m121 = c0o1;
+    real m101 = c0o1;
+    real m112 = c0o1;
+    real m110 = c0o1;
+    real m221 = c0o1;
+    real m001 = c0o1;
+    real m201 = c0o1;
+    real m021 = c0o1;
+    real m212 = c0o1;
+    real m010 = c0o1;
+    real m210 = c0o1;
+    real m012 = c0o1;
+    real m122 = c0o1;
+    real m100 = c0o1;
+    real m120 = c0o1;
+    real m102 = c0o1;
+    real m222 = c0o1;
+    real m022 = c0o1;
+    real m202 = c0o1;
+    real m002 = c0o1;
+    real m220 = c0o1;
+    real m020 = c0o1;
+    real m200 = c0o1;
+    real m000 = c0o1;
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //! - Define aliases to use the same variable for the distributions (f's):
+    //!
+    real& f000 = m111;
+    real& fP00 = m211;
+    real& fM00 = m011;
+    real& f0P0 = m121;
+    real& f0M0 = m101;
+    real& f00P = m112;
+    real& f00M = m110;
+    real& fPP0 = m221;
+    real& fMM0 = m001;
+    real& fPM0 = m201;
+    real& fMP0 = m021;
+    real& fP0P = m212;
+    real& fM0M = m010;
+    real& fP0M = m210;
+    real& fM0P = m012;
+    real& f0PP = m122;
+    real& f0MM = m100;
+    real& f0PM = m120;
+    real& f0MP = m102;
+    real& fPPP = m222;
+    real& fMPP = m022;
+    real& fPMP = m202;
+    real& fMMP = m002;
+    real& fPPM = m220;
+    real& fMPM = m020;
+    real& fPMM = m200;
+    real& fMMM = m000;
+
+    ////////////////////////////////////////////////////////////////////////////////
+    //! - Declare local variables for destination nodes
+    //!
+    real vvx, vvy, vvz, vxsq, vysq, vzsq;
+    real mxxPyyPzz, mxxMyy, mxxMzz, mxxyPyzz, mxxyMyzz, mxxzPyyz, mxxzMyyz, mxyyPxzz, mxyyMxzz;
+    real useNEQ = c1o1; // zero; //one;   //.... one = on ..... zero = off
+    real press;
+
+    ////////////////////////////////////////////////////////////////////////////////
+    //! - Set macroscopic values on destination node (zeroth and first order moments)
+    //!
+    press = coefficients.d000 - c2o1 * coefficients.LaplaceRho * c1o8;
+    vvx   = coefficients.a000;
+    vvy   = coefficients.b000;
+    vvz   = coefficients.c000;
+
+    m000 = press; // m000 is press, if drho is interpolated directly
+
+    vxsq = vvx * vvx;
+    vysq = vvy * vvy;
+    vzsq = vvz * vvz;
+
+    ////////////////////////////////////////////////////////////////////////////////
+    //! - Set moments (second to sixth order) on destination node
+    //!
+    // linear combinations for second order moments
+    mxxPyyPzz = m000;
+
+    mxxMyy = -c2o3 * ((coefficients.a100 - coefficients.b010) + kxxMyyAverage) * epsnew / omegaC * (c1o1 + press);
+    mxxMzz = -c2o3 * ((coefficients.a100 - coefficients.c001) + kxxMzzAverage) * epsnew / omegaC * (c1o1 + press);
+
+    m011 = -c1o3 * ((coefficients.b001 + coefficients.c010) + kyzAverage) * epsnew / omegaC * (c1o1 + press);
+    m101 = -c1o3 * ((coefficients.a001 + coefficients.c100) + kxzAverage) * epsnew / omegaC * (c1o1 + press);
+    m110 = -c1o3 * ((coefficients.a010 + coefficients.b100) + kxyAverage) * epsnew / omegaC * (c1o1 + press);
+
+    m200 = c1o3 * (        mxxMyy +        mxxMzz + mxxPyyPzz) * useNEQ;
+    m020 = c1o3 * (-c2o1 * mxxMyy +        mxxMzz + mxxPyyPzz) * useNEQ;
+    m002 = c1o3 * (        mxxMyy - c2o1 * mxxMzz + mxxPyyPzz) * useNEQ;
+
+    // linear combinations for third order moments
+    m111 = c0o1;
+
+    mxxyPyzz = c0o1;
+    mxxyMyzz = c0o1;
+    mxxzPyyz = c0o1;
+    mxxzMyyz = c0o1;
+    mxyyPxzz = c0o1;
+    mxyyMxzz = c0o1;
+
+    m210 = ( mxxyMyzz + mxxyPyzz) * c1o2;
+    m012 = (-mxxyMyzz + mxxyPyzz) * c1o2;
+    m201 = ( mxxzMyyz + mxxzPyyz) * c1o2;
+    m021 = (-mxxzMyyz + mxxzPyyz) * c1o2;
+    m120 = ( mxyyMxzz + mxyyPxzz) * c1o2;
+    m102 = (-mxyyMxzz + mxyyPxzz) * c1o2;
+
+    // fourth order moments
+    m022 = m000 * c1o9;
+    m202 = m022;
+    m220 = m022;
+
+    // fifth order moments
+
+    // sixth order moments
+    m222 = m000 * c1o27;
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //! - Chimera transform from central moments to well conditioned distributions as defined in Appendix J in
+    //! <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> see also Eq. (88)-(96) in <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>
+    //!
+    ////////////////////////////////////////////////////////////////////////////////////
+    // X - Dir
+    backwardInverseChimeraWithK(m000, m100, m200, vvx, vxsq, c1o1, c1o1);
+    backwardChimera(            m010, m110, m210, vvx, vxsq);
+    backwardInverseChimeraWithK(m020, m120, m220, vvx, vxsq, c3o1, c1o3);
+    backwardChimera(            m001, m101, m201, vvx, vxsq);
+    backwardChimera(            m011, m111, m211, vvx, vxsq);
+    backwardChimera(            m021, m121, m221, vvx, vxsq);
+    backwardInverseChimeraWithK(m002, m102, m202, vvx, vxsq, c3o1, c1o3);
+    backwardChimera(            m012, m112, m212, vvx, vxsq);
+    backwardInverseChimeraWithK(m022, m122, m222, vvx, vxsq, c9o1, c1o9);
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    // Y - Dir
+    backwardInverseChimeraWithK(m000, m010, m020, vvy, vysq, c6o1, c1o6);
+    backwardChimera(            m001, m011, m021, vvy, vysq);
+    backwardInverseChimeraWithK(m002, m012, m022, vvy, vysq, c18o1, c1o18);
+    backwardInverseChimeraWithK(m100, m110, m120, vvy, vysq, c3o2, c2o3);
+    backwardChimera(            m101, m111, m121, vvy, vysq);
+    backwardInverseChimeraWithK(m102, m112, m122, vvy, vysq, c9o2, c2o9);
+    backwardInverseChimeraWithK(m200, m210, m220, vvy, vysq, c6o1, c1o6);
+    backwardChimera(            m201, m211, m221, vvy, vysq);
+    backwardInverseChimeraWithK(m202, m212, m222, vvy, vysq, c18o1, c1o18);
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    // Z - Dir
+    backwardInverseChimeraWithK(m000, m001, m002, vvz, vzsq, c36o1, c1o36);
+    backwardInverseChimeraWithK(m010, m011, m012, vvz, vzsq, c9o1,  c1o9);
+    backwardInverseChimeraWithK(m020, m021, m022, vvz, vzsq, c36o1, c1o36);
+    backwardInverseChimeraWithK(m100, m101, m102, vvz, vzsq, c9o1,  c1o9);
+    backwardInverseChimeraWithK(m110, m111, m112, vvz, vzsq, c9o4,  c4o9);
+    backwardInverseChimeraWithK(m120, m121, m122, vvz, vzsq, c9o1,  c1o9);
+    backwardInverseChimeraWithK(m200, m201, m202, vvz, vzsq, c36o1, c1o36);
+    backwardInverseChimeraWithK(m210, m211, m212, vvz, vzsq, c9o1,  c1o9);
+    backwardInverseChimeraWithK(m220, m221, m222, vvz, vzsq, c36o1, c1o36);
+
+    f[DIR_000] = f000;
+    f[DIR_P00] = fP00;
+    f[DIR_M00] = fM00;
+    f[DIR_0P0] = f0P0;
+    f[DIR_0M0] = f0M0;
+    f[DIR_00P] = f00P;
+    f[DIR_00M] = f00M;
+    f[DIR_PP0] = fPP0;
+    f[DIR_MM0] = fMM0;
+    f[DIR_PM0] = fPM0;
+    f[DIR_MP0] = fMP0;
+    f[DIR_P0P] = fP0P;
+    f[DIR_M0M] = fM0M;
+    f[DIR_P0M] = fP0M;
+    f[DIR_M0P] = fM0P;
+    f[DIR_0PP] = f0PP;
+    f[DIR_0MM] = f0MM;
+    f[DIR_0PM] = f0PM;
+    f[DIR_0MP] = f0MP;
+    f[DIR_PPP] = fPPP;
+    f[DIR_MPP] = fMPP;
+    f[DIR_PMP] = fPMP;
+    f[DIR_MMP] = fMMP;
+    f[DIR_PPM] = fPPM;
+    f[DIR_MPM] = fMPM;
+    f[DIR_PMM] = fPMM;
+    f[DIR_MMM] = fMMM;
+}
+
+}
+
+#endif
diff --git a/src/logger/Logger.h b/src/logger/Logger.h
index 3a25fea02eb7d5ea1ab9bffebea08bfc9f512b04..f3c41c0e3bfb8aa12c94677040273fdaaaff64a3 100644
--- a/src/logger/Logger.h
+++ b/src/logger/Logger.h
@@ -39,10 +39,10 @@
 // The default log level is set to trace. Supported levels: trace < debug < info < warning < critical
 // 
 // The logging is realized in 3 different log sinks:
-// 1. colorded console output
+// 1. colored console output
 // 2. a daily log file
 // 3. a log file from the last run of VirtualFluids
-// The default file path is relativ to executed command logs/
+// The default file path is relative to executed command logs/
 // File path can be changed via changeLogPath()
 
 #define VF_LOG_TRACE(...) spdlog::trace(__VA_ARGS__)
@@ -57,7 +57,7 @@ namespace vf::logging
     class Logger
     {
     public:
-        // initalizing the above named logger
+        // initializing the above named logger
         static void initializeLogger();
 
         // changing the path of the log files
diff --git a/utilities/ci-regression-tests/regression-tests-ci.yml.j2 b/utilities/ci-regression-tests/regression-tests-ci.yml.j2
index 4367ad6c7d5f820ef8975c37dbf843e5342e4dbd..f162ff0c855130ffb8f2cc1c391a62360577b82a 100644
--- a/utilities/ci-regression-tests/regression-tests-ci.yml.j2
+++ b/utilities/ci-regression-tests/regression-tests-ci.yml.j2
@@ -1,4 +1,4 @@
-image: git.rz.tu-bs.de:4567/irmb/virtualfluids/ubuntu20_04:1.5
+image: git.rz.tu-bs.de:4567/irmb/virtualfluids/ubuntu22_04:1.0
 
 stages: 
   - test
diff --git a/utilities/install-cppcheck.sh b/utilities/install-cppcheck.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e0a89854917b7378ac85fed0e3cc43dc624db598
--- /dev/null
+++ b/utilities/install-cppcheck.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+set -e
+
+cd /tmp
+git clone https://github.com/danmar/cppcheck.git
+cd cppcheck 
+git checkout 2.10.3
+make MATCHCOMPILER=yes FILESDIR=/usr/share/cppcheck HAVE_RULES=yes CXXFLAGS="-O2 -DNDEBUG -Wall -Wno-sign-compare -Wno-unused-function" install
+cd /tmp
+rm -rf /tmp/cppcheck
+ldconfig
+cppcheck --version
\ No newline at end of file