diff --git a/.clang-tidy b/.clang-tidy
index fffab0ce372641ebabd3468a5c106d2c9b0ce039..18eba527f27a2a808730ed2be3275a870c75dd7f 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -19,36 +19,24 @@ bugprone-*,
 -bugprone-reserved-identifier,
 
 misc-*,
--misc-misplaced-const,
--misc-const-correctness,
--misc-unused-parameters,
 -misc-no-recursion,
 -misc-non-private-member-variables-in-classes,
 -misc-include-cleaner,
 -misc-header-include-cycle,
 -misc-use-internal-linkage,
 -misc-use-anonymous-namespace,
+-misc-const-correctness,
+-misc-misplaced-const
 
 modernize-*,
 -modernize-use-auto,
--modernize-loop-convert,
 -modernize-pass-by-value,
 -modernize-raw-string-literal,
--modernize-use-using,
--modernize-avoid-bind,
--modernize-return-braced-init-list,
--modernize-min-max-use-initializer-list,
 -modernize-use-transparent-functors,
--modernize-redundant-void-arg,
 -modernize-use-trailing-return-type,
--modernize-use-default-member-init,
--modernize-use-equals-delete,
+-modernize-use-nodiscard,
 -modernize-macro-to-enum,
--modernize-avoid-c-arrays,
 -modernize-concat-nested-namespaces,
--modernize-use-nodiscard,
--modernize-type-traits,
--modernize-make-shared,
 
 mpi-*,
 -mpi-type-mismatch,
@@ -60,7 +48,6 @@ openmp-*,
 performance-*,
 -performance-enum-size,
 -performance-noexcept-swap,
--performance-move-const-arg,
 -performance-unnecessary-value-param,
 -performance-avoid-endl,
 -performance-no-int-to-ptr,
diff --git a/.gitignore b/.gitignore
index 884a87d9028dc52beae77b5ec2beb022a0456de0..3320ba00d5f618b5e938f5b4febdb7e09e4bf5f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,8 @@ CMakeLists.txt.user.*
 logfile*.txt
 *TestLog_p*.txt
 
+# Python venv
+.venv
 
 # Compiled python
 *.pyc
@@ -67,6 +69,7 @@ logfile*.txt
 
 
 # CMake
+CMakeUserPresets.json
 /CMakeLists.txt.user
 
 # CMake build files
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f45deb9a889c97fade978ce159e4d294198d2454..4a8e3506bda394cd236822c46ee6e5a8deaa1d49 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -6,6 +6,7 @@
 
 stages:
    - pretest
+   - "Code Quality"
    - test
    - deploy
    - benchmark
@@ -2034,7 +2035,11 @@ doc:
 ###############################################################################
 
 clang-tidy:
-   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang-17
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang-18
+   stage: "Code Quality"
+   needs: []
+   before_script:
+      - pip install pyyaml
    script:
       - $CXX --version
       - clang-tidy -version
@@ -2043,11 +2048,14 @@ clang-tidy:
       - cd $CI_PROJECT_DIR/build
       - cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DWALBERLA_BUFFER_DEBUG=ON -DWALBERLA_BUILD_TESTS=ON -DWALBERLA_BUILD_BENCHMARKS=ON -DWALBERLA_BUILD_TUTORIALS=ON -DWALBERLA_BUILD_TOOLS=ON -DWALBERLA_BUILD_WITH_MPI=ON -DWALBERLA_BUILD_WITH_OPENMP=ON -DCMAKE_BUILD_TYPE=Debug -DWALBERLA_BUILD_WITH_METIS=ON -DWALBERLA_BUILD_WITH_PARMETIS=ON -DWALBERLA_BUILD_WITH_OPENMESH=ON -DWALBERLA_DOUBLE_ACCURACY=ON -DWALBERLA_LOGLEVEL=DETAIL
       - cmake . -LA
-      - utilities/filterCompileCommands.py --file compile_commands.json --exclude "*" --include src/core src/field src/stencil src/blockforest src/domain_decomposition src/communication src/gpu src/vtk src/fft --exclude extern tests
-      - run-clang-tidy -quiet | tee clang-tidy-output.txt
+      - python3 utilities/clang-tidy/analyze.py -p utilities/clang-tidy/analyze.yml -r $CI_PROJECT_DIR -c compile_commands.json -o clang-tidy-output
+   after_script:
+      - mkdir -p $CI_PROJECT_DIR/artifacts
+      - mv $CI_PROJECT_DIR/build/clang-tidy-output $CI_PROJECT_DIR/artifacts/clang-tidy-output
    artifacts:
+      when: always
       paths:
-         - $CI_PROJECT_DIR/build/clang-tidy-output.txt
+         - $CI_PROJECT_DIR/artifacts/clang-tidy-output
    tags:
       - docker
 
diff --git a/CMakePresets.json b/CMakePresets.json
new file mode 100644
index 0000000000000000000000000000000000000000..e1b021bd37b0272e303315e0c72455e57e9760a7
--- /dev/null
+++ b/CMakePresets.json
@@ -0,0 +1,32 @@
+{
+    "version": 6,
+    "cmakeMinimumRequired": {
+      "major": 3,
+      "minor": 23,
+      "patch": 0
+    },
+    "configurePresets": [
+      {
+        "name": "clang-tidy",
+        "generator": "Unix Makefiles",
+        "binaryDir": "${sourceDir}/build/clang-tidy",
+        "cacheVariables": {
+          "CMAKE_EXPORT_COMPILE_COMMANDS": true,
+          "WALBERLA_BUFFER_DEBUG": true,
+          "WALBERLA_BUILD_TESTS": true,
+          "WALBERLA_BUILD_BENCHMARKS": true,
+          "WALBERLA_BUILD_TUTORIALS": true,
+          "WALBERLA_BUILD_TOOLS": true,
+          "WALBERLA_BUILD_WITH_MPI": true,
+          "WALBERLA_BUILD_WITH_OPENMP": true,
+          "CMAKE_BUILD_TYPE": "Debug",
+          "WALBERLA_BUILD_WITH_METIS": true,
+          "WALBERLA_BUILD_WITH_PARMETIS": true,
+          "WALBERLA_BUILD_WITH_OPENMESH": true,
+          "WALBERLA_DOUBLE_ACCURACY": true,
+          "WALBERLA_LOGLEVEL": "DETAIL"
+        }
+      }
+    ]
+  }
+  
\ No newline at end of file
diff --git a/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/AMRSedimentSettling.cpp b/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/AMRSedimentSettling.cpp
index 38d1d9ad4a159c369acd85733884898a084e87b7..96142f46d7b7d0d3f60c47ac0e26b550fe5c2310 100644
--- a/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/AMRSedimentSettling.cpp
+++ b/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/AMRSedimentSettling.cpp
@@ -165,9 +165,9 @@ template< typename LatticeModel_T, typename Filter_T >
 void VectorGradientRefinement< LatticeModel_T, Filter_T >::operator()( std::vector< std::pair< const Block *, uint_t > > & minTargetLevels,
                                                                        std::vector< const Block * > &, const BlockForest & )
 {
-   for( auto it = minTargetLevels.begin(); it != minTargetLevels.end(); ++it )
+   for(auto & minTargetLevel : minTargetLevels)
    {
-      const Block * const block = it->first;
+      const Block * const block = minTargetLevel.first;
 
       const uint_t currentLevelOfBlock = block->getLevel();
 
@@ -175,7 +175,7 @@ void VectorGradientRefinement< LatticeModel_T, Filter_T >::operator()( std::vect
 
       if( uField == nullptr )
       {
-         it->second = uint_t(0);
+         minTargetLevel.second = uint_t(0);
          continue;
       }
 
@@ -253,12 +253,12 @@ void VectorGradientRefinement< LatticeModel_T, Filter_T >::operator()( std::vect
       if( refine && currentLevelOfBlock < maxLevel_ )
       {
          WALBERLA_ASSERT( !coarsen );
-         it->second = currentLevelOfBlock + uint_t(1);
+         minTargetLevel.second = currentLevelOfBlock + uint_t(1);
       }
       if( coarsen && currentLevelOfBlock > uint_t(0) )
       {
          WALBERLA_ASSERT( !refine );
-         it->second = currentLevelOfBlock - uint_t(1);
+         minTargetLevel.second = currentLevelOfBlock - uint_t(1);
       }
    }
 }
@@ -500,7 +500,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const AABB & do
 
    MPIManager::instance()->useWorldComm();
 
-   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) );
+   sforest.addRefinementSelectionFunction( [numberOfLevels, refinementBox](auto && PH1) { refinementSelection(std::forward<decltype(PH1)>(PH1), numberOfLevels, refinementBox); } );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    Vector3<bool> periodicity( true, true, false);
@@ -1375,7 +1375,7 @@ int main( int argc, char **argv )
    cr.setRelaxationModel( pe::cr::HardContactSemiImplicitTimesteppingSolvers::ApproximateInelasticCoulombContactByDecoupling );
 
    // set up synchronization procedure
-   std::function<void(void)> syncCall = std::bind( pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, &(*timingTreePE), overlap, false );
+   std::function<void(void)> syncCall = [&capture0 = blocks->getBlockForest(), bodyStorageID, capture1 = &(*timingTreePE), overlap] { pe::syncNextNeighbors<BodyTypeTuple>(capture0, bodyStorageID, capture1, overlap, false); };
 
    // create pe bodies
 
@@ -1525,14 +1525,14 @@ int main( int argc, char **argv )
 
    // force averaging functionality
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
+   std::function<void(void)> storeForceTorqueInCont1 = [bodiesFTContainer1] { bodiesFTContainer1->store(); };
 
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
+   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = [bodiesFTContainer2] { bodiesFTContainer2->setOnBodies(); };
 
    shared_ptr<pe_coupling::ForceTorqueOnBodiesScaler> forceScaler = make_shared<pe_coupling::ForceTorqueOnBodiesScaler>(blocks, bodyStorageID, real_t(0.5));
-   std::function<void(void)> setForceScalingFactorToOne = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(1));
-   std::function<void(void)> setForceScalingFactorToHalf = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5));
+   std::function<void(void)> setForceScalingFactorToOne = [forceScaler] { forceScaler->resetScalingFactor(real_t(1)); };
+   std::function<void(void)> setForceScalingFactorToHalf = [forceScaler] { forceScaler->resetScalingFactor(real_t(0.5)); };
 
    if( averageForceTorqueOverTwoTimSteps ) {
       bodiesFTContainer2->store();
@@ -2244,4 +2244,4 @@ int main( int argc, char **argv )
 
 int main( int argc, char **argv ){
    amr_sediment_settling::main(argc, argv);
-}
+}
\ No newline at end of file
diff --git a/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/AMRSettlingSphere.cpp b/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/AMRSettlingSphere.cpp
index 2f738db33c3e0a0c3e1600a579f40873c38fa459..70f91ffc80e4c156308be805ea0e199d6dfd78aa 100644
--- a/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/AMRSettlingSphere.cpp
+++ b/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/AMRSettlingSphere.cpp
@@ -158,9 +158,9 @@ template< typename LatticeModel_T, typename Filter_T >
 void VectorGradientRefinement< LatticeModel_T, Filter_T >::operator()( std::vector< std::pair< const Block *, uint_t > > & minTargetLevels,
                                                                        std::vector< const Block * > &, const BlockForest & )
 {
-   for( auto it = minTargetLevels.begin(); it != minTargetLevels.end(); ++it )
+   for(auto & minTargetLevel : minTargetLevels)
    {
-      const Block * const block = it->first;
+      const Block * const block = minTargetLevel.first;
 
       const uint_t currentLevelOfBlock = block->getLevel();
 
@@ -168,7 +168,7 @@ void VectorGradientRefinement< LatticeModel_T, Filter_T >::operator()( std::vect
 
       if( uField == nullptr )
       {
-         it->second = uint_t(0);
+         minTargetLevel.second = uint_t(0);
          continue;
       }
 
@@ -246,12 +246,12 @@ void VectorGradientRefinement< LatticeModel_T, Filter_T >::operator()( std::vect
       if( refine && currentLevelOfBlock < maxLevel_ )
       {
          WALBERLA_ASSERT( !coarsen );
-         it->second = currentLevelOfBlock + uint_t(1);
+         minTargetLevel.second = currentLevelOfBlock + uint_t(1);
       }
       if( coarsen && currentLevelOfBlock > uint_t(0) )
       {
          WALBERLA_ASSERT( !refine );
-         it->second = currentLevelOfBlock - uint_t(1);
+         minTargetLevel.second = currentLevelOfBlock - uint_t(1);
       }
    }
 }
@@ -307,28 +307,28 @@ private:
 static void refinementSelection( SetupBlockForest& forest, uint_t levels, const AABB & refinementBox )
 {
    real_t dx = real_t(1); // dx on finest level
-   for( auto block = forest.begin(); block != forest.end(); ++block )
+   for(auto & block : forest)
    {
-      uint_t blockLevel = block->getLevel();
+      uint_t blockLevel = block.getLevel();
       uint_t levelScalingFactor = ( uint_t(1) << (levels - uint_t(1) - blockLevel) );
       real_t dxOnLevel = dx * real_c(levelScalingFactor);
-      AABB blockAABB = block->getAABB();
+      AABB blockAABB = block.getAABB();
 
       // extend block AABB by ghostlayers
       AABB extendedBlockAABB = blockAABB.getExtended( dxOnLevel * real_c(FieldGhostLayers) );
 
       if( extendedBlockAABB.intersects( refinementBox ) )
          if( blockLevel < ( levels - uint_t(1) ) )
-            block->setMarker( true );
+            block.setMarker( true );
    }
 }
 
 static void workloadAndMemoryAssignment( SetupBlockForest& forest )
 {
-   for( auto block = forest.begin(); block != forest.end(); ++block )
+   for(auto & block : forest)
    {
-      block->setWorkload( numeric_cast< workload_t >( uint_t(1) << block->getLevel() ) );
-      block->setMemory( numeric_cast< memory_t >(1) );
+      block.setWorkload( numeric_cast< workload_t >( uint_t(1) << block.getLevel() ) );
+      block.setMemory( numeric_cast< memory_t >(1) );
    }
 }
 
@@ -378,7 +378,7 @@ static shared_ptr< StructuredBlockForest > createBlockStructure( const AABB & do
 
    WALBERLA_LOG_INFO_ON_ROOT(" - refinement box: " << refinementBox);
 
-   sforest.addRefinementSelectionFunction( std::bind( refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox ) );
+   sforest.addRefinementSelectionFunction( [numberOfLevels, refinementBox](auto && PH1) { refinementSelection(std::forward<decltype(PH1)>(PH1), numberOfLevels, refinementBox); } );
    sforest.addWorkloadMemorySUIDAssignmentFunction( workloadAndMemoryAssignment );
 
    sforest.init( domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1], numberOfCoarseBlocksPerDirection[2], true, true, true );
@@ -620,9 +620,9 @@ public:
       for( uint_t level = 0; level < numberOfLevels_; ++level)
       {
          real_t timeOnLevelProcessLocal = real_t(0);
-         for( auto timerIt = timerOnEachLevel_.begin(); timerIt != timerOnEachLevel_.end(); ++timerIt )
+         for(auto const & timerIt : timerOnEachLevel_)
          {
-            std::string timerName = *timerIt + " (" + std::to_string(level) + ")";
+            std::string timerName = timerIt + " (" + std::to_string(level) + ")";
             timeOnLevelProcessLocal += real_c((*levelwiseTimingPool_)[timerName].total());
          }
 
@@ -630,15 +630,14 @@ public:
          {
             // evaluate more timers on finest level
 
-            for( auto timerIt = timerOnFinestLevel_.begin(); timerIt != timerOnFinestLevel_.end(); ++timerIt )
+            for(auto const & timerIt : timerOnFinestLevel_)
             {
-               std::string timerName = *timerIt + " (" + std::to_string(level) + ")";
+               std::string timerName = timerIt + " (" + std::to_string(level) + ")";
                timeOnLevelProcessLocal += real_c((*levelwiseTimingPool_)[timerName].total());
             }
-            for( auto timerIt = timerInPE_.begin(); timerIt != timerInPE_.end(); ++timerIt )
+            for(auto const & timerName : timerInPE_)
             {
-               std::string timerName = *timerIt;
-               timeOnLevelProcessLocal += real_c((*peTimingTree_)[timerName].total());
+                timeOnLevelProcessLocal += real_c((*peTimingTree_)[timerName].total());
             }
          }
 
@@ -950,7 +949,7 @@ int main( int argc, char **argv )
    pe::cr::DEM cr(globalBodyStorage, blocks->getBlockStoragePointer(), bodyStorageID, ccdID, fcdID, &(*timingTreePE));
 
    // set up synchronization procedure
-   std::function<void(void)> syncCall = std::bind( pe::syncShadowOwners<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, &(*timingTreePE), overlap, false );
+   std::function<void(void)> syncCall = [&capture0 = blocks->getBlockForest(), bodyStorageID, capture1 = &(*timingTreePE), overlap] { pe::syncShadowOwners<BodyTypeTuple>(capture0, bodyStorageID, capture1, overlap, false); };
 
    // create pe bodies
 
@@ -1009,12 +1008,12 @@ int main( int argc, char **argv )
 
    // force averaging functionality
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
+   std::function<void(void)> storeForceTorqueInCont1 = [bodiesFTContainer1] { bodiesFTContainer1->store(); };
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
+   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = [bodiesFTContainer2] { bodiesFTContainer2->setOnBodies(); };
    shared_ptr<pe_coupling::ForceTorqueOnBodiesScaler> forceScaler = make_shared<pe_coupling::ForceTorqueOnBodiesScaler>(blocks, bodyStorageID, real_t(0.5));
-   std::function<void(void)> setForceScalingFactorToOne = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(1));
-   std::function<void(void)> setForceScalingFactorToHalf = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5));
+   std::function<void(void)> setForceScalingFactorToOne = [forceScaler] { forceScaler->resetScalingFactor(real_t(1)); };
+   std::function<void(void)> setForceScalingFactorToHalf = [forceScaler] { forceScaler->resetScalingFactor(real_t(0.5)); };
 
    if( averageForceTorqueOverTwoTimSteps ) {
       bodiesFTContainer2->store();
@@ -1331,4 +1330,4 @@ int main( int argc, char **argv )
 
 int main( int argc, char **argv ){
    amr_settling_sphere::main(argc, argv);
-}
+}
\ No newline at end of file
diff --git a/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/WorkloadEvaluation.cpp b/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/WorkloadEvaluation.cpp
index a12727e32f47e7c57c3ccbf7714cff7aa6daf3b9..e6694f56c34bdad38fd637c9b4572de48d3f27cd 100644
--- a/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/WorkloadEvaluation.cpp
+++ b/apps/benchmarks/AdaptiveMeshRefinementFluidParticleCoupling/WorkloadEvaluation.cpp
@@ -540,7 +540,7 @@ int main( int argc, char **argv )
    // connect to pe
    const real_t overlap = real_c( 1.5 ) * dx;
 
-   std::function<void(void)> syncCall = std::bind( pe::syncNextNeighbors<BodyTypeTuple>, std::ref(blocks->getBlockForest()), bodyStorageID, &timingTreePE, overlap, false );
+   std::function<void(void)> syncCall = [&capture0 = blocks->getBlockForest(), bodyStorageID, capture1 = &timingTreePE, overlap] { pe::syncNextNeighbors<BodyTypeTuple>(capture0, bodyStorageID, capture1, overlap, false); };
 
    auto generationDomain = AABB( real_t(0), real_t(0), real_t(0), real_c(XCells), real_c(YCells), real_c(ZCells) - topWallOffset);
    auto peMaterial = pe::createMaterial( "mat", densityRatio, real_t(1), real_t(0.25), real_t(0.25), real_t(0), real_t(200), real_t(100), real_t(100), real_t(100) );
@@ -761,11 +761,11 @@ int main( int argc, char **argv )
                          ( blocks, pdfFieldID, boundaryHandlingID, bodyStorageID, globalBodyStorage, bodyFieldID, reconstructor, FormerMO_Flag, Fluid_Flag, pe_coupling::selectRegularBodies, optimizeForSmallObstacleFraction ), "PDF Restore" );
 
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer1 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> storeForceTorqueInCont1 = std::bind(&pe_coupling::BodiesForceTorqueContainer::store, bodiesFTContainer1);
+   std::function<void(void)> storeForceTorqueInCont1 = [bodiesFTContainer1] { bodiesFTContainer1->store(); };
    shared_ptr<pe_coupling::BodiesForceTorqueContainer> bodiesFTContainer2 = make_shared<pe_coupling::BodiesForceTorqueContainer>(blocks, bodyStorageID);
-   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = std::bind(&pe_coupling::BodiesForceTorqueContainer::setOnBodies, bodiesFTContainer2);
+   std::function<void(void)> setForceTorqueOnBodiesFromCont2 = [bodiesFTContainer2] { bodiesFTContainer2->setOnBodies(); };
    shared_ptr<pe_coupling::ForceTorqueOnBodiesScaler> forceScaler = make_shared<pe_coupling::ForceTorqueOnBodiesScaler>(blocks, bodyStorageID, real_t(1));
-   std::function<void(void)> setForceScalingFactorToHalf = std::bind(&pe_coupling::ForceTorqueOnBodiesScaler::resetScalingFactor,forceScaler,real_t(0.5));
+   std::function<void(void)> setForceScalingFactorToHalf = [forceScaler] { forceScaler->resetScalingFactor(real_t(0.5)); };
 
    if( averageForceTorqueOverTwoTimSteps ) {
       bodiesFTContainer2->store();
@@ -981,4 +981,4 @@ int main( int argc, char **argv )
 
 int main( int argc, char **argv ){
    workload_evaluation::main(argc, argv);
-}
+}
\ No newline at end of file
diff --git a/apps/benchmarks/CouetteFlow/CouetteFlow.cpp b/apps/benchmarks/CouetteFlow/CouetteFlow.cpp
index 1f3ea1b7dfade52e614a916a40261415e6874984..79f65a0af80494904db42134eeca372cebc827fa 100644
--- a/apps/benchmarks/CouetteFlow/CouetteFlow.cpp
+++ b/apps/benchmarks/CouetteFlow/CouetteFlow.cpp
@@ -162,19 +162,19 @@ template< typename LatticeModel_T, class Enable = void >
 struct StencilString;
 
 template< typename LatticeModel_T >
-struct StencilString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q15 >::value >::type >
+struct StencilString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q15 > > >
 {
    static const char * str() { return "D3Q15"; }
 };
 
 template< typename LatticeModel_T >
-struct StencilString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q19 >::value >::type >
+struct StencilString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q19 > > >
 {
    static const char * str() { return "D3Q19"; }
 };
 
 template< typename LatticeModel_T >
-struct StencilString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q27 >::value >::type >
+struct StencilString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q27 > > >
 {
    static const char * str() { return "D3Q27"; }
 };
@@ -184,22 +184,22 @@ template< typename LatticeModel_T, class Enable = void >
 struct CollisionModelString;
 
 template< typename LatticeModel_T >
-struct CollisionModelString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::CollisionModel::tag,
-                                                                                          lbm::collision_model::SRT_tag >::value >::type >
+struct CollisionModelString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::CollisionModel::tag,
+                                                                                          lbm::collision_model::SRT_tag > > >
 {
    static const char * str() { return "SRT"; }
 };
 
 template< typename LatticeModel_T >
-struct CollisionModelString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::CollisionModel::tag,
-                                                                                          lbm::collision_model::TRT_tag >::value >::type >
+struct CollisionModelString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::CollisionModel::tag,
+                                                                                          lbm::collision_model::TRT_tag > > >
 {
    static const char * str() { return "TRT"; }
 };
 
 template< typename LatticeModel_T >
-struct CollisionModelString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::CollisionModel::tag,
-                                                                                          lbm::collision_model::MRT_tag >::value >::type >
+struct CollisionModelString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::CollisionModel::tag,
+                                                                                          lbm::collision_model::MRT_tag > > >
 {
    static const char * str() { return "MRT"; }
 };
@@ -271,10 +271,10 @@ private:
 
 static void workloadAndMemoryAssignment( SetupBlockForest& forest, const memory_t memoryPerBlock )
 {
-   for( auto block = forest.begin(); block != forest.end(); ++block )
+   for(auto & block : forest)
    {
-      block->setWorkload( numeric_cast< workload_t >( uint_t(1) << block->getLevel() ) );
-      block->setMemory( memoryPerBlock );
+      block.setWorkload( numeric_cast< workload_t >( uint_t(1) << block.getLevel() ) );
+      block.setMemory( memoryPerBlock );
    }
 }
 
@@ -293,7 +293,7 @@ static shared_ptr< SetupBlockForest > createSetupBlockForest( const blockforest:
                                                              ( setup.zCells + uint_t(2) * FieldGhostLayers ) ) * memoryPerCell;
 
    forest->addRefinementSelectionFunction( refinementSelectionFunctions );
-   forest->addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadAndMemoryAssignment, std::placeholders::_1, memoryPerBlock ) );
+   forest->addWorkloadMemorySUIDAssignmentFunction([memoryPerBlock](auto & sbf) { workloadAndMemoryAssignment(sbf, memoryPerBlock); });
 
    forest->init( AABB( real_c(0), real_c(0), real_c(0), real_c( setup.xBlocks * setup.xCells ),
                                                         real_c( setup.yBlocks * setup.yCells ),
@@ -634,10 +634,10 @@ struct AddRefinementTimeStep
 };
 
 template< typename LatticeModel_T  >
-struct AddRefinementTimeStep< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::CollisionModel::tag, lbm::collision_model::MRT_tag >::value ||
-                                                                       std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q15 >::value ||
-                                                                       std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q27 >::value
-                                                                       >::type >
+struct AddRefinementTimeStep< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::CollisionModel::tag, lbm::collision_model::MRT_tag > ||
+                                                                       std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q15 > ||
+                                                                       std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q27 >
+                                                                       > >
 {
    static void add( SweepTimeloop & timeloop, shared_ptr< blockforest::StructuredBlockForest > & blocks,
                     const BlockDataID & pdfFieldId, const BlockDataID & flagFieldId, const BlockDataID & boundaryHandlingId,
@@ -718,9 +718,9 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
 
    if( vtkBeforeTimeStep )
    {
-      for( auto output = vtkOutputFunctions.begin(); output != vtkOutputFunctions.end(); ++output )
-         timeloop.addFuncBeforeTimeStep( output->second.outputFunction, std::string("VTK: ") + output->first,
-                                         output->second.requiredGlobalStates, output->second.incompatibleGlobalStates );
+      for(auto & output : vtkOutputFunctions)
+         timeloop.addFuncBeforeTimeStep( output.second.outputFunction, std::string("VTK: ") + output.first,
+                                        output.second.requiredGlobalStates, output.second.incompatibleGlobalStates );
    }
 
    // add 'refinement' LB time step to time loop
@@ -733,11 +733,11 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
 
    // evaluation
 
-   const auto exactSolutionFunction = std::bind( exactVelocity, std::placeholders::_1, blocks->getDomain(), setup.maxVelocity_L );
+   const auto exactSolutionFunction = [domain = blocks->getDomain(), maxVel = setup.maxVelocity_L](auto & p) { return exactVelocity(p, domain, maxVel); };
 
    auto volumetricFlowRate = field::makeVolumetricFlowRateEvaluation< VelocityAdaptor_T, FlagField_T >( configBlock, blocks, velocityAdaptorId,
                                                                                                         flagFieldId, Fluid_Flag,
-                                                                                                        std::bind( exactFlowRate, setup.flowRate_L ),
+                                                                                                        [flowRate = setup.flowRate_L] { return exactFlowRate(flowRate); },
                                                                                                         exactSolutionFunction );
    volumetricFlowRate->setNormalizationFactor( real_t(1) / setup.maxVelocity_L );
    volumetricFlowRate->setDomainNormalization( Vector3<real_t>( real_t(1) ) );
@@ -766,9 +766,9 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
 
    if( !vtkBeforeTimeStep )
    {
-      for( auto output = vtkOutputFunctions.begin(); output != vtkOutputFunctions.end(); ++output )
-         timeloop.addFuncAfterTimeStep( output->second.outputFunction, std::string("VTK: ") + output->first,
-                                        output->second.requiredGlobalStates, output->second.incompatibleGlobalStates );
+      for(auto & output : vtkOutputFunctions)
+         timeloop.addFuncAfterTimeStep( output.second.outputFunction, std::string("VTK: ") + output.first,
+                                       output.second.requiredGlobalStates, output.second.incompatibleGlobalStates );
    }
 
    // remaining time logger
diff --git a/apps/benchmarks/FieldCommunication/FieldCommunication.cpp b/apps/benchmarks/FieldCommunication/FieldCommunication.cpp
index c9b3cc87a35b7ea56d8889e7d3caf18d9da352ec..094e7d5dd1bbd83876803f7afe47479c4ebb6602 100644
--- a/apps/benchmarks/FieldCommunication/FieldCommunication.cpp
+++ b/apps/benchmarks/FieldCommunication/FieldCommunication.cpp
@@ -34,7 +34,7 @@ template<typename Stencil_T>
 class SingleMessageBufferedScheme
 {
 public:
-    typedef Stencil_T Stencil;
+    using Stencil = Stencil_T;
 
     SingleMessageBufferedScheme( const weak_ptr< StructuredBlockForest > & bf, const int tag = 17953 )
             : blockForest_( bf ), tag_( tag ) {}
@@ -354,8 +354,8 @@ int main( int argc, char **argv )
             auto databaseBlock = config->getBlock( "Database" );
             if ( databaseBlock )
             {
-                for ( auto it = databaseBlock.begin(); it != databaseBlock.end(); ++it )
-                    stringProperties[it->first] = it->second;
+                for (const auto & it : databaseBlock)
+                    stringProperties[it.first] = it.second;
             }
 
             realProperties["total_min"] = real_c( timingPool["totalTime"].min()) / real_c( iterations );
diff --git a/apps/benchmarks/FluidizedBed/FluidizedBedGPU.cpp b/apps/benchmarks/FluidizedBed/FluidizedBedGPU.cpp
index cf454243e5c71ce9b8cde90dd73fa92b47d44bff..7150cede83accc038dcebd56b05ee7619fdae3ef 100644
--- a/apps/benchmarks/FluidizedBed/FluidizedBedGPU.cpp
+++ b/apps/benchmarks/FluidizedBed/FluidizedBedGPU.cpp
@@ -103,7 +103,7 @@ using flag_t      = walberla::uint8_t;
 using FlagField_T = FlagField< flag_t >;
 
 using namespace lbm_mesapd_coupling::psm::gpu;
-typedef pystencils::PSMPackInfo PackInfo_T;
+using PackInfo_T = pystencils::PSMPackInfo;
 
 ///////////
 // FLAGS //
@@ -183,7 +183,7 @@ std::ostream& operator<<(std::ostream& os, ParticleInfo const& m)
 template< typename Accessor_T >
 ParticleInfo evaluateParticleInfo(const Accessor_T& ac)
 {
-   static_assert(std::is_base_of< mesa_pd::data::IAccessor, Accessor_T >::value, "Provide a valid accessor");
+   static_assert(std::is_base_of_v< mesa_pd::data::IAccessor, Accessor_T >, "Provide a valid accessor");
 
    ParticleInfo info;
    for (uint_t i = 0; i < ac.size(); ++i)
diff --git a/apps/benchmarks/Percolation/Percolation.cpp b/apps/benchmarks/Percolation/Percolation.cpp
index f778f7bc951582c2aa5ef04281c66801bd8c0728..0f890b67da7f608b0f6b0f09269dd42ddad808a9 100644
--- a/apps/benchmarks/Percolation/Percolation.cpp
+++ b/apps/benchmarks/Percolation/Percolation.cpp
@@ -73,7 +73,7 @@ namespace percolation
 
 using namespace walberla;
 using namespace lbm_mesapd_coupling::psm::gpu;
-typedef pystencils::PSMPackInfo PackInfo_T;
+using PackInfo_T = pystencils::PSMPackInfo;
 
 using flag_t      = walberla::uint8_t;
 using FlagField_T = FlagField< flag_t >;
diff --git a/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp b/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp
index 6f21d16ad34beffce6a711ae27d4adb42cc4b049..325b24f7a075095dbfa7ab363bb54c96f3259f2f 100644
--- a/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp
+++ b/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp
@@ -154,13 +154,13 @@ template< typename LatticeModel_T, class Enable = void >
 struct StencilString;
 
 template< typename LatticeModel_T >
-struct StencilString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q19 >::value >::type >
+struct StencilString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q19 > > >
 {
    static const char * str() { return "D3Q19"; }
 };
 
 template< typename LatticeModel_T >
-struct StencilString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q27 >::value >::type >
+struct StencilString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q27 > > >
 {
    static const char * str() { return "D3Q27"; }
 };
@@ -170,15 +170,15 @@ template< typename LatticeModel_T, class Enable = void >
 struct CollisionModelString;
 
 template< typename LatticeModel_T >
-struct CollisionModelString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::CollisionModel::tag,
-                                                                                          lbm::collision_model::SRT_tag >::value >::type >
+struct CollisionModelString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::CollisionModel::tag,
+                                                                                          lbm::collision_model::SRT_tag > > >
 {
    static const char * str() { return "SRT"; }
 };
 
 template< typename LatticeModel_T >
-struct CollisionModelString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::CollisionModel::tag,
-                                                                                          lbm::collision_model::TRT_tag >::value >::type >
+struct CollisionModelString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::CollisionModel::tag,
+                                                                                          lbm::collision_model::TRT_tag > > >
 {
    static const char * str() { return "TRT"; }
 };
@@ -241,10 +241,10 @@ private:
       if( setup_.circularProfile )
       {
          auto corners = block.getAABB().corners();
-         for( auto p = corners.begin(); p != corners.end(); ++p )
+         for(auto & corner : corners)
          {
-            const real_t dy = (*p)[1] - forest.getDomain().center()[1];
-            const real_t dz = (*p)[2] - forest.getDomain().center()[2];
+            const real_t dy = corner[1] - forest.getDomain().center()[1];
+            const real_t dz = corner[2] - forest.getDomain().center()[2];
             const real_t r = setup_.radius_L - bufferDistance_;
             if( (dy * dy + dz * dz) >= (r * r) )
                return false;
@@ -281,10 +281,10 @@ private:
 
 static void workloadAndMemoryAssignment( SetupBlockForest& forest, const memory_t memoryPerBlock )
 {
-   for( auto block = forest.begin(); block != forest.end(); ++block )
+   for(auto & block : forest)
    {
-      block->setWorkload( numeric_cast< workload_t >( uint_t(1) << block->getLevel() ) );
-      block->setMemory( memoryPerBlock );
+      block.setWorkload( numeric_cast< workload_t >( uint_t(1) << block.getLevel() ) );
+      block.setMemory( memoryPerBlock );
    }
 }
 
@@ -303,7 +303,7 @@ static shared_ptr< SetupBlockForest > createSetupBlockForest( const blockforest:
                                                              ( setup.zCells + uint_t(2) * FieldGhostLayers ) ) * memoryPerCell;
 
    forest->addRefinementSelectionFunction( refinementSelectionFunctions );
-   forest->addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadAndMemoryAssignment, std::placeholders::_1, memoryPerBlock ) );
+   forest->addWorkloadMemorySUIDAssignmentFunction( [memoryPerBlock](auto & bForest) { return workloadAndMemoryAssignment(bForest, memoryPerBlock); } );
 
    forest->init( AABB( real_c(0), real_c(0), real_c(0), real_c( setup.xBlocks * setup.xCells ),
                                                         real_c( setup.yBlocks * setup.yCells ),
@@ -822,9 +822,9 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
 
    if( vtkBeforeTimeStep )
    {
-      for( auto output = vtkOutputFunctions.begin(); output != vtkOutputFunctions.end(); ++output )
-         timeloop.addFuncBeforeTimeStep( output->second.outputFunction, std::string("VTK: ") + output->first,
-                                         output->second.requiredGlobalStates, output->second.incompatibleGlobalStates );
+      for(auto & output : vtkOutputFunctions)
+         timeloop.addFuncBeforeTimeStep( output.second.outputFunction, std::string("VTK: ") + output.first,
+                                        output.second.requiredGlobalStates, output.second.incompatibleGlobalStates );
    }
 
    // add 'refinement' LB time step to time loop
@@ -844,13 +844,15 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
    timeloop.addFuncBeforeTimeStep( makeSharedFunctor(ts), "LBM refinement time step" );
                                                  
    // evaluation 
-   
-   const auto exactSolutionFunction = setup.circularProfile ? std::bind( exactPipeVelocity, std::placeholders::_1, blocks, setup ) :
-                                                              std::bind( exactPlatesVelocity, std::placeholders::_1, blocks, setup );
+   using FlowRateVelocitySolution_T = std::function<Vector3<real_t> (const Vector3<real_t> &)>;
+   const FlowRateVelocitySolution_T exactPipeFunction = [&blocks, &setup](const Vector3<real_t> &p) { return exactPipeVelocity(p, blocks, setup); };
+   const FlowRateVelocitySolution_T exactPlateFunction = [&blocks, &setup](const Vector3<real_t> &p) { return exactPlatesVelocity(p, blocks, setup); };
+
+   const auto exactSolutionFunction = setup.circularProfile ? exactPipeFunction : exactPlateFunction;
 
    auto volumetricFlowRate = field::makeVolumetricFlowRateEvaluation< VelocityAdaptor_T, FlagField_T >( configBlock, blocks, velocityAdaptorId,
                                                                                                         flagFieldId, Fluid_Flag,
-                                                                                                        std::bind( exactFlowRate, setup.flowRate_L ),
+                                                                                                        [flowRate = setup.flowRate_L] { return exactFlowRate(flowRate); },
                                                                                                         exactSolutionFunction );
    volumetricFlowRate->setNormalizationFactor( real_t(1) / setup.maxVelocity_L );
    volumetricFlowRate->setDomainNormalization( Vector3<real_t>( real_t(1) ) );
@@ -883,9 +885,9 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
 
    if( !vtkBeforeTimeStep )
    {
-      for( auto output = vtkOutputFunctions.begin(); output != vtkOutputFunctions.end(); ++output )
-         timeloop.addFuncAfterTimeStep( output->second.outputFunction, std::string("VTK: ") + output->first,
-                                        output->second.requiredGlobalStates, output->second.incompatibleGlobalStates );
+      for(auto & output : vtkOutputFunctions)
+         timeloop.addFuncAfterTimeStep( output.second.outputFunction, std::string("VTK: ") + output.first,
+                                       output.second.requiredGlobalStates, output.second.incompatibleGlobalStates );
    }
 
    // remaining time logger
diff --git a/apps/benchmarks/ProbeVsExtraMessage/ProbeVsExtraMessage.cpp b/apps/benchmarks/ProbeVsExtraMessage/ProbeVsExtraMessage.cpp
index bb9adfd177d72d0fd503dc62e896598353eebcfa..400f9261d9755befebffe820551bb020b59e1a19 100644
--- a/apps/benchmarks/ProbeVsExtraMessage/ProbeVsExtraMessage.cpp
+++ b/apps/benchmarks/ProbeVsExtraMessage/ProbeVsExtraMessage.cpp
@@ -63,7 +63,7 @@ private:
    shared_ptr<mpi::MPIManager> manager_;
    Vector3<uint_t> procs_;
    Vector3<bool>   periodicity_;
-   Vector3<int>    pos_;
+   std::array<int, 3>    pos_;
    std::array<int, 27> ranks_;
 };
 
@@ -73,7 +73,7 @@ MPIInfo::MPIInfo( const Vector3<uint_t>& procs, const Vector3<bool>& periodicity
    , periodicity_(periodicity)
 {
    manager_->createCartesianComm(procs[0], procs[1], procs[2], periodicity[0], periodicity[1], periodicity[2]);
-   manager_->cartesianCoord(pos_.data());
+   manager_->cartesianCoord(pos_);
 
    for (auto dirIt = stencil::D3Q27::beginNoCenter(); dirIt != stencil::D3Q27::end(); ++dirIt)
    {
@@ -137,9 +137,9 @@ void communicate( MPIInfo& mpiInfo,
       WALBERLA_MPI_BARRIER();
       tp["unpack"].start();
       auto& recvInfos = bs.getRecvInfos();
-      for (auto recvIt = recvInfos.begin(); recvIt != recvInfos.end(); ++recvIt)
+      for (auto & recvInfoItem : recvInfos)
       {
-         auto& rb = recvIt->second.buffer;
+         auto& rb = recvInfoItem.second.buffer;
          rb >> recvBuf;
          WALBERLA_ASSERT(rb.isEmpty());
       }
@@ -259,7 +259,7 @@ int main( int argc, char ** argv )
 }
 } // namespace walberla
 
-int main( int argc, char* argv[] )
+int main( int argc, char** argv )
 {
    return walberla::main( argc, argv );
-}
+}
\ No newline at end of file
diff --git a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
index 3c75d4ab686d7f55021fe12bf844c54b74901da3..18cf402593c1c4d9f21ae068b37f082ff852d856 100644
--- a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
+++ b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
@@ -204,25 +204,25 @@ template< typename LatticeModel_T, class Enable = void >
 struct StencilString;
 
 template< typename LatticeModel_T >
-struct StencilString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::Stencil, stencil::D2Q9 >::value >::type >
+struct StencilString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::Stencil, stencil::D2Q9 > > >
 {
    static const char * str() { return "D2Q9"; }
 };
 
 template< typename LatticeModel_T >
-struct StencilString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q15 >::value >::type >
+struct StencilString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q15 > > >
 {
    static const char * str() { return "D3Q15"; }
 };
 
 template< typename LatticeModel_T >
-struct StencilString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q19 >::value >::type >
+struct StencilString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q19 > > >
 {
    static const char * str() { return "D3Q19"; }
 };
 
 template< typename LatticeModel_T >
-struct StencilString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q27 >::value >::type >
+struct StencilString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q27 > > >
 {
    static const char * str() { return "D3Q27"; }
 };
@@ -232,22 +232,22 @@ template< typename LatticeModel_T, class Enable = void >
 struct CollisionModelString;
 
 template< typename LatticeModel_T >
-struct CollisionModelString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::CollisionModel::tag,
-                                                                                          lbm::collision_model::SRT_tag >::value >::type >
+struct CollisionModelString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::CollisionModel::tag,
+                                                                                          lbm::collision_model::SRT_tag > > >
 {
    static const char * str() { return "SRT"; }
 };
 
 template< typename LatticeModel_T >
-struct CollisionModelString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::CollisionModel::tag,
-                                                                                          lbm::collision_model::TRT_tag >::value >::type >
+struct CollisionModelString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::CollisionModel::tag,
+                                                                                          lbm::collision_model::TRT_tag > > >
 {
    static const char * str() { return "TRT"; }
 };
 
 template< typename LatticeModel_T >
-struct CollisionModelString< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::CollisionModel::tag,
-                                                                                          lbm::collision_model::MRT_tag >::value >::type >
+struct CollisionModelString< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::CollisionModel::tag,
+                                                                                          lbm::collision_model::MRT_tag > > >
 {
    static const char * str() { return "MRT"; }
 };
@@ -355,7 +355,7 @@ bool Cylinder::contains( const AABB & aabb ) const
 {
    if( setup_.circularCrossSection )
    {
-      Vector3< real_t > p[8];
+      std::array< Vector3< real_t >, 8 > p;
       p[0].set( aabb.xMin(), aabb.yMin(), aabb.zMin() );
       p[1].set( aabb.xMax(), aabb.yMin(), aabb.zMin() );
       p[2].set( aabb.xMin(), aabb.yMax(), aabb.zMin() );
@@ -521,12 +521,12 @@ public:
 
    void operator()( SetupBlockForest & forest )
    {
-      for( auto block = forest.begin(); block != forest.end(); ++block )
+      for(auto & block : forest)
       {
-         const AABB & aabb = block->getAABB();
+         const AABB & aabb = block.getAABB();
 
-         if( block->getLevel() < level_ && cylinder_.intersects( aabb, bufferDistance_ ) && !cylinder_.contains( aabb ) )
-            block->setMarker( true );
+         if( block.getLevel() < level_ && cylinder_.intersects( aabb, bufferDistance_ ) && !cylinder_.contains( aabb ) )
+            block.setMarker( true );
       }
    }
 
@@ -633,10 +633,10 @@ static void workloadMemoryAndSUIDAssignment( SetupBlockForest & forest, const me
    }
    else
    {
-      for( auto block = forest.begin(); block != forest.end(); ++block )
+      for(auto & block : forest)
       {
-         block->setWorkload( numeric_cast< workload_t >( uint_t(1) << block->getLevel() ) );
-         block->setMemory( memoryPerBlock );
+         block.setWorkload( numeric_cast< workload_t >( uint_t(1) << block.getLevel() ) );
+         block.setMemory( memoryPerBlock );
       }
    }
 }
@@ -656,7 +656,8 @@ static shared_ptr< SetupBlockForest > createSetupBlockForest( const blockforest:
                                                              ( setup.xCells + uint_t(2) * FieldGhostLayers ) ) * memoryPerCell;
 
    forest->addRefinementSelectionFunction( refinementSelectionFunctions );
-   forest->addWorkloadMemorySUIDAssignmentFunction( std::bind( workloadMemoryAndSUIDAssignment, std::placeholders::_1, memoryPerBlock, std::cref( setup ) ) );
+   forest->addWorkloadMemorySUIDAssignmentFunction([memoryPerBlock, setup_cref = std::cref(setup)](SetupBlockForest & sbf) {
+      return workloadMemoryAndSUIDAssignment(sbf, memoryPerBlock, setup_cref); } );
 
    forest->init( AABB( real_c(0), real_c(0), real_c(0),
                        setup.H * ( real_c(setup.xBlocks) * real_c(setup.xCells) ) / ( real_c(setup.yzBlocks) * real_c(setup.yzCells) ), setup.H, setup.H ),
@@ -1034,11 +1035,11 @@ Set<SUID> Pseudo2DBlockStateDetermination::operator()( const std::vector< std::p
    auto aabb = forest_.getAABBFromBlockId( destintation );
    
    Set<SUID> state;
-   for( auto it = source.begin(); it != source.end(); ++it )
+   for(const auto & it : source)
    {
-      for( auto suid = it->second.begin(); suid != it->second.end(); ++suid )
-         if( *suid != state_ )
-            state += *suid;
+      for(auto suid : it.second)
+         if( suid != state_ )
+            state += suid;
    }
    
    if( markEmptyBlocks_ )
@@ -1067,13 +1068,13 @@ void keepInflowOutflowAtTheSameLevel( std::vector< std::pair< const Block *, uin
    // In addition to keeping in- and outflow blocks at the same level, this callback also
    // prevents these blocks from coarsening.
 
-   for( auto it = minTargetLevels.begin(); it != minTargetLevels.end(); ++it )
+   for(auto & minTargetLevel : minTargetLevels)
    {
-      const Block * const block = it->first;
+      const Block * const block = minTargetLevel.first;
       if( forest.atDomainXMinBorder(*block) )
       {
-         it->second = std::max( it->second, block->getLevel() );
-         maxInflowLevel = std::max( maxInflowLevel, it->second );
+         minTargetLevel.second = std::max( minTargetLevel.second, block->getLevel() );
+         maxInflowLevel = std::max( maxInflowLevel, minTargetLevel.second );
       }
       if( setup.strictlyObeyL )
       {
@@ -1083,19 +1084,18 @@ void keepInflowOutflowAtTheSameLevel( std::vector< std::pair< const Block *, uin
          p[0] = setup.L;
          if( aabb.contains(p) )
          {
-            it->second = std::max( it->second, block->getLevel() );
-            maxOutflowLevel = std::max( maxOutflowLevel, it->second );
+            minTargetLevel.second = std::max( minTargetLevel.second, block->getLevel() );
+            maxOutflowLevel = std::max( maxOutflowLevel, minTargetLevel.second );
          }
       }
       else if( forest.atDomainXMaxBorder(*block) )
       {
-         it->second = std::max( it->second, block->getLevel() );
-         maxOutflowLevel = std::max( maxOutflowLevel, it->second );
+         minTargetLevel.second = std::max( minTargetLevel.second, block->getLevel() );
+         maxOutflowLevel = std::max( maxOutflowLevel, minTargetLevel.second );
       }
    }
-   for( auto it = blocksAlreadyMarkedForRefinement.begin(); it != blocksAlreadyMarkedForRefinement.end(); ++it )
+   for(auto block : blocksAlreadyMarkedForRefinement)
    {
-      const Block * const block = *it;
       if( forest.atDomainXMinBorder(*block) )
       {
          maxInflowLevel = std::max( maxInflowLevel, block->getTargetLevel() );
@@ -1116,12 +1116,12 @@ void keepInflowOutflowAtTheSameLevel( std::vector< std::pair< const Block *, uin
    mpi::allReduceInplace( maxInflowLevel, mpi::MAX );
    mpi::allReduceInplace( maxOutflowLevel, mpi::MAX );
 
-   for( auto it = minTargetLevels.begin(); it != minTargetLevels.end(); ++it )
+   for(auto & minTargetLevel : minTargetLevels)
    {
-      const Block * const block = it->first;
+      const Block * const block = minTargetLevel.first;
       if( forest.atDomainXMinBorder(*block) )
       {
-         it->second = maxInflowLevel;
+         minTargetLevel.second = maxInflowLevel;
       }
       if( setup.strictlyObeyL )
       {
@@ -1130,10 +1130,10 @@ void keepInflowOutflowAtTheSameLevel( std::vector< std::pair< const Block *, uin
          auto p = aabb.center();
          p[0] = setup.L;
          if( aabb.contains(p) )
-            it->second = maxOutflowLevel;
+            minTargetLevel.second = maxOutflowLevel;
       }
       else if( forest.atDomainXMaxBorder(*block) )
-         it->second = maxOutflowLevel;
+         minTargetLevel.second = maxOutflowLevel;
    }
 }
 
@@ -1143,10 +1143,10 @@ void keepInflowOutflowAtTheSameLevel( std::vector< std::pair< const Block *, uin
 void pseudo2DTargetLevelCorrection( std::vector< std::pair< const Block *, uint_t > > & minTargetLevels,
                                     std::vector< const Block * > &, const blockforest::BlockForest & forest )
 {
-   for( auto it = minTargetLevels.begin(); it != minTargetLevels.end(); ++it )
+   for(auto & minTargetLevel : minTargetLevels)
    {
-      if( ! forest.atDomainZMinBorder( *(it->first ) ) )
-         it->second = uint_t(0);
+      if( ! forest.atDomainZMinBorder( *(minTargetLevel.first ) ) )
+         minTargetLevel.second = uint_t(0);
    }
 }
 
@@ -1177,12 +1177,12 @@ public:
    
    void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & )
    {
-      for( auto it = blockData.begin(); it != blockData.end(); ++it )
+      for(auto & it : blockData)
       {
-         if( it->first->getState().contains( state_ ) )
-            it->second = Pseudo2DPhantomWeight( markEmptyBlocks_ ? uint8_t(0) : uint8_t(1) );
+         if( it.first->getState().contains( state_ ) )
+            it.second = Pseudo2DPhantomWeight( markEmptyBlocks_ ? uint8_t(0) : uint8_t(1) );
          else
-            it->second = Pseudo2DPhantomWeight( markEmptyBlocks_ ? uint8_t(1) : uint8_t(0) );
+            it.second = Pseudo2DPhantomWeight( markEmptyBlocks_ ? uint8_t(1) : uint8_t(0) );
       }
    }
 
@@ -1297,10 +1297,9 @@ public:
                const bool logToStream = true, const bool logToFile = true, const std::string& filename = std::string("SchaeferTurek.txt"),
                const Set<SUID> & requiredSelectors = Set<SUID>::emptySet(),
                const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() ) :
-      initialized_( false ), blocks_( blocks ),
-      executionCounter_( uint_t(0) ), checkFrequency_( checkFrequency ), pdfFieldId_( pdfFieldId ), flagFieldId_( flagFieldId ),
-      fluid_( fluid ), obstacle_( obstacle ), setup_( setup ), D_( uint_t(0) ), AD_( real_t(0) ), AL_( real_t(0) ), forceEvaluationExecutionCount_( uint_t(0) ),
-      strouhalRising_( false ), strouhalNumberRealD_( real_t(0) ), strouhalNumberDiscreteD_( real_t(0) ), strouhalEvaluationExecutionCount_( uint_t(0) ),
+      blocks_( blocks ),
+      checkFrequency_( checkFrequency ), pdfFieldId_( pdfFieldId ), flagFieldId_( flagFieldId ),
+      fluid_( fluid ), obstacle_( obstacle ), setup_( setup ),
       logToStream_( logToStream ), logToFile_( logToFile ), filename_( filename ),
       requiredSelectors_( requiredSelectors ), incompatibleSelectors_( incompatibleSelectors )
    {
@@ -1345,13 +1344,13 @@ protected:
 
 
 
-   bool initialized_;
+   bool initialized_{ false };
 
    weak_ptr< StructuredBlockStorage > blocks_;
    std::map< IBlock *, std::vector< std::pair< Cell, stencil::Direction > > >  directions_;
 
-   uint_t executionCounter_;
-   uint_t checkFrequency_;
+   uint_t executionCounter_{ uint_c(0) };
+   uint_t checkFrequency_{ uint_c(0) };
    
    BlockDataID pdfFieldId_;
    BlockDataID flagFieldId_;
@@ -1361,23 +1360,23 @@ protected:
    
    Setup setup_;
 
-   uint_t D_;
-   real_t AD_;
-   real_t AL_;
+   uint_t D_{ uint_c(0) };
+   real_t AD_{ real_c(0) };
+   real_t AL_{ real_c(0) };
    
    Vector3< real_t > force_;
    std::vector< math::Sample > forceSample_;
-   uint_t forceEvaluationExecutionCount_;
+   uint_t forceEvaluationExecutionCount_{ uint_c(0) };
    
    std::vector< std::deque< real_t > > coefficients_;
    std::vector< std::pair< real_t, real_t > > coefficientExtremas_;
 
    std::vector< real_t > strouhalVelocities_;
    std::vector< uint_t > strouhalTimeStep_;
-   bool strouhalRising_;
-   real_t strouhalNumberRealD_;
-   real_t strouhalNumberDiscreteD_;
-   uint_t strouhalEvaluationExecutionCount_;
+   bool strouhalRising_{ false };
+   real_t strouhalNumberRealD_{ real_c(0) };
+   real_t strouhalNumberDiscreteD_{ real_c(0) };
+   uint_t strouhalEvaluationExecutionCount_{ uint_c(0) };
 
    bool logToStream_;
    bool logToFile_;
@@ -1604,10 +1603,10 @@ void Evaluation< LatticeModel_T >::operator()( IBlock * block, const uint_t leve
       const PdfField_T * const pdfField = block->template getData< PdfField_T >( pdfFieldId_ );
 
       const auto & directions = directions_[ block ];
-      for( auto pair = directions.begin(); pair != directions.end(); ++pair )
+      for(const auto & pair : directions)
       {
-         const Cell cell( pair->first );
-         const stencil::Direction direction( pair->second );
+         const Cell cell( pair.first );
+         const stencil::Direction direction( pair.second );
 
          const real_t scaleFactor = real_t(1) / real_c( uint_t(1) << ( (Is2D< LatticeModel_T >::value ? uint_t(1) : uint_t(2)) * level ) );
 
@@ -1712,8 +1711,8 @@ void Evaluation< LatticeModel_T >::getResultsForSQLOnRoot( std::map< std::string
 {
    WALBERLA_ROOT_SECTION()
    {
-      for( auto result = sqlResults_.begin(); result != sqlResults_.end(); ++result )
-         realProperties[ result->first ] = result->second;
+      for(const auto & sqlResult : sqlResults_)
+         realProperties[ sqlResult.first ] = sqlResult.second;
          
       integerProperties[ "forceEvaluationTimeStep" ] = int_c( forceEvaluationExecutionCount_ );
       integerProperties[ "strouhalEvaluationTimeStep" ] = int_c( strouhalEvaluationExecutionCount_ );
@@ -2155,7 +2154,7 @@ public:
 
    SnapshotSimulator( const weak_ptr<blockforest::StructuredBlockForest> & blocks,
                       const uint_t failAt, const uint_t failRangeBegin, const uint_t failRangeEnd, const bool failRebalance ) :
-      blocks_( blocks ), executionCounter_( 0 ),
+      blocks_( blocks ),
       failAt_( failAt ), failRangeBegin_( failRangeBegin ), failRangeEnd_( failRangeEnd ), failRebalance_( failRebalance )
    {}
 
@@ -2216,7 +2215,7 @@ private:
 
    weak_ptr<blockforest::StructuredBlockForest> blocks_;
 
-   uint_t executionCounter_;
+   uint_t executionCounter_{ uint_c(0) };
    uint_t failAt_;
 
    uint_t failRangeBegin_;
@@ -2302,11 +2301,11 @@ struct AddRefinementTimeStep
 };
 
 template< typename LatticeModel_T  >
-struct AddRefinementTimeStep< LatticeModel_T, typename std::enable_if< std::is_same< typename LatticeModel_T::CollisionModel::tag, lbm::collision_model::MRT_tag >::value ||
-                                                                       std::is_same< typename LatticeModel_T::Stencil, stencil::D2Q9 >::value ||
-                                                                       std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q15 >::value ||
-                                                                       std::is_same< typename LatticeModel_T::Stencil, stencil::D3Q27 >::value
-                                                                       >::type >
+struct AddRefinementTimeStep< LatticeModel_T, std::enable_if_t< std::is_same_v< typename LatticeModel_T::CollisionModel::tag, lbm::collision_model::MRT_tag > ||
+                                                                       std::is_same_v< typename LatticeModel_T::Stencil, stencil::D2Q9 > ||
+                                                                       std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q15 > ||
+                                                                       std::is_same_v< typename LatticeModel_T::Stencil, stencil::D3Q27 >
+                                                                       > >
 {
    static void add( SweepTimeloop & timeloop, shared_ptr< blockforest::StructuredBlockForest > & blocks,
                     const BlockDataID & pdfFieldId, const BlockDataID & flagFieldId, const BlockDataID & boundaryHandlingId,
@@ -2429,9 +2428,9 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
 
    if( vtkBeforeTimeStep )
    {
-      for( auto output = vtkOutputFunctions.begin(); output != vtkOutputFunctions.end(); ++output )
-         timeloop.addFuncBeforeTimeStep( output->second.outputFunction, std::string("VTK: ") + output->first,
-                                         output->second.requiredGlobalStates, output->second.incompatibleGlobalStates );
+      for(auto & output : vtkOutputFunctions)
+         timeloop.addFuncBeforeTimeStep( output.second.outputFunction, std::string("VTK: ") + output.first,
+                                        output.second.requiredGlobalStates, output.second.incompatibleGlobalStates );
    }
 
    // evaluation
@@ -2490,8 +2489,8 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
          adaptiveRefinementLog = oss.str();
       }
 
-      minTargetLevelDeterminationFunctions.add( std::bind( keepInflowOutflowAtTheSameLevel, std::placeholders::_1, std::placeholders::_2, 
-                                                           std::placeholders::_3, std::cref(setup) ) );
+      minTargetLevelDeterminationFunctions.add([setup_cref = std::cref(setup)](auto & minTargetLevels, auto & blocksAlreadyMarkedForRefinement, auto & bf) {
+         return keepInflowOutflowAtTheSameLevel(minTargetLevels, blocksAlreadyMarkedForRefinement, bf, setup_cref); } );
 
       if( Is2D< LatticeModel_T >::value )
          minTargetLevelDeterminationFunctions.add( pseudo2DTargetLevelCorrection );
@@ -2610,9 +2609,9 @@ void run( const shared_ptr< Config > & config, const LatticeModel_T & latticeMod
 
    if( !vtkBeforeTimeStep )
    {
-      for( auto output = vtkOutputFunctions.begin(); output != vtkOutputFunctions.end(); ++output )
-         timeloop.addFuncAfterTimeStep( output->second.outputFunction, std::string("VTK: ") + output->first,
-                                        output->second.requiredGlobalStates, output->second.incompatibleGlobalStates );
+      for(auto & output : vtkOutputFunctions)
+         timeloop.addFuncAfterTimeStep( output.second.outputFunction, std::string("VTK: ") + output.first,
+                                       output.second.requiredGlobalStates, output.second.incompatibleGlobalStates );
    }
 
    // stability check (non-finite values in the PDF field?)
@@ -3060,7 +3059,7 @@ int main( int argc, char **argv )
       refinementSelectionFunctions.add( cylinderRefinementSelection );
    }
 
-   refinementSelectionFunctions.add( std::bind( setInflowOutflowToSameLevel, std::placeholders::_1, setup ) );
+   refinementSelectionFunctions.add([&setup](auto & bf) { return setInflowOutflowToSameLevel(bf, setup); });
 
    if( setup.pseudo2D )
       refinementSelectionFunctions.add( Pseudo2DRefinementSelectionCorrection );
diff --git a/apps/showcases/Antidunes/Antidunes.cpp b/apps/showcases/Antidunes/Antidunes.cpp
index 48113869c8672be163c2c7c6e377d4b5b45f17a3..899ed8cb37d3323d36fee067a56d09b8a63e06a3 100644
--- a/apps/showcases/Antidunes/Antidunes.cpp
+++ b/apps/showcases/Antidunes/Antidunes.cpp
@@ -106,7 +106,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using ParticleAccessor_T = mesa_pd::data::ParticleAccessorWithBaseShape;
@@ -308,19 +308,19 @@ void initHydrostaticPressure(const std::weak_ptr< StructuredBlockForest >& block
 
       CellInterval local = pdfField->xyzSizeWithGhostLayer(); // block-, i.e., process-local cell interval
 
-      for (auto cellIt = local.begin(); cellIt != local.end(); ++cellIt)
+      for (const auto& cell : local)
       {
          // initialize the (hydrostatic) pressure, i.e., LBM density
          // Bernoulli: p = p0 + density * gravity * height
          // => LBM (density=1): rho = rho0 + gravity * height = 1 + 1/cs^2 * g * h = 1 + 3 * g * h
          // shift global cell by 0.5 since density is set for cell center
 
-         Vector3< real_t > cellCenter = blockForest->getBlockLocalCellCenter(*blockIt, *cellIt);
+         Vector3< real_t > cellCenter = blockForest->getBlockLocalCellCenter(*blockIt, cell);
          const real_t rho             = hydrostaticDensityFct(cellCenter);
 
-         const Vector3< real_t > velocity = pdfField->getVelocity(*cellIt);
+         const Vector3< real_t > velocity = pdfField->getVelocity(cell);
 
-         pdfField->setDensityAndVelocity(*cellIt, velocity, rho);
+         pdfField->setDensityAndVelocity(cell, velocity, rho);
       }
    }
 }
@@ -591,11 +591,9 @@ int main(int argc, char** argv)
    // read model parameters from parameter file
    const auto modelParameters               = configPtr->getOneBlock("ModelParameters");
    const std::string pdfReconstructionModel = modelParameters.getParameter< std::string >("pdfReconstructionModel");
-   const std::string pdfRefillingModel      = modelParameters.getParameter< std::string >("pdfRefillingModel");
    const std::string excessMassDistributionModel =
       modelParameters.getParameter< std::string >("excessMassDistributionModel");
    const walberla::free_surface::ExcessMassDistributionModel excessMassModel(excessMassDistributionModel);
-   const std::string curvatureModel          = modelParameters.getParameter< std::string >("curvatureModel");
    const bool useSimpleMassExchange          = modelParameters.getParameter< bool >("useSimpleMassExchange");
    const real_t cellConversionThreshold      = modelParameters.getParameter< real_t >("cellConversionThreshold");
    const real_t cellConversionForceThreshold = modelParameters.getParameter< real_t >("cellConversionForceThreshold");
@@ -1144,8 +1142,7 @@ int main(int argc, char** argv)
                           "Second ghost layer update: after excess mass distribution sweep (fill level field)")
          // update bubble model, i.e., perform registered bubble merges/splits; bubble merges/splits are
          // already detected and registered by CellConversionSweep
-         << AfterFunction(std::bind(&walberla::free_surface::bubble_model::BubbleModelBase::update, bubbleModel),
-                          "Sweep: bubble model update");
+         << AfterFunction([&bubbleModel]() { bubbleModel->update(); }, "Sweep: bubble model update");
    }
    else
    {
@@ -1163,8 +1160,7 @@ int main(int argc, char** argv)
                              "Second ghost layer update: after excess mass distribution sweep (fill level field)")
             // update bubble model, i.e., perform registered bubble merges/splits; bubble merges/splits
             // are already detected and registered by CellConversionSweep
-            << AfterFunction(std::bind(&walberla::free_surface::bubble_model::BubbleModelBase::update, bubbleModel),
-                             "Sweep: bubble model update");
+            << AfterFunction([&]() { bubbleModel->update(); }, "Sweep: bubble model update");
       }
       else
       {
@@ -1184,8 +1180,7 @@ int main(int argc, char** argv)
                                 "Second ghost layer update: after excess mass distribution sweep (fill level field)")
                // update bubble model, i.e., perform registered bubble merges/splits; bubble
                // merges/splits are already detected and registered by CellConversionSweep
-               << AfterFunction(std::bind(&walberla::free_surface::bubble_model::BubbleModelBase::update, bubbleModel),
-                                "Sweep: bubble model update");
+               << AfterFunction([&]() { bubbleModel->update(); }, "Sweep: bubble model update");
          }
       }
    }
@@ -1540,14 +1535,14 @@ int main(int argc, char** argv)
          {
             WALBERLA_LOG_INFO_ON_ROOT("Writing checkpointing file in time step " << t)
 
-            blockForest->saveBlockData(snapshotBaseFolder + "/tmp_" + pdfFieldFile, pdfFieldID);
-            blockForest->saveBlockData(snapshotBaseFolder + "/tmp_" + fillFieldFile, fillFieldID);
-            blockForest->saveBlockData(snapshotBaseFolder + "/tmp_" + excessMassFieldFile, excessMassFieldID);
-            blockForest->saveBlockData(snapshotBaseFolder + "/tmp_" + particleStorageFile, particleStorageID);
+            blockForest->saveBlockData(snapshotBaseFolder + std::string("/tmp_") += pdfFieldFile, pdfFieldID);
+            blockForest->saveBlockData(snapshotBaseFolder + "/tmp_" += fillFieldFile, fillFieldID);
+            blockForest->saveBlockData(snapshotBaseFolder + "/tmp_" += excessMassFieldFile, excessMassFieldID);
+            blockForest->saveBlockData(snapshotBaseFolder + "/tmp_" += particleStorageFile, particleStorageID);
 
             WALBERLA_ROOT_SECTION()
             {
-               std::string tmpCheckpointConfigFile = snapshotBaseFolder + "/tmp_" + checkpointConfigFile;
+               std::string tmpCheckpointConfigFile = snapshotBaseFolder + "/tmp_" += checkpointConfigFile;
                std::ofstream file;
                file.open(tmpCheckpointConfigFile.c_str());
 
@@ -1566,14 +1561,14 @@ int main(int argc, char** argv)
             // checkpointing
             WALBERLA_ROOT_SECTION()
             {
-               renameFile(snapshotBaseFolder + "/tmp_" + pdfFieldFile, snapshotBaseFolder + "/" + pdfFieldFile);
-               renameFile(snapshotBaseFolder + "/tmp_" + fillFieldFile, snapshotBaseFolder + "/" + fillFieldFile);
-               renameFile(snapshotBaseFolder + "/tmp_" + excessMassFieldFile,
-                          snapshotBaseFolder + "/" + excessMassFieldFile);
-               renameFile(snapshotBaseFolder + "/tmp_" + particleStorageFile,
-                          snapshotBaseFolder + "/" + particleStorageFile);
-               renameFile(snapshotBaseFolder + "/tmp_" + checkpointConfigFile,
-                          snapshotBaseFolder + "/" + checkpointConfigFile);
+               renameFile(snapshotBaseFolder + "/tmp_" += pdfFieldFile, snapshotBaseFolder + "/" += pdfFieldFile);
+               renameFile(snapshotBaseFolder + "/tmp_" += fillFieldFile, snapshotBaseFolder + "/" += fillFieldFile);
+               renameFile(snapshotBaseFolder + "/tmp_" += excessMassFieldFile,
+                          snapshotBaseFolder + "/" += excessMassFieldFile);
+               renameFile(snapshotBaseFolder + "/tmp_" += particleStorageFile,
+                          snapshotBaseFolder + "/" += particleStorageFile);
+               renameFile(snapshotBaseFolder + "/tmp_" += checkpointConfigFile,
+                          snapshotBaseFolder + "/" += checkpointConfigFile);
             }
          }
       }
diff --git a/apps/showcases/Antidunes/AntidunesBoundaryHandling.h b/apps/showcases/Antidunes/AntidunesBoundaryHandling.h
index f210d8e74f3a638ddfa691f3c1cac05bba14acd8..bc9adcbbb17698fd65d95e059e9b2510b9885db9 100644
--- a/apps/showcases/Antidunes/AntidunesBoundaryHandling.h
+++ b/apps/showcases/Antidunes/AntidunesBoundaryHandling.h
@@ -59,7 +59,7 @@ class AntidunesBoundaryHandling
    using flag_t    = typename FlagField_T::value_type;
    using Stencil_T = typename LatticeModel_T::Stencil;
    using CommunicationStencil_T =
-      typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+      std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
    using PdfField_T = lbm::PdfField< LatticeModel_T >;
 
    // boundary
diff --git a/apps/showcases/Antidunes/PIDController.cpp b/apps/showcases/Antidunes/PIDController.cpp
index 83df9f470f30f259a4cdab8073ff4e67ff0f1f86..833355eedc4b92d50614a09c25d74b9f678abb15 100644
--- a/apps/showcases/Antidunes/PIDController.cpp
+++ b/apps/showcases/Antidunes/PIDController.cpp
@@ -16,7 +16,7 @@ PIDController::PIDController()
    : commandVariable_(0), actuatingVariable_(0), proportionalGain_(0), derivateGain_(0), integralGain_(0), maxRamp_(0),
      minActuatingVariable_(0), maxActuatingVariable_(0), errorIntegral_(0)
 {
-   std::fill(errorHistory_, errorHistory_ + sizeof(errorHistory_) / sizeof(real_t), real_t(0));
+   std::fill(errorHistory_.data(), errorHistory_.data() + sizeof(errorHistory_) / sizeof(real_t), real_t(0));
 }
 
 PIDController::PIDController(const real_t commandVariable, const real_t initialActuatingVariable,
@@ -26,7 +26,7 @@ PIDController::PIDController(const real_t commandVariable, const real_t initialA
      proportionalGain_(proportionalGain), derivateGain_(derivateGain), integralGain_(integralGain), maxRamp_(maxRamp),
      minActuatingVariable_(minActuatingVariable), maxActuatingVariable_(maxActuatingVariable), errorIntegral_(0)
 {
-   std::fill(errorHistory_, errorHistory_ + sizeof(errorHistory_) / sizeof(real_t), real_t(0));
+   std::fill(errorHistory_.data(), errorHistory_.data() + sizeof(errorHistory_) / sizeof(real_t), real_t(0));
 
    if (integralGain_ > real_t(0))
       errorIntegral_ = initialActuatingVariable / integralGain_;
@@ -41,7 +41,7 @@ PIDController::PIDController(const real_t commandVariable, const real_t initialA
      maxRamp_(std::numeric_limits< real_t >::max()), minActuatingVariable_(-std::numeric_limits< real_t >::max()),
      maxActuatingVariable_(std::numeric_limits< real_t >::max()), errorIntegral_(0)
 {
-   std::fill(errorHistory_, errorHistory_ + sizeof(errorHistory_) / sizeof(real_t), real_t(0));
+   std::fill(errorHistory_.data(), errorHistory_.data() + sizeof(errorHistory_) / sizeof(real_t), real_t(0));
 
    if (integralGain_ > real_t(0))
       errorIntegral_ = initialActuatingVariable / integralGain_;
@@ -56,7 +56,8 @@ real_t PIDController::update(const real_t controlledVariable)
 
    const real_t d =
       (error + real_t(3) * errorHistory_[0] - real_t(3) * errorHistory_[1] - errorHistory_[2]) * ONE_OVER_SIX;
-   std::rotate(errorHistory_, errorHistory_ + 1, errorHistory_ + sizeof(errorHistory_) / sizeof(real_t));
+   std::rotate(errorHistory_.data(), errorHistory_.data() + 1,
+               errorHistory_.data() + sizeof(errorHistory_) / sizeof(real_t));
    errorHistory_[sizeof(errorHistory_) / sizeof(real_t) - size_t(1)] = error;
 
    real_t newActuationVariable = proportionalGain_ * error + derivateGain_ * d + integralGain_ * errorIntegral_;
diff --git a/apps/showcases/Antidunes/PIDController.h b/apps/showcases/Antidunes/PIDController.h
index aeae57260688bbeca012a240fac40209e94e2e55..77d27cc3529fb9376545fd3b4344f7a75e7e33ed 100644
--- a/apps/showcases/Antidunes/PIDController.h
+++ b/apps/showcases/Antidunes/PIDController.h
@@ -46,6 +46,6 @@ class PIDController
    real_t minActuatingVariable_;
    real_t maxActuatingVariable_;
 
-   real_t errorHistory_[3];
+   std::array< real_t, 3 > errorHistory_;
    real_t errorIntegral_;
 };
diff --git a/apps/showcases/Antidunes/Utility.h b/apps/showcases/Antidunes/Utility.h
index e3e0e2149a01f26ee097287494d2d982ef9025c3..a91786e44cc439d77cbe637531bd5f54f4b09f65 100644
--- a/apps/showcases/Antidunes/Utility.h
+++ b/apps/showcases/Antidunes/Utility.h
@@ -41,13 +41,13 @@ struct SphereSelector
    template< typename ParticleAccessor_T >
    bool inline operator()(const size_t particleIdx, const ParticleAccessor_T& ac) const
    {
-      static_assert(std::is_base_of< mesa_pd::data::IAccessor, ParticleAccessor_T >::value,
+      static_assert(std::is_base_of_v< mesa_pd::data::IAccessor, ParticleAccessor_T >,
                     "Provide a valid accessor as template");
       return ac.getBaseShape(particleIdx)->getShapeType() == mesa_pd::data::Sphere::SHAPE_TYPE;
    }
 };
 
-void renameFile(const std::string& oldName, const std::string& newName)
+inline void renameFile(const std::string& oldName, const std::string& newName)
 {
    int result = std::rename(oldName.c_str(), newName.c_str());
    if (result != 0)
@@ -55,7 +55,7 @@ void renameFile(const std::string& oldName, const std::string& newName)
                                                             << result);
 }
 
-void write2DVectorToFile(const std::vector< real_t >& vec, uint_t len1, uint_t len2, std::string filename)
+inline void write2DVectorToFile(const std::vector< real_t >& vec, uint_t len1, uint_t len2, std::string filename)
 {
    std::ofstream file;
    file.open(filename.c_str());
@@ -184,22 +184,22 @@ class AverageDataSliceEvaluator
          maxFluidZPos_ = uint_t(0);
 
          // iterate all (inner) cells in the field
-         for (auto cell = xyz.begin(); cell != xyz.end(); ++cell)
+         for (auto cell : xyz)
          {
-            blocks_->transformBlockLocalToGlobalCell(globalCell, *block, *cell);
+            blocks_->transformBlockLocalToGlobalCell(globalCell, *block, cell);
             auto entryIdx = uint_c(globalCell.x()) + uint_c(globalCell.z()) * xlen_;
-            if (flagField->isFlagSet(*cell, solidMO) || flagField->isFlagSet(*cell, solidNoSlip))
+            if (flagField->isFlagSet(cell, solidMO) || flagField->isFlagSet(cell, solidNoSlip))
             {
                x_z_SolidVolumeFraction_[entryIdx] += real_t(1);
                x_z_FillLevel_[entryIdx] += real_t(1);
             }
             else
             {
-               auto fillLevel = fillField->get(*cell);
+               auto fillLevel = fillField->get(cell);
                x_z_FillLevel_[entryIdx] += fillLevel;
                if (fillLevel > 0_r)
                {
-                  x_z_VelocityX_[entryIdx] += pdfField->getVelocity(*cell)[0];
+                  x_z_VelocityX_[entryIdx] += pdfField->getVelocity(cell)[0];
                   ++x_z_FluidCellCount_[entryIdx];
 
                   maxFluidZPos_ = std::max(uint_t(globalCell.z()), maxFluidZPos_);
@@ -254,7 +254,7 @@ class AverageDataSliceEvaluator
    std::vector< uint_t > x_z_FluidCellCount_;
 };
 
-void writeSphereInformationToFile(const std::string& filename, walberla::mesa_pd::data::ParticleStorage& ps,
+inline void writeSphereInformationToFile(const std::string& filename, walberla::mesa_pd::data::ParticleStorage& ps,
                                   Vector3< real_t >& domainSize, int precision = 12)
 {
    std::ostringstream ossData;
@@ -279,7 +279,7 @@ void writeSphereInformationToFile(const std::string& filename, walberla::mesa_pd
    walberla::mpi::writeMPITextFile(filename, ossData.str());
 }
 
-void getAvgDiameterScalingFactor(const std::string& filename, const Vector3< uint_t >& domainSize,
+inline void getAvgDiameterScalingFactor(const std::string& filename, const Vector3< uint_t >& domainSize,
                                  const uint_t bedCopiesInX, const uint_t bedCopiesInY, real_t& avgDiameter,
                                  real_t& scalingFactor)
 {
@@ -333,7 +333,7 @@ void getAvgDiameterScalingFactor(const std::string& filename, const Vector3< uin
    walberla::mpi::broadcastObject(avgDiameter);
 }
 
-void initSpheresFromFile(const std::string& filename, walberla::mesa_pd::data::ParticleStorage& ps,
+inline void initSpheresFromFile(const std::string& filename, walberla::mesa_pd::data::ParticleStorage& ps,
                          const walberla::mesa_pd::domain::IDomain& domain, walberla::real_t density,
                          const Vector3< uint_t >& domainSize,
                          const std::function< bool(walberla::Vector3< real_t >) >& particleCreateFunction,
@@ -425,7 +425,7 @@ void initSpheresFromFile(const std::string& filename, walberla::mesa_pd::data::P
    walberla::mpi::allReduceInplace(numParticles, walberla::mpi::SUM);
 }
 
-void getAverageVelocity(const mesa_pd::data::ParticleAccessorWithBaseShape& ac, real_t& averageVelocity,
+inline void getAverageVelocity(const mesa_pd::data::ParticleAccessorWithBaseShape& ac, real_t& averageVelocity,
                         real_t& maxVelocity, uint_t& numParticles, real_t& maxHeight)
 {
    averageVelocity = real_t(0);
@@ -452,7 +452,7 @@ void getAverageVelocity(const mesa_pd::data::ParticleAccessorWithBaseShape& ac,
    averageVelocity /= real_t(numParticles);
 }
 
-auto createPlane(mesa_pd::data::ParticleStorage& ps, const mesa_pd::Vec3& pos, const mesa_pd::Vec3& normal)
+inline auto createPlane(mesa_pd::data::ParticleStorage& ps, const mesa_pd::Vec3& pos, const mesa_pd::Vec3& normal)
 {
    auto p0 = ps.create(true);
    p0->setPosition(pos);
diff --git a/apps/showcases/FluidizedBed/FluidizedBedMEM.cpp b/apps/showcases/FluidizedBed/FluidizedBedMEM.cpp
index 2eb0e481e35f5fe2f25967aba47952d0d1705062..2907d18a2eaf51cced2d3408115679e4122b0c3f 100644
--- a/apps/showcases/FluidizedBed/FluidizedBedMEM.cpp
+++ b/apps/showcases/FluidizedBed/FluidizedBedMEM.cpp
@@ -302,7 +302,7 @@ std::ostream& operator<<(std::ostream& os, ParticleInfo const& m)
 template< typename Accessor_T >
 ParticleInfo evaluateParticleInfo(const Accessor_T& ac)
 {
-   static_assert(std::is_base_of< mesa_pd::data::IAccessor, Accessor_T >::value, "Provide a valid accessor");
+   static_assert(std::is_base_of_v< mesa_pd::data::IAccessor, Accessor_T >, "Provide a valid accessor");
 
    ParticleInfo info;
    for (uint_t i = 0; i < ac.size(); ++i)
diff --git a/apps/showcases/FluidizedBed/FluidizedBedPSM.cpp b/apps/showcases/FluidizedBed/FluidizedBedPSM.cpp
index b35bca1bb18e2e9ef92df8ae0f7b5520d6c9fec7..b5a408a9f3247cdd39fe130c19ae059d0f23fc11 100644
--- a/apps/showcases/FluidizedBed/FluidizedBedPSM.cpp
+++ b/apps/showcases/FluidizedBed/FluidizedBedPSM.cpp
@@ -295,7 +295,7 @@ std::ostream& operator<<(std::ostream& os, ParticleInfo const& m)
 template< typename Accessor_T >
 ParticleInfo evaluateParticleInfo(const Accessor_T& ac)
 {
-   static_assert(std::is_base_of< mesa_pd::data::IAccessor, Accessor_T >::value, "Provide a valid accessor");
+   static_assert(std::is_base_of_v< mesa_pd::data::IAccessor, Accessor_T >, "Provide a valid accessor");
 
    ParticleInfo info;
    for (uint_t i = 0; i < ac.size(); ++i)
diff --git a/apps/showcases/FreeSurface/BubblyPoiseuille.cpp b/apps/showcases/FreeSurface/BubblyPoiseuille.cpp
index e54117c159c3ac0dc4de3f507e642ead83f474af..90791430392ce90071edd96e26f5fe5221828e8b 100644
--- a/apps/showcases/FreeSurface/BubblyPoiseuille.cpp
+++ b/apps/showcases/FreeSurface/BubblyPoiseuille.cpp
@@ -55,7 +55,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using flag_t                        = uint32_t;
diff --git a/apps/showcases/FreeSurface/CapillaryWave.cpp b/apps/showcases/FreeSurface/CapillaryWave.cpp
index 376a8d9cb0810f76a58cc1485bf7cb4bedf67c55..b492c4763c186f64f74a0ca61cf99625a64d7778 100644
--- a/apps/showcases/FreeSurface/CapillaryWave.cpp
+++ b/apps/showcases/FreeSurface/CapillaryWave.cpp
@@ -54,7 +54,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using flag_t                        = uint32_t;
diff --git a/apps/showcases/FreeSurface/DamBreakCylindrical.cpp b/apps/showcases/FreeSurface/DamBreakCylindrical.cpp
index 31ee52c2cfbedc43f5c17aa7abaa2e54a36c4d1e..1cafbd61cca0da7ca5a6cc4e0fcfcfbc72717de1 100644
--- a/apps/showcases/FreeSurface/DamBreakCylindrical.cpp
+++ b/apps/showcases/FreeSurface/DamBreakCylindrical.cpp
@@ -61,7 +61,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using flag_t                        = uint32_t;
@@ -258,13 +258,13 @@ class ColumnHeightEvaluator
 
             const FlagField_T* const flagField = blockIt->template getData< const FlagField_T >(flagFieldID);
 
-            for (auto c = localSearchInterval.begin(); c != localSearchInterval.end(); ++c)
+            for (auto c : localSearchInterval)
             {
-               if (flagInfo.isInterface(flagField->get(*c)))
+               if (flagInfo.isInterface(flagField->get(c)))
                {
-                  if (c->y() >= maxColumnHeight)
+                  if (c.y() >= maxColumnHeight)
                   {
-                     maxColumnHeight  = c->y();
+                     maxColumnHeight  = c.y();
                      isInterfaceFound = true;
                   }
                }
diff --git a/apps/showcases/FreeSurface/DamBreakRectangular.cpp b/apps/showcases/FreeSurface/DamBreakRectangular.cpp
index 8f7c29e3fbbed58e349d57197a60d412ddca92d0..29fe2626980c4a056b8de077866c744de6fc1725 100644
--- a/apps/showcases/FreeSurface/DamBreakRectangular.cpp
+++ b/apps/showcases/FreeSurface/DamBreakRectangular.cpp
@@ -56,7 +56,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using flag_t                        = uint32_t;
@@ -129,13 +129,13 @@ class ColumnHeightEvaluator
 
             const FlagField_T* const flagField = blockIt->template getData< const FlagField_T >(flagFieldID);
 
-            for (auto c = localSearchInterval.begin(); c != localSearchInterval.end(); ++c)
+            for (auto c : localSearchInterval)
             {
-               if (flagInfo.isInterface(flagField->get(*c)))
+               if (flagInfo.isInterface(flagField->get(c)))
                {
-                  if (c->y() >= maxColumnHeight)
+                  if (c.y() >= maxColumnHeight)
                   {
-                     maxColumnHeight  = c->y();
+                     maxColumnHeight  = c.y();
                      isInterfaceFound = true;
                   }
                }
@@ -214,13 +214,13 @@ class ColumnWidthEvaluator
 
             const FlagField_T* const flagField = blockIt->template getData< const FlagField_T >(flagFieldID);
 
-            for (auto c = localSearchInterval.begin(); c != localSearchInterval.end(); ++c)
+            for (auto c : localSearchInterval)
             {
-               if (flagInfo.isInterface(flagField->get(*c)))
+               if (flagInfo.isInterface(flagField->get(c)))
                {
-                  if (c->x() >= maxColumnWidth)
+                  if (c.x() >= maxColumnWidth)
                   {
-                     maxColumnWidth   = c->x();
+                     maxColumnWidth   = c.x();
                      isInterfaceFound = true;
                   }
                }
diff --git a/apps/showcases/FreeSurface/DropImpact.cpp b/apps/showcases/FreeSurface/DropImpact.cpp
index 61da9474b18682bf4e26e075d29bc917172df934..9d60414a6f90f76880f1747102d84581118be357 100644
--- a/apps/showcases/FreeSurface/DropImpact.cpp
+++ b/apps/showcases/FreeSurface/DropImpact.cpp
@@ -56,7 +56,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using flag_t                        = uint32_t;
diff --git a/apps/showcases/FreeSurface/DropWetting.cpp b/apps/showcases/FreeSurface/DropWetting.cpp
index a55ad88083021fa3cc3f86caa3b7d8248a7e199d..5c90ca81d8eca79a88e5e279b61ab72fb5ef4dbc 100644
--- a/apps/showcases/FreeSurface/DropWetting.cpp
+++ b/apps/showcases/FreeSurface/DropWetting.cpp
@@ -56,7 +56,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using flag_t                        = uint32_t;
diff --git a/apps/showcases/FreeSurface/GravityWave.cpp b/apps/showcases/FreeSurface/GravityWave.cpp
index 702682bcf0aa37a77ec8e54dea1ba2155810c66c..5ba4d7e3faf66b5a99e97f5f63e7d708166a250d 100644
--- a/apps/showcases/FreeSurface/GravityWave.cpp
+++ b/apps/showcases/FreeSurface/GravityWave.cpp
@@ -55,7 +55,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using flag_t                        = uint32_t;
diff --git a/apps/showcases/FreeSurface/MovingDrop.cpp b/apps/showcases/FreeSurface/MovingDrop.cpp
index 4fb4c49d34f3031f74c480795d9873c90a7cc91b..bdde7da6f8801990df0c1c9942edf21ad8ef1d04 100644
--- a/apps/showcases/FreeSurface/MovingDrop.cpp
+++ b/apps/showcases/FreeSurface/MovingDrop.cpp
@@ -54,7 +54,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using flag_t                        = uint32_t;
diff --git a/apps/showcases/FreeSurface/RisingBubble.cpp b/apps/showcases/FreeSurface/RisingBubble.cpp
index 27e714c319928f9f79886d35f05159b7f3bffb28..6f5c0f272f864371f5d0d539141dcf25e57f6005 100644
--- a/apps/showcases/FreeSurface/RisingBubble.cpp
+++ b/apps/showcases/FreeSurface/RisingBubble.cpp
@@ -56,7 +56,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using flag_t                        = uint32_t;
diff --git a/apps/showcases/FreeSurface/TaylorBubble.cpp b/apps/showcases/FreeSurface/TaylorBubble.cpp
index 9685f8fad1ef28bec990ec4e380b4a4bd12f99b4..484986d8aa60509e9a52588fefa9934d23bdfe7d 100644
--- a/apps/showcases/FreeSurface/TaylorBubble.cpp
+++ b/apps/showcases/FreeSurface/TaylorBubble.cpp
@@ -57,7 +57,7 @@ using PdfCommunication_T    = blockforest::SimpleCommunication< LatticeModelSten
 // the geometry computations in SurfaceGeometryHandler require meaningful values in the ghost layers in corner
 // directions (flag field and fill level field); this holds, even if the lattice model uses a D3Q19 stencil
 using CommunicationStencil_T =
-   typename std::conditional< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >::type;
+   std::conditional_t< LatticeModel_T::Stencil::D == uint_t(2), stencil::D2Q9, stencil::D3Q27 >;
 using Communication_T = blockforest::SimpleCommunication< CommunicationStencil_T >;
 
 using flag_t                        = uint32_t;
diff --git a/apps/showcases/LightRisingParticleInFluidAMR/LightRisingParticleInFluidAMR.cpp b/apps/showcases/LightRisingParticleInFluidAMR/LightRisingParticleInFluidAMR.cpp
index 86d1978670867aa33d8011aff1a4b46dd27660a8..57f37f0eb89eda88dfb1b13bd7e9501bebc676c9 100644
--- a/apps/showcases/LightRisingParticleInFluidAMR/LightRisingParticleInFluidAMR.cpp
+++ b/apps/showcases/LightRisingParticleInFluidAMR/LightRisingParticleInFluidAMR.cpp
@@ -155,23 +155,23 @@ const FlagUID FormerMO_Flag("former moving obstacle");
 static void refinementSelection(SetupBlockForest &forest, uint_t levels, AABB refinementBox) {
    real_t dx = real_t(1); // dx on finest level
    const uint_t finestLevel = levels - uint_t(1);
-   for (auto block = forest.begin(); block != forest.end(); ++block) {
-      uint_t blockLevel = block->getLevel();
+   for (auto & block : forest) {
+      uint_t blockLevel = block.getLevel();
       uint_t levelScalingFactor = (uint_t(1) << (finestLevel - blockLevel));
       real_t dxOnLevel = dx * real_c(levelScalingFactor);
-      AABB blockAABB = block->getAABB();
+      AABB blockAABB = block.getAABB();
       // extend block AABB by ghostlayers
       AABB extendedBlockAABB = blockAABB.getExtended(dxOnLevel * real_c(FieldGhostLayers));
       if (extendedBlockAABB.intersects(refinementBox))
          if (blockLevel < finestLevel) // only if the block is not on the finest level
-            block->setMarker(true);
+            block.setMarker(true);
    }
 }
 
 static void workloadAndMemoryAssignment(SetupBlockForest &forest) {
-   for (auto block = forest.begin(); block != forest.end(); ++block) {
-      block->setWorkload(numeric_cast<workload_t>(uint_t(1) << block->getLevel()));
-      block->setMemory(numeric_cast<memory_t>(1));
+   for (auto & block : forest) {
+      block.setWorkload(numeric_cast<workload_t>(uint_t(1) << block.getLevel()));
+      block.setMemory(numeric_cast<memory_t>(1));
    }
 }
 static shared_ptr<StructuredBlockForest>
@@ -212,7 +212,7 @@ createBlockStructure(const AABB &domainAABB, Vector3<uint_t> blockSizeInCells, u
       WALBERLA_LOG_INFO_ON_ROOT(" - refinement box: " << refinementBox);
 
       sforest.addRefinementSelectionFunction(
-              std::bind(refinementSelection, std::placeholders::_1, numberOfLevels, refinementBox));
+              [numberOfLevels, refinementBox](SetupBlockForest& block) { refinementSelection(block, numberOfLevels, refinementBox); });
       sforest.addWorkloadMemorySUIDAssignmentFunction(workloadAndMemoryAssignment);
 
       sforest.init(domainAABB, numberOfCoarseBlocksPerDirection[0], numberOfCoarseBlocksPerDirection[1],
@@ -922,7 +922,7 @@ int main(int argc, char** argv) {
    // add velocity field and utility
    BlockDataID velocityFieldID = field::addToStorage<VelocityField_T>( blocks, "velocity field", Vector3<real_t>(real_t(0)), field::fzyx, uint_t(2) );
 
-   typedef lbm::VelocityFieldWriter< PdfField_T, VelocityField_T > VelocityFieldWriter_T;
+   using VelocityFieldWriter_T = lbm::VelocityFieldWriter<PdfField_T, VelocityField_T>;
    BlockSweepWrapper< VelocityFieldWriter_T > velocityFieldWriter( blocks, VelocityFieldWriter_T( pdfFieldID, velocityFieldID ) );
 
    shared_ptr<blockforest::communication::NonUniformBufferedScheme<stencil::D3Q27> > velocityCommunicationScheme = make_shared<blockforest::communication::NonUniformBufferedScheme<stencil::D3Q27> >( blocks );
@@ -931,7 +931,7 @@ int main(int argc, char** argv) {
    // add q criterion field (only needed for mesh output)
    BlockDataID qCriterionFieldID = field::addToStorage<QCriterionField_T>(blocks, "q criterion field", real_t(0), field::fzyx, uint_t(1));
 
-   typedef lbm::QCriterionFieldWriter<VelocityField_T, QCriterionField_T, FluidFilter_T> QCriterionFieldWriter_T;
+   using QCriterionFieldWriter_T = lbm::QCriterionFieldWriter<VelocityField_T, QCriterionField_T, FluidFilter_T>;
    BlockSweepWrapper<QCriterionFieldWriter_T> qCriterionFieldWriter(blocks, QCriterionFieldWriter_T(blocks, velocityFieldID,
            qCriterionFieldID, fluidFlagFieldEvaluationFilter));
 
diff --git a/apps/showcases/PhaseFieldAllenCahn/GPU/util.cpp b/apps/showcases/PhaseFieldAllenCahn/GPU/util.cpp
index f6694910ce7e1c25b5549c9ed2bfb49378ce6b2c..11ff724bf696b9d43e93cca86f1164d9928e9c04 100644
--- a/apps/showcases/PhaseFieldAllenCahn/GPU/util.cpp
+++ b/apps/showcases/PhaseFieldAllenCahn/GPU/util.cpp
@@ -101,7 +101,7 @@ void flood_fill(PhaseField_T& phaseField, VelocityField_T& velocityField, CellIn
    center_of_mass[1] += real_c(startCell.y() + boundingBox.yMin());
    center_of_mass[2] += real_c(startCell.z() + boundingBox.xMin());
 
-   const int DIRS[6] = { N, S, E, W, T, B };
+   const uint_t DIRS[6] = { N, S, E, W, T, B };
 
    CellInterval sizeInterval = phaseField.xyzSize();
    while (!cellQueue.empty())
@@ -109,7 +109,7 @@ void flood_fill(PhaseField_T& phaseField, VelocityField_T& velocityField, CellIn
       Cell& cell = cellQueue.front();
       cellQueue.pop();
 
-      for (int i : DIRS)
+      for (uint_t i : DIRS)
       {
          Cell neighborCell(cell.x() + cx[i], cell.y() + cy[i], cell.z() + cz[i]);
 
diff --git a/apps/tutorials/basics/02_Sweeps.cpp b/apps/tutorials/basics/02_Sweeps.cpp
index 85fc3e69d32f26e9fe512a137b046dc73c0ff20f..656992353ee42e482640ed5d06f30a857fc76366 100644
--- a/apps/tutorials/basics/02_Sweeps.cpp
+++ b/apps/tutorials/basics/02_Sweeps.cpp
@@ -125,9 +125,7 @@ int main( int argc, char ** argv )
    SweepTimeloop timeloop( blocks, numberOfTimesteps );
 
    // registering the function sweep
-   auto pointerToTwoArgFunction = & simpleSweep;
-   auto pointerToOneArgFunction = std::bind( pointerToTwoArgFunction, std::placeholders::_1, fieldID );
-   timeloop.add() << Sweep( pointerToOneArgFunction, "BogusAlgorithm" );
+   timeloop.add() << Sweep( [fieldID](IBlock * block){ simpleSweep(block, fieldID); }, "BogusAlgorithm" );
 
    // registering the class sweep
    timeloop.add() << Sweep( SimpleSweep(fieldID), "BogusAlgorithmButNowAsFunctor" );
diff --git a/apps/tutorials/lbm/05_BackwardFacingStep.cpp b/apps/tutorials/lbm/05_BackwardFacingStep.cpp
index 1fdc44a7524ad79071c7c58ff39ed306ee1245a0..0c45080c21309b5de08ecae9587891e260ce61c4 100644
--- a/apps/tutorials/lbm/05_BackwardFacingStep.cpp
+++ b/apps/tutorials/lbm/05_BackwardFacingStep.cpp
@@ -125,8 +125,8 @@ public:
       WALBERLA_ROOT_SECTION() {
          std::ofstream fileLocBottom(filename_.c_str(), std::ios_base::app);
          fileLocBottom << executionCounter_ << " ";
-         for (auto i = reattachmentLocations.begin(); i != reattachmentLocations.end(); i++) {
-            fileLocBottom << *i << " ";
+         for (auto i : reattachmentLocations) {
+            fileLocBottom << i << " ";
          }
          fileLocBottom << std::endl;
          fileLocBottom.close();
diff --git a/apps/tutorials/lbm/06_LBBoundaryCondition.cpp b/apps/tutorials/lbm/06_LBBoundaryCondition.cpp
index 9b215a0e9ca13c5a91b0b67486c2efe151b79a16..ef6de7ff8b35ca11f31367e74216aae60c9e4687 100644
--- a/apps/tutorials/lbm/06_LBBoundaryCondition.cpp
+++ b/apps/tutorials/lbm/06_LBBoundaryCondition.cpp
@@ -245,15 +245,15 @@ BoundaryHandling_T* MyBoundaryHandling::operator()(IBlock* const block,
       Cell offset(0, 0, 0);
       storage->transformBlockLocalToGlobalCell(offset, *block);
 
-      for (auto cellIt = west.begin(); cellIt != west.end(); ++cellIt)
+      for (auto cellIt : west)
       {
-         Cell globalCell = *cellIt + offset;
+         Cell globalCell = cellIt + offset;
          const real_t y = real_c(globalCell[1]);
 
          Vector3< real_t > ubbVel(0);
          ubbVel[0] = -real_t(4) * y * (y - H) / (H * H) * setup_.inflowVelocity[0];
 
-         handling->forceBoundary(UBBFlagUID, cellIt->x(), cellIt->y(), cellIt->z(), UBB_T::Velocity(ubbVel));
+         handling->forceBoundary(UBBFlagUID, cellIt.x(), cellIt.y(), cellIt.z(), UBB_T::Velocity(ubbVel));
       }
       //! [forceBoundary_UBB]
    }
@@ -267,10 +267,10 @@ BoundaryHandling_T* MyBoundaryHandling::operator()(IBlock* const block,
    {
       //! [forceBoundary_ParserUBB_eqs]
       const uint_t maxSize = 150;
-      char x_eq[maxSize];
-      snprintf(x_eq, maxSize, "0.1*4/%f/%f * y * (%f - y) * 0.5 * (1 - cos(2 * 3.1415926538 * t / %f));", H, H, H, setup_.period);
+      std::array<char, maxSize> x_eq;
+      snprintf(x_eq.data(), maxSize, "0.1*4/%f/%f * y * (%f - y) * 0.5 * (1 - cos(2 * 3.1415926538 * t / %f));", H, H, H, setup_.period);
 
-      std::array< std::string, 3 > eqs = { x_eq, "0", "0" };
+      std::array< std::string, 3 > eqs = { x_eq.data(), "0", "0" };
       handling->forceBoundary(ParserUBBFlagUID, west, ParserUBB_T::Parser(eqs));
       //! [forceBoundary_ParserUBB_eqs]
 
@@ -299,15 +299,15 @@ BoundaryHandling_T* MyBoundaryHandling::operator()(IBlock* const block,
       Cell offset(0, 0, 0);
       storage->transformBlockLocalToGlobalCell(offset, *block);
 
-      for (auto cellIt = east.begin(); cellIt != east.end(); ++cellIt)
+      for (auto cellIt : east)
       {
-         Cell globalCell = *cellIt + offset;
+         Cell globalCell = cellIt + offset;
          const real_t y = real_c(globalCell[1]);
 
          real_t local_density =
             setup_.outflowPressure * (real_t(1.0) + real_t(0.01) * std::sin(real_t(2.0 * 3.1415926538) * y / H));
 
-         handling->forceBoundary(PressureFlagUID, cellIt->x(), cellIt->y(), cellIt->z(),
+         handling->forceBoundary(PressureFlagUID, cellIt.x(), cellIt.y(), cellIt.z(),
                                  Pressure_T::LatticeDensity(local_density));
       }
       //! [forceBoundary_Pressure]
diff --git a/apps/tutorials/pde/01_SolvingPDE.cpp b/apps/tutorials/pde/01_SolvingPDE.cpp
index 0a058def9918537181fc9e79ec9de54a8b8bf91a..86c6e4057a5abb38c13ccf44bafa09b7d4c397dd 100644
--- a/apps/tutorials/pde/01_SolvingPDE.cpp
+++ b/apps/tutorials/pde/01_SolvingPDE.cpp
@@ -50,14 +50,14 @@ using Stencil_T = stencil::D2Q5;
 void initBC( const shared_ptr< StructuredBlockStorage > & blocks, const BlockDataID & srcID, const BlockDataID & dstID )
 {
    // iterate all blocks with an iterator 'block'
-   for( auto block = blocks->begin(); block != blocks->end(); ++block )
+   for( auto &block : *blocks )
    {
       // The Dirichlet boundary condition is non-zero only at the top boundary.
-      if( blocks->atDomainYMaxBorder( *block ) )
+      if( blocks->atDomainYMaxBorder( block ) )
       {
          // get the field data out of the blocks
-         auto src = block->getData< ScalarField >( srcID );
-         auto dst = block->getData< ScalarField >( dstID );
+         auto src = block.getData< ScalarField >( srcID );
+         auto dst = block.getData< ScalarField >( dstID );
 
          // obtain a CellInterval object that holds information about the number of cells in x,y,z direction of the field including ghost layers
          // Since src and dst have the same size, one object is enough.
@@ -67,14 +67,14 @@ void initBC( const shared_ptr< StructuredBlockStorage > & blocks, const BlockDat
          xyz.yMin() = xyz.yMax();
 
          // iterate all cells in the top boundary with the iterator 'cell'
-         for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+         for( auto cell : xyz )
          {
             // obtain the physical coordinate of the center of the current cell
-            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
+            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( block, cell );
 
             // set the values of the Dirichlet boundary condition given by the function u(x,1) = sin(2*PI*x)*sinh(2*PI) in the source and destination field
-            src->get( *cell ) = std::sin( real_c(2) * math::pi * p[0] ) * std::sinh( real_c(2) * math::pi );
-            dst->get( *cell ) = std::sin( real_c(2) * math::pi * p[0] ) * std::sinh( real_c(2) * math::pi );
+            src->get( cell ) = std::sin( real_c(2) * math::pi * p[0] ) * std::sinh( real_c(2) * math::pi );
+            dst->get( cell ) = std::sin( real_c(2) * math::pi * p[0] ) * std::sinh( real_c(2) * math::pi );
          }
       }
    }
@@ -86,22 +86,22 @@ void initBC( const shared_ptr< StructuredBlockStorage > & blocks, const BlockDat
 void initRHS( const shared_ptr< StructuredBlockStorage > & blocks, const BlockDataID & rhsID )
 {
    // iterate all blocks with an iterator 'block'
-   for( auto block = blocks->begin(); block != blocks->end(); ++block )
+   for( auto &block : *blocks )
    {
       // get the field data out of the block
-      auto f = block->getData< ScalarField >( rhsID );
+      auto f = block.getData< ScalarField >( rhsID );
 
       // obtain a CellInterval object that holds information about the number of cells in x,y,z direction of the field excluding ghost layers
       CellInterval xyz = f->xyzSize();
 
       // iterate all (inner) cells in the field
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for( auto cell : xyz )
       {
          // obtain the physical coordinate of the center of the current cell
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( block, cell );
 
          // set the right-hand side, given by the function f(x,y) = 4*PI*PI*sin(2*PI*x)*sinh(2*PI*y)
-         f->get( *cell ) = real_c(4) * math::pi * math::pi * std::sin( real_c(2) * math::pi * p[0] ) *
+         f->get( cell ) = real_c(4) * math::pi * math::pi * std::sin( real_c(2) * math::pi * p[0] ) *
                            std::sinh( real_c(2) * math::pi * p[1] );
       }
    }
diff --git a/apps/tutorials/pde/02_HeatEquation.cpp b/apps/tutorials/pde/02_HeatEquation.cpp
index 6c22dadb2250cb21192000650207ebdd03cc7bcc..55fa80b95d9643f5a3fd069145c31b945acf15e0 100644
--- a/apps/tutorials/pde/02_HeatEquation.cpp
+++ b/apps/tutorials/pde/02_HeatEquation.cpp
@@ -60,13 +60,13 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
       CellInterval xyz = u->xyzSize();
 
       // iterate all (inner) cells in the field
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell ){
+      for(auto cell : xyz){
 
          // obtain the physical coordinate of the center of the current cell
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
 
          // set the initial condition, given by the function u(x,y,0) = sin(PI*x)*sin(PI*y)
-         u->get( *cell ) = std::sin( math::pi * p[0] ) * std::sin( math::pi * p[1] );
+         u->get( cell ) = std::sin( math::pi * p[0] ) * std::sin( math::pi * p[1] );
       }
    }
 }
diff --git a/apps/tutorials/pde/03_HeatEquation_Extensions.cpp b/apps/tutorials/pde/03_HeatEquation_Extensions.cpp
index 8c7d79a05b50fcb25babd2a91dd5e5574d77f1ab..a7304d407973a4576d6125d0bf12f854fe3449b3 100644
--- a/apps/tutorials/pde/03_HeatEquation_Extensions.cpp
+++ b/apps/tutorials/pde/03_HeatEquation_Extensions.cpp
@@ -61,13 +61,13 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
       CellInterval xyz = u->xyzSize();
 
       // iterate all (inner) cells in the field
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell ){
+      for(auto cell : xyz){
 
          // obtain the physical coordinate of the center of the current cell
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
 
          // set the initial condition, given by the function u(x,y,0) = sin(PI*x)*sin(PI*y)
-         u->get( *cell ) = std::sin( math::pi * p[0] ) * std::sin( math::pi * p[1] );
+         u->get( cell ) = std::sin( math::pi * p[0] ) * std::sin( math::pi * p[1] );
       }
    }
 }
diff --git a/apps/tutorials/pe/02_ConfinedGasExtended.cpp b/apps/tutorials/pe/02_ConfinedGasExtended.cpp
index 4e08411755475040ba6bbf8ad2404f8cec568c18..5d6963b4320004e2b65b14b4d3f1285fcbdbc02a 100644
--- a/apps/tutorials/pe/02_ConfinedGasExtended.cpp
+++ b/apps/tutorials/pe/02_ConfinedGasExtended.cpp
@@ -157,20 +157,28 @@ int main( int argc, char ** argv )
    std::function<void(void)> syncCall;
    if (!syncShadowOwners)
    {
-      syncCall = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(*forest), storageID, &tt, real_c(0.0), false );
+      syncCall = [forest, storageID, ttree = &tt](){
+         pe::syncNextNeighbors< BodyTuple >(std::ref(*forest), storageID, ttree, real_c(0.0), false);
+      };
    } else
    {
-      syncCall = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(*forest), storageID, &tt, real_c(0.0), false );
+      syncCall = [forest, storageID, ttree = &tt](){
+         pe::syncShadowOwners<BodyTuple>(std::ref(*forest), storageID, ttree, real_c(0.0), false );
+      };
    }
 
    //! [Bind Sync Call]
    std::function<void(void)> syncCallWithoutTT;
    if (!syncShadowOwners)
    {
-      syncCallWithoutTT = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(nullptr), real_c(0.0), false );
+      syncCallWithoutTT = [forest, storageID](){
+         pe::syncNextNeighbors< BodyTuple >(std::ref(*forest), storageID, static_cast<WcTimingTree*>(nullptr), real_c(0.0), false);
+      };
    } else
    {
-      syncCallWithoutTT = std::bind( pe::syncShadowOwners<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(nullptr), real_c(0.0), false );
+      syncCallWithoutTT = [forest, storageID](){
+         pe::syncShadowOwners<BodyTuple>(std::ref(*forest), storageID, static_cast<WcTimingTree*>(nullptr), real_c(0.0), false );
+      };
    }
    //! [Bind Sync Call]
    
diff --git a/src/blockforest/AABBRefinementSelection.h b/src/blockforest/AABBRefinementSelection.h
index f92b062d52fea38c889356d80e7f2e66e3ddffa3..06910bc5052c781e6b72af0cb9c54c9822a35a70 100644
--- a/src/blockforest/AABBRefinementSelection.h
+++ b/src/blockforest/AABBRefinementSelection.h
@@ -52,20 +52,20 @@ public:
          {
             Config::Blocks aabbBlocks;
             refinementBlock.getBlocks( "AABB", aabbBlocks );
-            for( auto block = aabbBlocks.begin(); block != aabbBlocks.end(); ++block )
+            for(auto & aabbBlock : aabbBlocks)
             {
-               const math::AABB aabb  = block->getParameter< math::AABB >( "AABB" );
-               const uint_t     level = block->getParameter< uint_t >( "level" );
+               const math::AABB aabb  = aabbBlock.getParameter< math::AABB >( "AABB" );
+               const uint_t     level = aabbBlock.getParameter< uint_t >( "level" );
                addAABB( aabb, level );
             }
 
             // For regions, the simulation space is assumed to be [ <0,0,0>, <1,1,1> ]
             Config::Blocks regionBlocks;
             refinementBlock.getBlocks( "Region", regionBlocks );
-            for( auto block = regionBlocks.begin(); block != regionBlocks.end(); ++block )
+            for(auto & regionBlock : regionBlocks)
             {
-               const math::AABB region = block->getParameter< math::AABB >( "region" );
-               const uint_t     level  = block->getParameter< uint_t >( "level" );
+               const math::AABB region = regionBlock.getParameter< math::AABB >( "region" );
+               const uint_t     level  = regionBlock.getParameter< uint_t >( "level" );
                addRegion( region, level );
             }
          }
@@ -91,12 +91,12 @@ public:
       if( aabbs.empty() )
          return;
 
-      for( auto block = forest.begin(); block != forest.end(); ++block )
+      for(auto & block : forest)
       {
-         for( auto aabb = aabbs.begin(); aabb != aabbs.end(); ++aabb )
+         for(auto & aabb : aabbs)
          {
-            if( block->getAABB().intersects( aabb->first ) && block->getLevel() < aabb->second )
-               block->setMarker( true );
+            if( block.getAABB().intersects( aabb.first ) && block.getLevel() < aabb.second )
+               block.setMarker( true );
          }
       }
    }
@@ -108,16 +108,16 @@ public:
       std::vector< std::pair< math::AABB, uint_t > > aabbs = transformRegionsToAABBs( forest.getDomain() );
       aabbs.insert( aabbs.end(), aabbs_.begin(), aabbs_.end() );
 
-      for( auto it = minTargetLevels.begin(); it != minTargetLevels.end(); ++it )
+      for(auto & minTargetLevel : minTargetLevels)
       {
-         uint_t currentLevelOfBlock = it->first->getLevel();
+         const uint_t currentLevelOfBlock = minTargetLevel.first->getLevel();
          uint_t targetLevelOfBlock = currentLevelOfBlock;
 
-         for( auto aabb = aabbs.begin(); aabb != aabbs.end(); ++aabb )
+         for(auto & aabb : aabbs)
          {
-            if( it->first->getAABB().intersects( aabb->first ) )
+            if( minTargetLevel.first->getAABB().intersects( aabb.first ) )
             {
-               uint_t targetLevelOfAABB = aabb->second;
+               uint_t targetLevelOfAABB = aabb.second;
                if( currentLevelOfBlock > targetLevelOfAABB )
                {
                   targetLevelOfBlock = currentLevelOfBlock - uint_t(1);
@@ -132,7 +132,7 @@ public:
          }
 
          WALBERLA_CHECK_LESS_EQUAL(std::abs(int_c(targetLevelOfBlock) - int_c(currentLevelOfBlock)), uint_t(1), "Only level difference of maximum 1 allowed!");
-         it->second = targetLevelOfBlock;
+         minTargetLevel.second = targetLevelOfBlock;
       }
    }
 
@@ -142,14 +142,15 @@ private:
    std::vector< std::pair< math::AABB, uint_t > > transformRegionsToAABBs( const math::AABB & simulationDomain ) const
    {
       std::vector< std::pair< math::AABB, uint_t > > aabbs;
-      for( auto region = regions_.begin(); region != regions_.end(); ++region )
+      aabbs.reserve(regions_.size());
+      for(const auto & region : regions_)
       {
-         aabbs.emplace_back( math::AABB( simulationDomain.xMin() + region->first.xMin() * simulationDomain.xSize(),
-                                         simulationDomain.yMin() + region->first.yMin() * simulationDomain.ySize(),
-                                         simulationDomain.zMin() + region->first.zMin() * simulationDomain.zSize(),
-                                         simulationDomain.xMin() + region->first.xMax() * simulationDomain.xSize(),
-                                         simulationDomain.yMin() + region->first.yMax() * simulationDomain.ySize(),
-                                         simulationDomain.zMin() + region->first.zMax() * simulationDomain.zSize() ), region->second );
+         aabbs.emplace_back( math::AABB( simulationDomain.xMin() + region.first.xMin() * simulationDomain.xSize(),
+                                         simulationDomain.yMin() + region.first.yMin() * simulationDomain.ySize(),
+                                         simulationDomain.zMin() + region.first.zMin() * simulationDomain.zSize(),
+                                         simulationDomain.xMin() + region.first.xMax() * simulationDomain.xSize(),
+                                         simulationDomain.yMin() + region.first.yMax() * simulationDomain.ySize(),
+                                         simulationDomain.zMin() + region.first.zMax() * simulationDomain.zSize() ), region.second );
       }
       return aabbs;
    }
diff --git a/src/blockforest/Block.h b/src/blockforest/Block.h
index a61de6ac5c898c0ea1f8bb6a28f0a7b7f33fe002..b68c43addb72a3d185091d3be18cf5acb8db3fac 100644
--- a/src/blockforest/Block.h
+++ b/src/blockforest/Block.h
@@ -144,7 +144,7 @@ private:
    BlockID id_;
    uint_t  level_; // 0=coarse (= block is located on the initial grid) -> 1 -> 2 -> finer
 
-   std::vector< NeighborBlock* >  neighborhoodSection_[26]; // the 26 neighborhood sections
+   std::array< std::vector< NeighborBlock* >, 26 >  neighborhoodSection_; // the 26 neighborhood sections
    std::vector< NeighborBlock  >  neighborhood_;            // all neighbor blocks
 
    uint_t targetLevel_; // | level_ - targetLevel_ | <= 1
@@ -292,8 +292,8 @@ inline bool Block::neighborhoodSectionHasLargerBlock( const uint_t sectionIndex
 inline void Block::addNeighbor( const BlockID & id, const uint_t process, const Set<SUID> & state )
 {
 #ifndef NDEBUG
-   for( uint_t i = 0; i != neighborhood_.size(); ++i )
-      WALBERLA_ASSERT( neighborhood_[i].getId() < id || id < neighborhood_[i].getId() );
+   for(const auto & neighbor : neighborhood_)
+      WALBERLA_ASSERT( neighbor.getId() < id || id < neighbor.getId() );
 #endif
 
    neighborhood_.emplace_back( forest_, id, process, state );
diff --git a/src/blockforest/BlockForest.cpp b/src/blockforest/BlockForest.cpp
index 495da585dd97ab39679cebdd38e1267c1c44e018..654d7789db996e0a55a2c75127762ad86ea601ae 100644
--- a/src/blockforest/BlockForest.cpp
+++ b/src/blockforest/BlockForest.cpp
@@ -293,23 +293,23 @@ BlockForest::BlockForest( const uint_t process, const SetupBlockForest& forest,
 
       std::set< uint_t > neighbors;
 
-      for( uint_t i = 0; i != blocks.size(); ++i ) {
+      for(auto & block : blocks) {
 
-         WALBERLA_ASSERT( blocks_.find( blocks[i]->getId() ) == blocks_.end() );
+         WALBERLA_ASSERT( blocks_.find( block->getId() ) == blocks_.end() );
 
-         blocks_[ blocks[i]->getId() ] = std::make_shared< Block >( *this, blocks[i] );
+         blocks_[ block->getId() ] = std::make_shared< Block >( *this, block );
 
-         for( uint_t j = 0; j != blocks[i]->getNeighborhoodSize(); ++j )
-            if( blocks[i]->getNeighbor(j)->getProcess() != process )
-               neighbors.insert( blocks[i]->getNeighbor(j)->getProcess() );
+         for( uint_t j = 0; j != block->getNeighborhoodSize(); ++j )
+            if( block->getNeighbor(j)->getProcess() != process )
+               neighbors.insert( block->getNeighbor(j)->getProcess() );
       }
 
       if( insertBuffersIntoProcessNetwork_ && ( process + 1 ) < forest.getNumberOfProcesses() &&
           forest.isBufferProcess( process + 1 ) )
          neighbors.insert( process + 1 );
 
-      for( std::set< uint_t >::iterator it = neighbors.begin(); it != neighbors.end(); ++it )
-         neighborhood_.push_back( *it );
+      for(uint_t neighbor : neighbors)
+         neighborhood_.push_back( neighbor );
    }
    else if( insertBuffersIntoProcessNetwork_ )
    {
@@ -403,10 +403,10 @@ BlockForest::BlockForest( const uint_t process, const char* const filename, cons
 
    // domain AABB
 
-   real_t domain[6];
+   std::array< real_t, 6 > domain;
 
-   for( uint_t i = 0; i != 6; ++i ) {
-      domain[i] = byteArrayToReal< real_t >( buffer, offset );
+   for(real_t & dom : domain) {
+      dom = byteArrayToReal< real_t >( buffer, offset );
       offset += sizeof( real_t ) + 1 + 2;
    }
 
@@ -414,8 +414,8 @@ BlockForest::BlockForest( const uint_t process, const char* const filename, cons
 
    // number of coarse/root blocks in each direction
 
-   for( uint_t i = 0; i != 3; ++i ) {
-      size_[i] = byteArrayToUint( buffer, offset, 4 );
+   for(uint_t & s : size_) {
+      s = byteArrayToUint( buffer, offset, 4 );
       offset += 4;
    }
 
@@ -827,16 +827,16 @@ std::map< uint_t, std::vector< Vector3<real_t> > > BlockForest::getNeighboringPr
 {
    std::map< uint_t, std::vector< Vector3<real_t> > > offsets;
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+   for(const auto & it : blocks_)
    {
-      const auto & block = it->second;
+      const auto & block = it.second;
       const AABB & blockAABB = block->getAABB();
 
-      const real_t eps[] = { real_c( 1.0E-6 ) * ( blockAABB.xMax() - blockAABB.xMin() ),
+      const std::array< real_t, 3 > eps = { real_c( 1.0E-6 ) * ( blockAABB.xMax() - blockAABB.xMin() ),
                              real_c( 1.0E-6 ) * ( blockAABB.yMax() - blockAABB.yMin() ),
                              real_c( 1.0E-6 ) * ( blockAABB.zMax() - blockAABB.zMin() ) };
 
-      uint_t i[] = { uint_c(0), uint_c(0), uint_c(0) };
+      std::array< uint_t, 3 > i = { uint_c(0), uint_c(0), uint_c(0) };
 
       for( i[2] = 0; i[2] != 3; ++i[2] ) {
          for( i[1] = 0; i[1] != 3; ++i[1] ) {
@@ -848,13 +848,13 @@ std::map< uint_t, std::vector< Vector3<real_t> > > BlockForest::getNeighboringPr
                const auto sectionIndex = getBlockNeighborhoodSectionIndex( i[0], i[1], i[2] );
                const auto neighbors = block->getNeighborhoodSection( sectionIndex );
 
-               for( auto neighbor = neighbors.begin(); neighbor != neighbors.end(); ++neighbor )
+               for(auto neighbor : neighbors)
                {
-                  if( (*neighbor)->getProcess() == getProcess() )
+                  if( neighbor->getProcess() == getProcess() )
                      continue;
 
                   AABB aabb;
-                  getAABBFromBlockId( aabb, (*neighbor)->getId() );
+                  getAABBFromBlockId( aabb, neighbor->getId() );
 
                   Vector3< real_t > offset;
 
@@ -871,7 +871,7 @@ std::map< uint_t, std::vector< Vector3<real_t> > > BlockForest::getNeighboringPr
                              ( isPeriodic(j) && realIsEqual( std::fabs( offset[j] ), getDomain().max(j) - getDomain().min(j), eps[j] ) ) );
                   }
 
-                  const auto process = (*neighbor)->getProcess();
+                  const auto process = neighbor->getProcess();
                   auto & processOffsets = offsets[ process ];
 
                   bool newOffset = true;
@@ -1071,11 +1071,11 @@ void BlockForest::createSnapshot( const std::vector<uint_t> & sendTo, const std:
       buffer << block->first;
       block->second->toBuffer( buffer );
 
-      for( auto dataItem = blockDataItem_.begin(); dataItem != blockDataItem_.end(); ++dataItem )
+      for(auto & dataItem : blockDataItem_)
       {
-         auto blockDataHandlingWrapper = dataItem->getDataHandling( block->second.get() );
+         auto blockDataHandlingWrapper = dataItem.getDataHandling( block->second.get() );
          if( blockDataHandlingWrapper )
-            blockDataHandlingWrapper->serialize( block->second.get(), dataItem->getId(), buffer );
+            blockDataHandlingWrapper->serialize( block->second.get(), dataItem.getId(), buffer );
       }
    }
 
@@ -1169,19 +1169,19 @@ void BlockForest::restoreSnapshot( const SnapshotRestoreFunction & processMappin
 
    std::set< uint_t > neighborhood;
 
-   for( auto it = snapshot_.begin(); it != snapshot_.end(); ++it )
+   for(auto & it : snapshot_)
    {
-      if( processMapping( it->first ) == process_ )
+      if( processMapping( it.first ) == process_ )
       {
-         mpi::RecvBuffer & buffer = it->second;
+         mpi::RecvBuffer & buffer = it.second;
 
          std::vector< uint_t > pNeighborhood;
          buffer >> pNeighborhood;
 
-         for( auto n = pNeighborhood.begin(); n != pNeighborhood.end(); ++n )
+         for(uint_t & n : pNeighborhood)
          {
-            WALBERLA_ASSERT_LESS( processMapping(*n), uint_c( mpi::MPIManager::instance()->numProcesses() ) );
-            neighborhood.insert( processMapping(*n) );
+            WALBERLA_ASSERT_LESS( processMapping(n), uint_c( mpi::MPIManager::instance()->numProcesses() ) );
+            neighborhood.insert( processMapping(n) );
          }
 
          uint_t blocks( uint_t(0) );
@@ -1199,17 +1199,17 @@ void BlockForest::restoreSnapshot( const SnapshotRestoreFunction & processMappin
             blocks_[ id ] = std::make_shared< Block >( *this, id, aabb, level, buffer, processMapping );
 
             Block * block = blocks_[ id ].get();
-            for( auto dataItem = blockDataItem_.begin(); dataItem != blockDataItem_.end(); ++dataItem )
+            for(auto & dataItem : blockDataItem_)
             {
-               auto blockDataHandlingWrapper = dataItem->getDataHandling( block );
+               auto blockDataHandlingWrapper = dataItem.getDataHandling( block );
                if( blockDataHandlingWrapper )
                {
-                  addBlockData( block, dataItem->getId(), blockDataHandlingWrapper->deserialize( block ) );
-                  blockDataHandlingWrapper->deserialize( block, dataItem->getId(), buffer );
+                  addBlockData( block, dataItem.getId(), blockDataHandlingWrapper->deserialize( block ) );
+                  blockDataHandlingWrapper->deserialize( block, dataItem.getId(), buffer );
                }
                else
                {
-                  addBlockData( block, dataItem->getId(), nullptr );
+                  addBlockData( block, dataItem.getId(), nullptr );
                }
             }
          }
@@ -1218,8 +1218,8 @@ void BlockForest::restoreSnapshot( const SnapshotRestoreFunction & processMappin
 
    WALBERLA_LOG_PROGRESS( "BlockForest restore snapshot: restoring process neighborhood" );
 
-   for( auto n = neighborhood.begin(); n != neighborhood.end(); ++n )
-      neighborhood_.push_back( *n );
+   for(uint_t n : neighborhood)
+      neighborhood_.push_back( n );
 
    rebuildProcessesWithBlocksCommunicator();
 
@@ -1234,8 +1234,8 @@ void BlockForest::restoreSnapshot( const SnapshotRestoreFunction & processMappin
    if( ! callbackAfterBlockDataIsUnpacked_.empty() )
       WALBERLA_LOG_PROGRESS( "BlockForest restore snapshot: executing call back functions after data was restored" );
 
-   for( auto f = callbackAfterBlockDataIsRestored_.begin(); f != callbackAfterBlockDataIsRestored_.end(); ++f )
-      f->second();
+   for(auto & f : callbackAfterBlockDataIsRestored_)
+      f.second();
 
    WALBERLA_MPI_SECTION()
    {
@@ -1281,8 +1281,8 @@ void BlockForest::restoreSnapshot( const SnapshotRestoreFunction & processMappin
             for( auto phantom = phantomBlocks.begin(); phantom != phantomBlocks.end() && !performUpdate; ++phantom )
             {
                const auto & sourceProcess = phantom->second->getSourceProcess();
-               for( auto it = sourceProcess.begin(); it != sourceProcess.end(); ++it )
-                  performUpdate = ( *it != process_ );
+               for(uint_t sourceProces : sourceProcess)
+                  performUpdate = ( sourceProces != process_ );
             }
             mpi::allReduceInplace( performUpdate, mpi::LOGICAL_OR );
          }
@@ -1308,8 +1308,8 @@ void BlockForest::restoreSnapshot( const SnapshotRestoreFunction & processMappin
 void BlockForest::saveToFile( const std::string & filename, FileIOMode fileIOMode ) const
 {
    Set<SUID> suids;
-   for( auto block = blocks_.begin(); block != blocks_.end(); ++block )
-      suids += block->second->getState();
+   for(const auto & block : blocks_)
+      suids += block.second->getState();
 
    std::vector<SUID> localSuids( suids.begin(), suids.end() );
    std::vector<SUID> allSuids = mpi::allReduceSet( localSuids, mpi::UNION );
@@ -1332,11 +1332,11 @@ void BlockForest::saveToFile( const std::string & filename, const Set<SUID> & bl
    std::map< SUID, std::vector< bool > > suidMap;
 
    uint_t i = 0;
-   for( Set<SUID>::const_iterator it = blockStates.begin(); it != blockStates.end(); ++it ) {
+   for(auto blockState : blockStates) {
 
       std::vector< bool > suidBoolVec( 8 * suidBytes );
       suidBoolVec[i] = true;
-      suidMap[ *it ] = suidBoolVec;
+      suidMap[ blockState ] = suidBoolVec;
       ++i;
    }
 
@@ -1388,9 +1388,8 @@ void BlockForest::constructBlockInformation( const SetupBlockForest & forest )
    blockInformation_->nodes_.resize( forest.getNumberOfTrees() );
    auto & nodeForest = blockInformation_->nodes_;
 
-   for( uint_t i = 0; i != blocks.size(); ++i )
+   for(auto block : blocks)
    {
-      const SetupBlock * const block = blocks[i];
       BlockID id( block->getId() );
 
       std::stack< uint_t > index;
@@ -1493,9 +1492,10 @@ void BlockForest::constructBlockInformation( const std::vector< BlockID > & ids,
 void BlockForest::constructBlockInformation()
 {
    std::vector< std::pair< BlockID, std::pair< uint_t, Set<SUID> > > > data;
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+   data.reserve(blocks_.size());
+   for(auto & block : blocks_)
    {
-      data.emplace_back( it->first, std::make_pair( process_, it->second->getState() ) );
+      data.emplace_back( block.first, std::make_pair( process_, block.second->getState() ) );
    }
 
    mpi::SendBuffer sBuffer;
@@ -1513,10 +1513,10 @@ void BlockForest::constructBlockInformation()
    for( int r = 0; r != MPIManager::instance()->numProcesses(); ++r )
    {
       rBuffer >> data;
-      for( auto it = data.begin(); it != data.end(); ++it )
+      for(auto & it : data)
       {
-         ids.push_back( it->first );
-         nodes.push_back( make_shared< BlockInformation::Node >( it->second.first, it->second.second ) );
+         ids.push_back( it.first );
+         nodes.push_back( make_shared< BlockInformation::Node >( it.second.first, it.second.second ) );
       }
       data.clear();
    }
@@ -1586,9 +1586,9 @@ bool BlockForest::determineBlockTargetLevels( bool & additionalRefreshCycleRequi
 
    auto it0 = minTargetLevelsCallback.begin();
    auto it1 = blocksAlreadyMarkedForRefinement.begin();
-   for( auto it = mapping.begin(); it != mapping.end(); ++it )
+   for( int m : mapping )
    {
-      if( *it == 0 )
+      if( m == 0 )
       {
          WALBERLA_CHECK( it0 != minTargetLevelsCallback.end() );
          minTargetLevelsAllBlocks.push_back( *it0 );
@@ -1596,7 +1596,7 @@ bool BlockForest::determineBlockTargetLevels( bool & additionalRefreshCycleRequi
       }
       else
       {
-         WALBERLA_ASSERT_EQUAL( *it, 1 );
+         WALBERLA_ASSERT_EQUAL( m, 1 );
          WALBERLA_CHECK( it1 != blocksAlreadyMarkedForRefinement.end() );
          WALBERLA_CHECK_NOT_NULLPTR( *it1 );
          WALBERLA_CHECK_EQUAL( (*it1)->getTargetLevel(), (*it1)->getLevel() + uint_t(1) );
@@ -1877,10 +1877,10 @@ bool BlockForest::determineBlockTargetLevels( bool & additionalRefreshCycleRequi
 
       WALBERLA_LOG_PROGRESS( "BlockForest refresh:   + tell neighbors about blocks that can get merged" );
 
-      for( auto rank = ranksToRecvFrom.begin(); rank != ranksToRecvFrom.end(); ++rank )
+      for( auto rank: ranksToRecvFrom )
       {
-         WALBERLA_ASSERT_UNEQUAL( *rank, process_ );
-         mergeBufferSystem.sendBuffer( *rank ) << intentToMerge[ process_ ];
+         WALBERLA_ASSERT_UNEQUAL( rank, process_ );
+         mergeBufferSystem.sendBuffer( rank ) << intentToMerge[ process_ ];
       }
 
       mergeBufferSystem.sendAll();
@@ -1900,9 +1900,8 @@ bool BlockForest::determineBlockTargetLevels( bool & additionalRefreshCycleRequi
          WALBERLA_ASSERT( intentToMerge.find( process_ ) != intentToMerge.end() );
 
          const std::set< BlockID > & blocksToCheck = intentToMerge[ process_ ];
-         for( auto it = blocksToCheck.begin(); it != blocksToCheck.end(); ++it )
+         for(const auto & id : blocksToCheck)
          {
-            const BlockID & id = *it;
             WALBERLA_ASSERT( octetMember.find(id) != octetMember.end() );
             const std::map< BlockID, uint_t > & octetMembers = octetMember[id];
             WALBERLA_ASSERT( octetMembers.size() == uint_t(7) );
@@ -2029,8 +2028,8 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
    if( ! callbackBeforeBlockDataIsPacked_.empty() )
       WALBERLA_LOG_PROGRESS( "BlockForest refresh: - executing call back functions before block data is packed" );
 
-   for( auto f = callbackBeforeBlockDataIsPacked_.begin(); f != callbackBeforeBlockDataIsPacked_.end(); ++f )
-      f->second( *this, phantomForest );
+   for(auto & f : callbackBeforeBlockDataIsPacked_)
+      f.second( *this, phantomForest );
 
    //////////////////////////////////////
    // SCHEDULE RECV's FOR BUFFER SIZES //
@@ -2039,21 +2038,21 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
    std::map< uint_t, uint_t > numberOfBlocksToRecv; // does not include local transfers
 
    const auto & phantomBlocks = phantomForest.getBlockMap();
-   for( auto phantom = phantomBlocks.begin(); phantom != phantomBlocks.end(); ++phantom )
+   for(const auto & phantomBlock : phantomBlocks)
    {
-      auto & pBlock = phantom->second;
+      auto & pBlock = phantomBlock.second;
       auto & sourceProcesses = pBlock->getSourceProcess();
       if( pBlock->getSourceLevel() != pBlock->getLevel() || sourceProcesses[0] != process_ )
       {
          WALBERLA_ASSERT( blocks_.find( pBlock->getId() ) == blocks_.end() );
-         for( auto p = sourceProcesses.begin(); p != sourceProcesses.end(); ++p )
+         for(uint_t sourceProcesse : sourceProcesses)
          {
-            if( *p != process_ )
+            if( sourceProcesse != process_ )
             {
-               if( numberOfBlocksToRecv.find( *p ) == numberOfBlocksToRecv.end() )
-                  numberOfBlocksToRecv[*p] = uint_t(1);
+               if( numberOfBlocksToRecv.find( sourceProcesse ) == numberOfBlocksToRecv.end() )
+                  numberOfBlocksToRecv[sourceProcesse] = uint_t(1);
                else
-                  ++(numberOfBlocksToRecv[*p]);
+                  ++(numberOfBlocksToRecv[sourceProcesse]);
             }
          }
       }
@@ -2075,10 +2074,10 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
    WALBERLA_LOG_PROGRESS( "BlockForest refresh: - schedule receives for buffer sizes" );
 
    uint_t i( uint_t(0) );
-   for( auto it = recvBufferSizes.begin(); it != recvBufferSizes.end(); ++it )
+   for(auto & recvBufferSize : recvBufferSizes)
    {
-      MPI_Irecv( static_cast< void * >( &(it->second[0]) ), int_c( it->second.size() ), MPITrait< uint_t >::type(),
-                 int_c( it->first ), 0, MPIManager::instance()->comm(), &(recvBufferSizesRequests[i]) );
+      MPI_Irecv( static_cast< void * >( &(recvBufferSize.second[0]) ), int_c( recvBufferSize.second.size() ), MPITrait< uint_t >::type(),
+                 int_c( recvBufferSize.first ), 0, MPIManager::instance()->comm(), &(recvBufferSizesRequests[i]) );
       ++i;
    }
 
@@ -2090,16 +2089,16 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
    std::set< mpi::MPIRank > ranksToRecvFrom;
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+   for(auto & it : blocks_)
    {
-      auto & block = it->second;
+      auto & block = it.second;
       auto & targetProcesses = block->getTargetProcess();
       if( block->getTargetLevel() != block->getLevel() || targetProcesses[0] != process_ )
       {
          WALBERLA_ASSERT( targetProcesses.size() == uint_t(1) || targetProcesses.size() == uint_t(8) );
-         for( auto p = targetProcesses.begin(); p != targetProcesses.end(); ++p )
-            if( *p != process_ )
-               ranksToRecvFrom.insert( numeric_cast< mpi::MPIRank >(*p) );
+         for(uint_t targetProcesse : targetProcesses)
+            if( targetProcesse != process_ )
+               ranksToRecvFrom.insert( numeric_cast< mpi::MPIRank >(targetProcesse) );
       }
    }
 
@@ -2108,21 +2107,21 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
    std::map< uint_t, std::map< BlockID, Set<SUID> > > blockStates;
 
-   for( auto phantom = phantomBlocks.begin(); phantom != phantomBlocks.end(); ++phantom )
+   for(const auto & phantomBlock : phantomBlocks)
    {
-      auto & pBlock = phantom->second;
+      auto & pBlock = phantomBlock.second;
       auto & sourceProcesses = pBlock->getSourceProcess();
       if( pBlock->getSourceLevel() != pBlock->getLevel() || sourceProcesses[0] != process_ )
       {
-         for( auto p = sourceProcesses.begin(); p != sourceProcesses.end(); ++p )
-            blockStates[ *p ][ pBlock->getId() ] = pBlock->getState();
+         for(const uint_t sourceProcesse : sourceProcesses)
+            blockStates[ sourceProcesse ][ pBlock->getId() ] = pBlock->getState();
       }
    }
 
-   for( auto it = blockStates.begin(); it != blockStates.end(); ++it )
+   for(auto & blockState : blockStates)
    {
-      if( it->first != process_ )
-         bufferSystem.sendBuffer( numeric_cast< mpi::MPIRank >( it->first ) ) << it->second;
+      if( blockState.first != process_ )
+         bufferSystem.sendBuffer( numeric_cast< mpi::MPIRank >( blockState.first ) ) << blockState.second;
    }
 
    bufferSystem.sendAll();
@@ -2158,9 +2157,9 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
    std::vector< std::pair< Block *, std::vector< mpi::SendBuffer > > > blocksToPack; // includes data that is NOT transfered via MPI but copied locally
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+   for(auto & it : blocks_)
    {
-      auto & block = it->second;
+      auto & block = it.second;
       auto & targetProcesses = block->getTargetProcess();
       if( block->getTargetLevel() != block->getLevel() || targetProcesses[0] != process_ )
       {
@@ -2249,8 +2248,8 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
       // sender block "state"
 
-      for( auto buffer = buffers.begin(); buffer != buffers.end(); ++buffer )
-         *buffer << block->getState();
+      for(auto & buffer : buffers)
+         buffer << block->getState();
 
       // block data
 
@@ -2260,11 +2259,11 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
          WALBERLA_ASSERT_EQUAL( targetProcesses.size(), uint_t(1) );
          WALBERLA_ASSERT_EQUAL( targetState.size(), uint_t(1) );
 
-         for( auto dataItem = blockDataItem_.begin(); dataItem != blockDataItem_.end(); ++dataItem )
+         for(auto & dataItem : blockDataItem_)
          {
-            auto blockDataHandlingWrapper = dataItem->getDataHandling( block, targetState[0] );
+            auto blockDataHandlingWrapper = dataItem.getDataHandling( block, targetState[0] );
             if( blockDataHandlingWrapper )
-               blockDataHandlingWrapper->serialize( block, dataItem->getId(), buffers[0] );
+               blockDataHandlingWrapper->serialize( block, dataItem.getId(), buffers[0] );
          }
       }
       else if( block->targetBlockIsLarger() )
@@ -2329,8 +2328,8 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
    WALBERLA_LOG_PROGRESS( "BlockForest refresh: - deleting blocks that are split, merged, and/or transfered" );
 
-   for( auto block = blocksToPack.begin(); block != blocksToPack.end(); ++block )
-      blocks_.erase( block->first->getId() );
+   for(auto & block : blocksToPack)
+      blocks_.erase( block.first->getId() );
 
    ///////////////
    // SEND DATA //
@@ -2347,8 +2346,8 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
       auto & sizes = sendBufferSizes[ it->first ];
       WALBERLA_ASSERT( sizes.empty() );
-      for( auto buffer = it->second.begin(); buffer != it->second.end(); ++buffer )
-         sizes.push_back( (*buffer)->size() );
+      for(auto & buffer : it->second)
+         sizes.push_back( buffer->size() );
 
       blockDataSendRequests[ it->first ].resize( it->second.size() ); // do not resize this vector after this point!
    }
@@ -2385,9 +2384,9 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
    WALBERLA_LOG_PROGRESS( "BlockForest refresh: - allocating new blocks" );
 
-   for( auto phantom = phantomBlocks.begin(); phantom != phantomBlocks.end(); ++phantom )
+   for(const auto & pbIt : phantomBlocks)
    {
-      auto & pBlock = phantom->second;
+      auto & pBlock = pbIt.second;
       if( pBlock->getSourceLevel() != pBlock->getLevel() || pBlock->getSourceProcess()[0] != process_ )
       {
          WALBERLA_ASSERT( blocks_.find( pBlock->getId() ) == blocks_.end() );
@@ -2469,8 +2468,8 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
    WALBERLA_LOG_PROGRESS( "BlockForest refresh: - perform local data transfer" );
 
-   for( auto buffer = localBlocks.begin(); buffer != localBlocks.end(); ++buffer )
-      recvLocalBlocks.emplace_back( **buffer );
+   for(auto & localBlock : localBlocks)
+      recvLocalBlocks.emplace_back( *localBlock );
 
    ////////////////////////////////////
    // WAIT FOR RECV's FOR BLOCK DATA //
@@ -2478,9 +2477,9 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
    WALBERLA_LOG_PROGRESS( "BlockForest refresh: - wait for block data to be received" );
 
-   for( auto it = blockDataRecvRequests.begin(); it != blockDataRecvRequests.end(); ++it )
+   for(auto & blockDataRecvRequest : blockDataRecvRequests)
    {
-      auto & requests = it->second;
+      auto & requests = blockDataRecvRequest.second;
       MPI_Waitall( int_c( requests.size() ), &(requests[0]), MPI_STATUSES_IGNORE );
    }
 
@@ -2493,9 +2492,9 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
    if( ! sendBufferSizesRequests.empty() )
       MPI_Waitall( int_c( sendBufferSizesRequests.size() ), &(sendBufferSizesRequests[0]), MPI_STATUSES_IGNORE );
 
-   for( auto it = blockDataSendRequests.begin(); it != blockDataSendRequests.end(); ++it )
+   for(auto & blockDataSendRequest : blockDataSendRequests)
    {
-      auto & requests = it->second;
+      auto & requests = blockDataSendRequest.second;
       MPI_Waitall( int_c( requests.size() ), &(requests[0]), MPI_STATUSES_IGNORE );
    }
 
@@ -2505,11 +2504,11 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
    WALBERLA_LOG_PROGRESS( "BlockForest refresh: - clear send buffers (= free memory)" );
 
-   for( auto it = blocksToPack.begin(); it != blocksToPack.end(); ++it )
+   for(auto & it : blocksToPack)
    {
-      auto & buffers = it->second;
-      for( auto buffer = buffers.begin(); buffer != buffers.end(); ++buffer )
-         buffer->reset();
+      auto & buffers = it.second;
+      for(auto & buffer : buffers)
+         buffer.reset();
    }
 
    ////////////////////////////////
@@ -2520,17 +2519,17 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
 
    std::map< Block *, std::vector< std::pair< Set<SUID>, mpi::RecvBuffer * > > > blocksToUnpack; // includes data that is NOT transfered via MPI but copied locally
 
-   for( auto it = recvBlockData.begin(); it != recvBlockData.end(); ++it )
+   for(auto & it : recvBlockData)
    {
-      auto & buffers = it->second;
-      for( auto buffer = buffers.begin(); buffer != buffers.end(); ++buffer )
+      auto & buffers = it.second;
+      for(auto & buffer : buffers)
       {
          // header = sender block ID + receiver block ID & sender block "state"
 
          BlockID sId;
          BlockID rId;
          Set<SUID> state;
-         (*buffer) >> sId >> rId >> state;
+         buffer >> sId >> rId >> state;
 
          WALBERLA_ASSERT( blocks_.find( rId ) != blocks_.end() );
          WALBERLA_ASSERT( phantomBlocks.find( rId ) != phantomBlocks.end() );
@@ -2540,7 +2539,7 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
          if( phantom->sourceBlockHasTheSameSize() || phantom->sourceBlockIsLarger() )
          {
             WALBERLA_ASSERT( blocksToUnpack.find( block ) == blocksToUnpack.end() );
-            blocksToUnpack[ block ].emplace_back( state, &(*buffer) );
+            blocksToUnpack[ block ].emplace_back( state, &buffer );
          }
          else
          {
@@ -2548,7 +2547,7 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
             if( bufferPtrs.empty() )
                bufferPtrs.resize( uint_t(8), std::make_pair( Set<SUID>::emptySet(), static_cast< mpi::RecvBuffer * >(nullptr) ) );
             WALBERLA_ASSERT_EQUAL( sId.getUsedBits(), rId.getUsedBits() + uint_t(3) );
-            bufferPtrs[ sId.getBranchId() ] = std::make_pair( state, &(*buffer) );
+            bufferPtrs[ sId.getBranchId() ] = std::make_pair( state, &buffer );
          }
       }
    }
@@ -2589,8 +2588,8 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
    if( ! callbackBeforeBlockDataIsUnpacked_.empty() )
       WALBERLA_LOG_PROGRESS( "BlockForest refresh: - executing call back functions before block data is unpacked" );
 
-   for( auto f = callbackBeforeBlockDataIsUnpacked_.begin(); f != callbackBeforeBlockDataIsUnpacked_.end(); ++f )
-      f->second( *this, phantomForest );
+   for(auto & f : callbackBeforeBlockDataIsUnpacked_)
+      f.second( *this, phantomForest );
 
    /////////////////
    // UNPACK DATA //
@@ -2599,9 +2598,10 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
    WALBERLA_LOG_PROGRESS( "BlockForest refresh: - unpacking block data from buffers" );
 
    std::vector< std::pair< Block *, std::vector< std::pair< Set<SUID>, mpi::RecvBuffer * > > > > dataToUnpack;
+   dataToUnpack.reserve(blocksToUnpack.size());
 
-   for( auto it = blocksToUnpack.begin(); it != blocksToUnpack.end(); ++it )
-      dataToUnpack.emplace_back( it->first, it->second );
+   for(auto & it : blocksToUnpack)
+      dataToUnpack.emplace_back( it.first, it.second );
 
    //#ifdef _OPENMP
    //#pragma omp parallel for schedule(dynamic)
@@ -2620,23 +2620,23 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
       {
          WALBERLA_ASSERT_EQUAL( buffers.size(), uint_t(1) );
 
-         for( auto dataItem = blockDataItem_.begin(); dataItem != blockDataItem_.end(); ++dataItem )
+         for(auto & dataItem : blockDataItem_)
          {
             // allocate
             {
-               auto blockDataHandlingWrapper = dataItem->getDataHandling( block );
+               auto blockDataHandlingWrapper = dataItem.getDataHandling( block );
                if( blockDataHandlingWrapper )
-                  addBlockData( block, dataItem->getId(), blockDataHandlingWrapper->deserialize( block ) );
+                  addBlockData( block, dataItem.getId(), blockDataHandlingWrapper->deserialize( block ) );
                else
-                  addBlockData( block, dataItem->getId(), nullptr );
+                  addBlockData( block, dataItem.getId(), nullptr );
             }
             // fill with sent data
             {
-               auto blockDataHandlingWrapper = dataItem->getDataHandling( block, buffers[0].first );
+               auto blockDataHandlingWrapper = dataItem.getDataHandling( block, buffers[0].first );
                if( blockDataHandlingWrapper )
                {
                   WALBERLA_ASSERT_NOT_NULLPTR( buffers[0].second );
-                  blockDataHandlingWrapper->deserialize( block, dataItem->getId(), *(buffers[0].second) );
+                  blockDataHandlingWrapper->deserialize( block, dataItem.getId(), *(buffers[0].second) );
                }
             }
          }
@@ -2738,8 +2738,8 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
          }
       }
 
-      for( auto it = buffers.begin(); it != buffers.end(); ++it )
-         it->second->reset();
+      for(auto & buffer : buffers)
+         buffer.second->reset();
    }
 
    //////////////
@@ -2749,8 +2749,8 @@ void BlockForest::update( PhantomBlockForest & phantomForest )
    if( ! callbackAfterBlockDataIsUnpacked_.empty() )
       WALBERLA_LOG_PROGRESS( "BlockForest refresh: - executing call back functions after block data was unpacked" );
 
-   for( auto f = callbackAfterBlockDataIsUnpacked_.begin(); f != callbackAfterBlockDataIsUnpacked_.end(); ++f )
-      f->second( *this, phantomForest );
+   for(auto & f : callbackAfterBlockDataIsUnpacked_)
+      f.second( *this, phantomForest );
 }
 
 
@@ -2769,8 +2769,8 @@ void BlockForest::saveToFile( const std::string & filename, FileIOMode fileIOMod
    {
       dataSize += internal::FILE_HEADER_SIZE; // header
       ++dataSize; // number of SUIDs
-      for( auto suid = suidMap.begin(); suid != suidMap.end(); ++suid )
-         dataSize += uint_t(1) + uint_c( suid->first.getIdentifier().length() );
+      for(const auto & suid : suidMap)
+         dataSize += uint_t(1) + uint_c( suid.first.getIdentifier().length() );
    }
 
    std::vector< uint8_t > processDataBuffer( dataSize );
@@ -2785,13 +2785,13 @@ void BlockForest::saveToFile( const std::string & filename, FileIOMode fileIOMod
 
       std::vector< SUID > suids( suidMap.size() );
 
-      for( auto suid = suidMap.begin(); suid != suidMap.end(); ++suid )
+      for(const auto & suid : suidMap)
       {
          for( uint_t i = uint_t(0); i != suids.size(); ++i )
          {
-            if( suid->second[i] )
+            if( suid.second[i] )
             {
-               suids[i] = suid->first;
+               suids[i] = suid.first;
                break;
             }
          }
@@ -2802,11 +2802,11 @@ void BlockForest::saveToFile( const std::string & filename, FileIOMode fileIOMod
 
       // for every SUID ...
 
-      for( auto it = suids.begin(); it != suids.end(); ++it )
+      for(auto & suid : suids)
       {
          // length of its identifier string
 
-         const uint_t length = it->getIdentifier().length();
+         const uint_t length = suid.getIdentifier().length();
          WALBERLA_CHECK_LESS( length, 256, "SUID identifiers are allowed to consist of 255 characters at most when saving the block structure to file!" );
 
          uintToByteArray( length, processDataBuffer, offset, 1 );
@@ -2814,7 +2814,7 @@ void BlockForest::saveToFile( const std::string & filename, FileIOMode fileIOMod
 
          // the identifier string
 
-         const char * str = it->getIdentifier().c_str();
+         const char * str = suid.getIdentifier().c_str();
          for( uint_t j = 0; j != length; ++j )
             processDataBuffer[offset+j] = *reinterpret_cast< const uint8_t* >( str + j );
          offset += length;
@@ -2837,14 +2837,14 @@ void BlockForest::saveToFile( const std::string & filename, FileIOMode fileIOMod
          std::vector< bool > suidBoolVec( 8 * suidBytes );
 
          const Set<SUID> & state = block->second->getState();
-         for( auto suid = state.begin(); suid != state.end(); ++suid )
+         for(auto suid : state)
          {
-            WALBERLA_CHECK( suidMap.find( *suid ) != suidMap.end(), "Block state SUID missing from SUID list saved to file."
-                                                                    "\n- SUID = " << *suid << "\n- block ID = " << block->first <<
+            WALBERLA_CHECK( suidMap.find( suid ) != suidMap.end(), "Block state SUID missing from SUID list saved to file."
+                                                                    "\n- SUID = " << suid << "\n- block ID = " << block->first <<
                                                                     "\n- block AABB = " << block->second->getAABB() );
             //Elementwise OR of all elements
             for (uint_t i = 0; i < suidBoolVec.size(); ++i) {
-               suidBoolVec[i] = suidBoolVec[i] || suidMap.find( *suid )->second[i];
+               suidBoolVec[i] = suidBoolVec[i] || suidMap.find( suid )->second[i];
             }
          }
 
@@ -2857,9 +2857,9 @@ void BlockForest::saveToFile( const std::string & filename, FileIOMode fileIOMod
    uintToByteArray( uint_c( neighborhood_.size() ), processDataBuffer, offset, uint_t(2) );
    offset += uint_t(2);
 
-   for( auto neighbor = neighborhood_.begin(); neighbor != neighborhood_.end(); ++neighbor )
+   for(uint_t neighbor : neighborhood_)
    {
-      uintToByteArray( *neighbor, processDataBuffer, offset, processIdBytes_ );
+      uintToByteArray( neighbor, processDataBuffer, offset, processIdBytes_ );
       offset += processIdBytes_;
    }
 
@@ -3005,8 +3005,8 @@ void BlockForest::storeFileHeader( std::vector< uint8_t > & data, uint_t & offse
 
    // number of coarse/root blocks in each direction
 
-   for( uint_t i = 0; i != 3; ++i ) {
-      uintToByteArray( size_[i], data, offset, 4 );
+   for(uint_t s : size_) {
+      uintToByteArray( s, data, offset, 4 );
       offset += 4;
    }
 
@@ -3054,9 +3054,7 @@ void BlockForest::checkBlockInformationConsistency( const SetupBlockForest& fore
    std::vector< const SetupBlock* > blocks;
    forest.getBlocks( blocks );
 
-   for( uint_t i = 0; i != blocks.size(); ++i ) {
-      const SetupBlock* const block = blocks[i];
-
+   for(auto block : blocks) {
       uint_t process = 0;
       WALBERLA_ASSERT( getBlockInformation().getProcess( process, block->getId() ) );
       WALBERLA_ASSERT_EQUAL( process, block->getProcess() );
diff --git a/src/blockforest/BlockForest.h b/src/blockforest/BlockForest.h
index c000ecff5f8fd484857b06ebda0bed7be79e4907..c271916ea4fa67cdfea727099f8d2bff2ad1206b 100644
--- a/src/blockforest/BlockForest.h
+++ b/src/blockforest/BlockForest.h
@@ -344,7 +344,7 @@ public:
 
 
    
-   internal::BlockDataHandlingAdder addBlockData( const std::string & identifier = std::string() ) { return internal::BlockDataHandlingAdder( *this, identifier ); }
+   internal::BlockDataHandlingAdder addBlockData( const std::string & identifier = std::string() ) { return { *this, identifier }; }
 
    template< typename T >
    inline BlockDataID addBlockData( const shared_ptr< T > & dataHandling,
@@ -387,7 +387,7 @@ public:
    void refresh();
 
    /// Functor that calls refresh with given frequency
-   RefreshFunctor getRefreshFunctor( const uint_t checkFrequency = uint_t(1) ) { return RefreshFunctor( *this, checkFrequency ); }
+   RefreshFunctor getRefreshFunctor( const uint_t checkFrequency = uint_t(1) ) { return { *this, checkFrequency }; }
    
    /// Modification stamp is changed when refresh moves a block or refines/coarsens at least one block
    /// however, stamp may (in rare cases) also change if block structure was not altered
@@ -470,7 +470,7 @@ public:
    void restoreSnapshot( const SnapshotRestoreFunction & processMapping, const bool rebelance = true );
 
    SnapshotCreationFunctor getSnapshotCreationFunctor( const SnapshotCreationFunction & function,
-                                                       const uint_t checkFrequency = uint_t(1) ) { return SnapshotCreationFunctor( *this, function, checkFrequency ); }
+                                                       const uint_t checkFrequency = uint_t(1) ) { return { *this, function, checkFrequency }; }
 
    inline uint_t    addCallbackFunctionAfterBlockDataIsRestored( const SnapshotRestoreCallbackFunction & f );
    inline void   removeCallbackFunctionAfterBlockDataIsRestored( const uint_t handle );
@@ -508,7 +508,7 @@ private:
    uint_t process_;
    uint_t processIdBytes_;
 
-   uint_t size_[3];     // number of coarse blocks on the initial grid (= number of octree root blocks) in each direction
+   std::array< uint_t, 3 > size_;     // number of coarse blocks on the initial grid (= number of octree root blocks) in each direction
    uint_t depth_;       // depth := number of levels - 1
    uint_t treeIdDigits_;
 
@@ -578,8 +578,8 @@ inline uint_t BlockForest::getNumberOfBlocks( const uint_t level ) const {
 
    uint_t numberOfBlocks = 0;
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
-      if( it->second->getLevel() == level ) ++numberOfBlocks;
+   for(const auto & bIt : blocks_)
+      if(bIt.second->getLevel() == level ) ++numberOfBlocks;
 
    return numberOfBlocks;
 }
@@ -588,48 +588,48 @@ inline uint_t BlockForest::getNumberOfBlocks( const uint_t level ) const {
 
 inline void BlockForest::getBlocks( std::vector< const Block* >& blocks, const uint_t level ) const {
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
-      if( it->second->getLevel() == level ) blocks.push_back( it->second.get() );
+   for(const auto & bIt : blocks_)
+      if(bIt.second->getLevel() == level ) blocks.push_back(bIt.second.get() );
 }
 
 
 
 inline void BlockForest::getBlocks( std::vector< Block* >& blocks, const uint_t level ) {
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
-      if( it->second->getLevel() == level ) blocks.push_back( it->second.get() );
+   for(auto & bIt : blocks_)
+      if(bIt.second->getLevel() == level ) blocks.push_back(bIt.second.get() );
 }
 
 
 
 inline void BlockForest::getBlocksContainedWithinAABB( std::vector< const IBlock* >& blocks, const AABB& aabb ) const {
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
-      if( aabb.contains( it->second->getAABB() ) ) blocks.push_back( it->second.get() );
+   for(const auto & bIt : blocks_)
+      if( aabb.contains(bIt.second->getAABB() ) ) blocks.push_back(bIt.second.get() );
 }
 
 
 
 inline void BlockForest::getBlocksContainedWithinAABB( std::vector< IBlock* >& blocks, const AABB& aabb ) {
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
-      if( aabb.contains( it->second->getAABB() ) ) blocks.push_back( it->second.get() );
+   for(auto & bIt : blocks_)
+      if( aabb.contains(bIt.second->getAABB() ) ) blocks.push_back(bIt.second.get() );
 }
 
 
 
 inline void BlockForest::getBlocksOverlappedByAABB( std::vector< const IBlock* >& blocks, const AABB& aabb ) const {
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
-      if( it->second->getAABB().intersects( aabb ) ) blocks.push_back( it->second.get() );
+   for(const auto & bIt : blocks_)
+      if( bIt.second->getAABB().intersects(aabb ) ) blocks.push_back(bIt.second.get() );
 }
 
 
 
 inline void BlockForest::getBlocksOverlappedByAABB( std::vector< IBlock* >& blocks, const AABB& aabb ) {
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
-      if( it->second->getAABB().intersects( aabb ) ) blocks.push_back( it->second.get() );
+   for(auto & bIt : blocks_)
+      if( bIt.second->getAABB().intersects(aabb ) ) blocks.push_back(bIt.second.get() );
 }
 
 
@@ -664,8 +664,8 @@ inline Block* BlockForest::getBlock( const IBlockID& id ) {
 
 inline const Block* BlockForest::getBlock( const real_t x, const real_t y, const real_t z ) const {
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
-      if( it->second->getAABB().contains(x,y,z) ) return it->second.get();
+   for(const auto & bIt : blocks_)
+      if( bIt.second->getAABB().contains(x, y, z) ) return bIt.second.get();
 
    return nullptr;
 }
@@ -674,8 +674,8 @@ inline const Block* BlockForest::getBlock( const real_t x, const real_t y, const
 
 inline Block* BlockForest::getBlock( const real_t x, const real_t y, const real_t z ) {
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
-      if( it->second->getAABB().contains(x,y,z) ) return it->second.get();
+   for(auto & bIt : blocks_)
+      if( bIt.second->getAABB().contains(x, y, z) ) return bIt.second.get();
 
    return nullptr;
 }
@@ -976,8 +976,8 @@ public:
                     std::vector< const Block * > & blocksAlreadyMarkedForRefinement,
                     const blockforest::BlockForest & forest )
    {
-      for( auto function = functions_.begin(); function != functions_.end(); ++function )
-         (*function)( minTargetLevels, blocksAlreadyMarkedForRefinement, forest );
+      for(auto & function : functions_)
+         function( minTargetLevels, blocksAlreadyMarkedForRefinement, forest );
    }
 
 private:
diff --git a/src/blockforest/BlockForestEvaluation.cpp b/src/blockforest/BlockForestEvaluation.cpp
index d587ef264fdc2f2ec84107fed85d41aa789da683..84474e604ae225d4019c448b5ec0a1ad6ab6ae2c 100644
--- a/src/blockforest/BlockForestEvaluation.cpp
+++ b/src/blockforest/BlockForestEvaluation.cpp
@@ -123,8 +123,8 @@ void BlockForestEvaluation::toStream( std::ostream & os ) const
       if( !blockData.empty() )
       {
          os << "\n- block data:";
-         for( auto data = blockData.begin(); data != blockData.end(); ++data )
-            os << "\n   + " << *data;
+         for(auto & data : blockData)
+            os << "\n   + " << data;
       }
 
       os << "\n- number of already performed restructure cycles: " << forest_.getModificationStamp()
diff --git a/src/blockforest/BlockID.h b/src/blockforest/BlockID.h
index e62d8ff09d05de25810b4364ecba6aff9824ee06..46968dfa4fef7e3072a283e3eb09e8910efcc094 100644
--- a/src/blockforest/BlockID.h
+++ b/src/blockforest/BlockID.h
@@ -276,7 +276,7 @@ public:
    uint_t getTreeId()    const { return id_; }
    uint_t getTreeIndex() const { return id_ - uintPow2( getUsedBits() - 1 ); }
 
-   BlockID getSuperId()  const { WALBERLA_ASSERT_GREATER_EQUAL( getUsedBits(), uint_c(4) ); return BlockID( id_ >> 3 ); }
+   BlockID getSuperId()  const { WALBERLA_ASSERT_GREATER_EQUAL( getUsedBits(), uint_c(4) ); return { id_ >> 3 }; }
    BlockID getFatherId() const { return getSuperId(); }
 
    void   appendBranchId( const uint_t branchId ) { WALBERLA_ASSERT_LESS_EQUAL( getUsedBits() + 3, math::UINT_BITS ); WALBERLA_ASSERT_LESS( branchId, 8 ); id_ = (id_ << 3) + branchId; }
diff --git a/src/blockforest/BlockReconstruction.h b/src/blockforest/BlockReconstruction.h
index c41689b94ea3e717486676452257d020579fe59a..6d1d977d134c3c33bac95ea12160b0ce62295d34 100644
--- a/src/blockforest/BlockReconstruction.h
+++ b/src/blockforest/BlockReconstruction.h
@@ -134,7 +134,7 @@ void BlockReconstruction::reconstructNeighborhood( BLOCK* block, const std::vect
    std::vector< real_t >                                      neighborhoodSectionBlockCenters;
    std::set< const NeighborhoodReconstructionBlock* >         neighborhood;
    std::map< const NeighborhoodReconstructionBlock*, uint_t > neighborhoodIndex;
-   std::vector< uint_t >                                      neighborhoodSectionBlocks[26];
+   std::array< std::vector< uint_t >, 26 >                    neighborhoodSectionBlocks;
 
    block->clearNeighborhood();
 
@@ -158,20 +158,20 @@ void BlockReconstruction::reconstructNeighborhood( BLOCK* block, const std::vect
          if( z <  domain.zMin() && zPeriodic ) z = domain.zMax() - domain.zMin() + z;
          if( z >= domain.zMax() && zPeriodic ) z = domain.zMin() - domain.zMax() + z;
 
-         for( uint_t i = 0; i != neighbors.size(); ++i ) {
-            if( neighbors[i].getAABB().contains( x, y, z ) ) {
+         for(const auto & neighbor : neighbors) {
+            if( neighbor.getAABB().contains(x, y, z ) ) {
 
-               const NeighborhoodReconstructionBlock* neighbor = &(neighbors[i]);
+               const NeighborhoodReconstructionBlock* neighborPtr = &neighbor;
                uint_t index = 0;
 
-               if( neighborhood.insert( neighbor ).second ) {
+               if( neighborhood.insert(neighborPtr ).second ) {
 
                   index = block->getNeighborhoodSize();
-                  neighborhoodIndex[ neighbor ] = index;
+                  neighborhoodIndex[ neighborPtr ] = index;
 
-                  block->addNeighbor( neighbor->getId(), neighbor->getProcess(), neighbor->getState() );
+                  block->addNeighbor(neighborPtr->getId(), neighborPtr->getProcess(), neighborPtr->getState() );
                }
-               else index = neighborhoodIndex[ neighbor ];
+               else index = neighborhoodIndex[ neighborPtr ];
 
                if( neighborhoodSectionBlocks[n].empty() || neighborhoodSectionBlocks[n].back() != index )
                   neighborhoodSectionBlocks[n].push_back( index );
@@ -274,8 +274,8 @@ void BlockReconstruction::reconstructNeighborhoodSections( BLOCK* block, const A
 
       block->clearNeighborhoodSection(n);
 
-      for( uint_t i = 0; i != neighborhoodSectionBlocks.size(); ++i )
-         block->addNeighbor( n, neighborhoodSectionBlocks[i] );
+      for(uint_t & neighborhoodSectionBlock : neighborhoodSectionBlocks)
+         block->addNeighbor( n, neighborhoodSectionBlock );
 
       neighborhoodSectionBlocks.clear();
       neighborhoodSectionBlockCenters.clear();
diff --git a/src/blockforest/GlobalLoadBalancing.h b/src/blockforest/GlobalLoadBalancing.h
index ca1509453d683bf2457c1d91a0c6a1b9f465fb75..4b04d436417fea309475ce20f2d55254e10ad508 100644
--- a/src/blockforest/GlobalLoadBalancing.h
+++ b/src/blockforest/GlobalLoadBalancing.h
@@ -386,8 +386,8 @@ uint_t GlobalLoadBalancing::balanceSorted( const std::vector< BLOCK* >& blocks,
          minWorkload = std::max( minWorkload, sortedBlocks[l][i]->getWorkload() );
          WALBERLA_ASSERT_LESS_EQUAL( sortedBlocks[l][i]->getMemory(), memoryLimit );
       }
-      for( uint_t i = 0; i != processesWork.size(); ++i )
-         minWorkload = std::max( minWorkload, processesWork[i] );
+      for(workload_t i : processesWork)
+         minWorkload = std::max( minWorkload, i );
 
       // check min - potentially nothing more to do
 
@@ -696,9 +696,7 @@ void GlobalLoadBalancing::reorderProcessesByBFS( std::vector< BLOCK* > & blocks,
 
          reorderMap[p] = process++;
 
-         for( uint_t i = 0; i != processNeighbors[p].size(); ++i ) {
-            const uint_t neighbor = processNeighbors[p][i];
-
+         for(uint_t neighbor : processNeighbors[p]) {
             if( !processed[neighbor] ) {
                processList.push_back( neighbor );
                processed[neighbor] = true;
@@ -723,12 +721,12 @@ void GlobalLoadBalancing::reorderProcessesByBFS( std::vector< BLOCK* > & blocks,
    }
 #endif
 
-   const int blockssize = int_c( blocks.size() );
+   const uint_t blockssize = blocks.size();
 #ifdef _OPENMP
    #pragma omp parallel for schedule(static)
 #endif
-   for( int i = 0; i < blockssize; ++i )
-      blocks[ uint_c(i) ]->assignTargetProcess( reorderMap[ blocks[ uint_c(i) ]->getTargetProcess() ] );
+   for( uint_t i = 0; i < blockssize; ++i )
+      blocks[ i ]->assignTargetProcess( reorderMap[ blocks[ i ]->getTargetProcess() ] );
 }
 
 
@@ -815,7 +813,7 @@ uint_t GlobalLoadBalancing::metis( const std::vector< BLOCK* >& blocks, const me
    std::vector< int64_t > part( uint_c(nvtxs) );
 
    real_t maxUbvec = metisConfig.maxUbvec();
-   real_t ubvec[]  = { real_c(1.01), maxUbvec };
+   std::array< real_t, 2 > ubvec  = { real_c(1.01), maxUbvec };
 
    // first call to METIS: always try to balance the workload as good as possible, but allow large imbalances concerning the memory (-> ubvec[1])
 
@@ -992,14 +990,14 @@ void GlobalLoadBalancing::metis2( const std::vector< BLOCK* >& blocks, const uin
    
    std::vector< int64_t > part( uint_c(nvtxs) );
    
-   int64_t options[ METIS_NOPTIONS ];
-   core::METIS_SetDefaultOptions( options );
-   options[ core::METIS_OPTION_NITER ] = 1000;
-   options[ core::METIS_OPTION_NSEPS ] = 100;
-   options[ core::METIS_OPTION_NCUTS ] = 100;
-   
+   std::array< int64_t, METIS_NOPTIONS > options;
+   core::METIS_SetDefaultOptions( options.data() );
+   options[ size_t(core::METIS_OPTION_NITER) ] = 1000;
+   options[ size_t(core::METIS_OPTION_NSEPS) ] = 100;
+   options[ size_t(core::METIS_OPTION_NCUTS) ] = 100;
+
    int ret = core::METIS_PartGraphKway( &nvtxs, &ncon, &( xadj[ 0 ] ), &( adjncy[ 0 ] ), &( vwgt[ 0 ] ), nullptr, &( adjwgt[0] ),
-                                  &nparts, nullptr, nullptr, options, &objval, &( part[ 0 ] ) );
+                                  &nparts, nullptr, nullptr, options.data(), &objval, &( part[ 0 ] ) );
 
    if( ret != core::METIS_OK ) 
    {
@@ -1055,10 +1053,10 @@ std::string GlobalLoadBalancing::metisErrorCodeToString( int errorCode )
 uint_t GlobalLoadBalancing::metisAdaptPartVector( std::vector< int64_t >& part, const uint_t numberOfProcesses )
 {
    std::vector<bool> hasBlock( numberOfProcesses, false );
-   for( uint_t i = 0; i != part.size(); ++i )
+   for( auto proc: part )
    {
-      WALBERLA_ASSERT_LESS( part[i], int_c( numberOfProcesses ) );
-      hasBlock[ uint_c(part[i]) ] = true;
+      WALBERLA_ASSERT_LESS( proc, int_c( numberOfProcesses ) );
+      hasBlock[ uint_c(proc) ] = true;
    }
 
    uint_t nProcesses = 0;
@@ -1066,8 +1064,8 @@ uint_t GlobalLoadBalancing::metisAdaptPartVector( std::vector< int64_t >& part,
    {
       if( !hasBlock[ uint_c(i) ] )
       {
-         for( uint_t j = 0; j != part.size(); ++j )
-            if( part[j] > i ) --part[j];
+         for(int64_t & j : part)
+            if( j > i ) --j;
       }
       else
          ++nProcesses;
diff --git a/src/blockforest/HilbertCurveConstruction.h b/src/blockforest/HilbertCurveConstruction.h
index fc9fa01daa61f970df7643c5fa837e9251f6e8ba..41218de0c0c5b167db990f2bdc86c31547700028 100644
--- a/src/blockforest/HilbertCurveConstruction.h
+++ b/src/blockforest/HilbertCurveConstruction.h
@@ -30,7 +30,7 @@ namespace blockforest {
 
 
 // see: "Dynamic Octree Load Balancing Using Space-Filling Curves", Campbell, Devine, Gervasio, Teresco, 2003
-static const uint_t hilbertOrder[24][8] = { { 0, 1, 3, 2, 6, 7, 5, 4 },
+static const std::array< std::array< uint_t , 8 >, 24 > hilbertOrder { { { 0, 1, 3, 2, 6, 7, 5, 4 },
                                             { 0, 4, 6, 2, 3, 7, 5, 1 },
                                             { 0, 1, 5, 4, 6, 7, 3, 2 },
                                             { 5, 1, 0, 4, 6, 2, 3, 7 },
@@ -53,9 +53,9 @@ static const uint_t hilbertOrder[24][8] = { { 0, 1, 3, 2, 6, 7, 5, 4 },
                                             { 5, 7, 6, 4, 0, 2, 3, 1 },
                                             { 3, 2, 6, 7, 5, 4, 0, 1 },
                                             { 3, 1, 0, 2, 6, 4, 5, 7 },
-                                            { 3, 1, 5, 7, 6, 4, 0, 2 } };
+                                            { 3, 1, 5, 7, 6, 4, 0, 2 } } };
 
-static const uint_t hilbertOrientation[24][8] = { {  1,  2,  0,  3,  4,  0,  5,  6 },
+static const std::array< std::array< uint_t , 8 >, 24 > hilbertOrientation { { {  1,  2,  0,  3,  4,  0,  5,  6 },
                                                   {  0,  7,  1,  8,  5,  1,  4,  9 },
                                                   { 15,  0,  2, 22, 20,  2, 19, 23 },
                                                   { 20,  6,  3, 23, 15,  3, 16, 22 },
@@ -78,7 +78,7 @@ static const uint_t hilbertOrientation[24][8] = { {  1,  2,  0,  3,  4,  0,  5,
                                                   {  3, 12, 20, 13, 16, 20, 15,  4 },
                                                   { 23, 18, 21, 10, 14, 21,  9, 15 },
                                                   {  4, 23, 22,  6,  1, 22, 11,  3 },
-                                                  { 21, 22, 23,  0,  9, 23, 14,  2 } };
+                                                  { 21, 22, 23,  0,  9, 23, 14,  2 } } };
 
 
 
diff --git a/src/blockforest/Initialization.cpp b/src/blockforest/Initialization.cpp
index d800a75b10a112edba39a6655c84bfad53cb1426..bd57fd21a13c2da47250878aa667a02ebcfcf3fc 100644
--- a/src/blockforest/Initialization.cpp
+++ b/src/blockforest/Initialization.cpp
@@ -63,7 +63,7 @@ shared_ptr< StructuredBlockForest > createUniformBlockGridFromConfig( const shar
       }
    }
    WALBERLA_ABORT_NO_DEBUG_INFO( "No Configuration specified" );
-   return shared_ptr<StructuredBlockForest>();
+   return {};
 }
 
 
@@ -270,10 +270,10 @@ public:
    FixedRefinementLevelSelector( const uint_t level ) : level_(level) {}
    void operator()( SetupBlockForest& forest )
    {
-      for( auto block = forest.begin(); block != forest.end(); ++block )
+      for(auto & block : forest)
       {
-         if( block->getLevel() < level_ )
-            block->setMarker( true );
+         if( block.getLevel() < level_ )
+            block.setMarker( true );
       }
    }
 private:
@@ -346,7 +346,7 @@ shared_ptr<BlockForest> createBlockForest(const math::AABB& simulationDomain,
          WALBERLA_LOG_INFO_ON_ROOT( "SetupBlockForest successfully saved to file!" );
       }
 
-      return shared_ptr<BlockForest>();
+      return {};
    }
 
    WALBERLA_MPI_SECTION()
@@ -631,11 +631,10 @@ createUniformBlockGrid( const AABB& domainAABB,
    const memory_t memoryLimit = ( maxBlocksPerProcess == 0 ) ? numeric_cast< memory_t >( sforest.getNumberOfBlocks() ) :
                                                                numeric_cast< memory_t >( maxBlocksPerProcess );
 
-   GlobalLoadBalancing::MetisConfiguration< SetupBlock > metisConfig( includeMetis, forceMetis,
-                                                                      std::bind( cellWeightedCommunicationCost, std::placeholders::_1, std::placeholders::_2,
-                                                                                   numberOfXCellsPerBlock,
-                                                                                   numberOfYCellsPerBlock,
-                                                                                   numberOfZCellsPerBlock ) );
+   auto commFunc = [=](const SetupBlock* const a, const SetupBlock* const b) {
+       return cellWeightedCommunicationCost(a, b, numberOfXCellsPerBlock, numberOfYCellsPerBlock, numberOfZCellsPerBlock);
+   };
+   GlobalLoadBalancing::MetisConfiguration< SetupBlock > metisConfig( includeMetis, forceMetis, commFunc );
 
    sforest.calculateProcessDistribution_Default( uint_c( MPIManager::instance()->numProcesses() ), memoryLimit, "hilbert", 10, false, metisConfig );
 
@@ -796,9 +795,9 @@ void uniformWorkloadAndMemoryAssignment( SetupBlockForest& forest ) {
    std::vector< SetupBlock* > blocks;
    forest.getBlocks( blocks );
 
-   for( uint_t i = 0; i != blocks.size(); ++i ) {
-      blocks[i]->setWorkload( numeric_cast< workload_t >(1) );
-      blocks[i]->setMemory( numeric_cast< memory_t >(1) );
+   for(auto & block : blocks) {
+      block->setWorkload( numeric_cast< workload_t >(1) );
+      block->setMemory( numeric_cast< memory_t >(1) );
    }
 }
 
@@ -850,11 +849,11 @@ memory_t cellWeightedCommunicationCost( const SetupBlock* const a, const SetupBl
 
 memory_t uniformFacesDominantCommunication( const SetupBlock* const a, const SetupBlock* const b ) {
 
-   uint_t faces[] = { 4, 10, 12, 13, 15, 21 };
+   std::array< uint_t, 6 > faces = { 4, 10, 12, 13, 15, 21 };
 
-   for( uint_t i = 0; i != 6; ++i ) {
-      for( uint_t j = 0; j != a->getNeighborhoodSectionSize(faces[i]); ++j )
-         if( a->getNeighbor(faces[i],j) == b )
+   for(uint_t face : faces) {
+      for( uint_t j = 0; j != a->getNeighborhoodSectionSize(face); ++j )
+         if( a->getNeighbor(face,j) == b )
             return numeric_cast< memory_t >(1000);
    }
 
diff --git a/src/blockforest/PhantomBlock.h b/src/blockforest/PhantomBlock.h
index 3872a72610f8ac4d72e095d48573d2c5f069b005..5cf6577fb666fad3446646947e831c1c6c3eddc7 100644
--- a/src/blockforest/PhantomBlock.h
+++ b/src/blockforest/PhantomBlock.h
@@ -150,7 +150,7 @@ private:
    // set by the user/application via callback
    walberla::any data_;
 
-   std::vector< NeighborBlock* > neighborhoodSection_[26]; // the 26 neighborhood sections (can be restored from 'neighborhood_')
+   std::array< std::vector< NeighborBlock* >, 26 > neighborhoodSection_; // the 26 neighborhood sections (can be restored from 'neighborhood_')
    std::vector< NeighborBlock  > neighborhood_;            // all neighbor blocks
 
    uint_t sourceLevel_; // | sourceLevel_ - level_ | == 1
@@ -300,8 +300,8 @@ inline bool PhantomBlock::neighborhoodSectionHasLargerBlock( const uint_t sectio
 inline void PhantomBlock::addNeighbor( const BlockID & id, const uint_t process, const Set<SUID> & state )
 {
 #ifndef NDEBUG
-   for( uint_t i = 0; i != neighborhood_.size(); ++i )
-      WALBERLA_ASSERT( neighborhood_[i].getId() < id || id < neighborhood_[i].getId() );
+   for(const auto & i : neighborhood_)
+      WALBERLA_ASSERT( i.getId() < id || id < i.getId() );
 #endif
 
    neighborhood_.emplace_back( phantomForest_, id, process, state );
diff --git a/src/blockforest/PhantomBlockForest.cpp b/src/blockforest/PhantomBlockForest.cpp
index fe7f8e1d3c09cbdc2b799f3bda07e09b8bbd4539..7594cf9d237626dccfd01c8413b9955f1beb9f18 100644
--- a/src/blockforest/PhantomBlockForest.cpp
+++ b/src/blockforest/PhantomBlockForest.cpp
@@ -134,13 +134,13 @@ void PhantomBlockForest::initialize( const BlockStateDeterminationFunction & fun
 
             std::vector< uint_t > sourceProcesses( uint_t(8), process );
             const auto & neighborhood = block->getNeighborhood();
-            for( auto neighbor = neighborhood.begin(); neighbor != neighborhood.end(); ++neighbor )
+            for(const auto & neighbor : neighborhood)
             {
-               auto & nid = neighbor->getId();
+               auto & nid = neighbor.getId();
                if( blockforest_.getLevelFromBlockId( nid ) == level && nid.getFatherId() == fid )
                {
-                  sourceProcesses[ neighbor->getId().getBranchId() ] = neighbor->getProcess();
-                  sourceStates[ neighbor->getId().getBranchId() ] = std::make_pair( nid, neighbor->getState() );
+                  sourceProcesses[ neighbor.getId().getBranchId() ] = neighbor.getProcess();
+                  sourceStates[ neighbor.getId().getBranchId() ] = std::make_pair( nid, neighbor.getState() );
                }
             }
 
@@ -158,13 +158,13 @@ void PhantomBlockForest::initialize( const BlockStateDeterminationFunction & fun
          else
          {
             const auto & neighborhood = block->getNeighborhood();
-            for( auto neighbor = neighborhood.begin(); neighbor != neighborhood.end(); ++neighbor )
+            for(const auto & neighbor : neighborhood)
             {
-               const auto & nid = neighbor->getId();
+               const auto & nid = neighbor.getId();
                if( blockforest_.getLevelFromBlockId( nid ) == level && nid.getFatherId() == fid && nid.getBranchId() == uint_t(0) )
                {
                   WALBERLA_ASSERT_EQUAL( block->getTargetProcess().size(), uint_t(0) );
-                  block->addTargetProcess( neighbor->getProcess() );
+                  block->addTargetProcess( neighbor.getProcess() );
 #ifdef NDEBUG
                   break;
 #endif
@@ -175,9 +175,9 @@ void PhantomBlockForest::initialize( const BlockStateDeterminationFunction & fun
       }
 
       const auto & neighborhood = block->getNeighborhood();
-      for( auto neighbor = neighborhood.begin(); neighbor != neighborhood.end(); ++neighbor )
-         if( neighbor->getProcess() != process )
-            ranksToRecvFrom.insert( numeric_cast< mpi::MPIRank >( neighbor->getProcess() ) );
+      for(const auto & neighbor : neighborhood)
+         if( neighbor.getProcess() != process )
+            ranksToRecvFrom.insert( numeric_cast< mpi::MPIRank >( neighbor.getProcess() ) );
 
       if( recalculateDepth )
          depth_ = std::max( depth_, targetLevel );
@@ -198,12 +198,12 @@ void PhantomBlockForest::initialize( const BlockStateDeterminationFunction & fun
    mpi::BufferSystem bufferSystem( MPIManager::instance()->comm(), 1941 ); // phantomblockforest = 112 104 97 110 116 111 109 98 108 111 99 107 102 111 114 101 115 116
    bufferSystem.setReceiverInfo( ranksToRecvFrom, true ); // ATTENTION: true = the size of a message from A to B varies
 
-   for( int i = 0; i != 2; ++i )
+   for( uint_t i = 0; i != 2; ++i )
    {
-      for( auto rank = ranksToRecvFrom.begin(); rank != ranksToRecvFrom.end(); ++rank )
+      for(mpi::MPIRank rank : ranksToRecvFrom)
       {
-         WALBERLA_ASSERT_UNEQUAL( uint_c(*rank), process );
-         bufferSystem.sendBuffer( *rank ) << blockNeighborhood[ process ];
+         WALBERLA_ASSERT_UNEQUAL( uint_c(rank), process );
+         bufferSystem.sendBuffer( rank ) << blockNeighborhood[ process ];
       }
 
       bufferSystem.sendAll();
@@ -217,12 +217,12 @@ void PhantomBlockForest::initialize( const BlockStateDeterminationFunction & fun
       }
 
       std::map< BlockID, std::pair< uint_t, Set<SUID> > > & localMap = blockNeighborhood[ process ];
-      for( auto it = blockNeighborhood.begin(); it != blockNeighborhood.end(); ++it )
+      for(auto & it : blockNeighborhood)
       {
-         if( it->first != process )
+         if( it.first != process )
          {
             // localMap.insert( it->second.begin(), it->second.end() ); // using 'insert' doesn't allow to assert consistency ... -> manual for loop
-            for( auto blockProcessPair = it->second.begin(); blockProcessPair != it->second.end(); ++blockProcessPair )
+            for( auto blockProcessPair = it.second.begin(); blockProcessPair != it.second.end(); ++blockProcessPair )
             {
 #ifndef NDEBUG
                if( localMap.find( blockProcessPair->first ) != localMap.end() )
@@ -230,7 +230,7 @@ void PhantomBlockForest::initialize( const BlockStateDeterminationFunction & fun
 #endif
                localMap[ blockProcessPair->first ] = blockProcessPair->second;
             }
-            it->second.clear();
+            it.second.clear();
          }
       }
    }
@@ -238,16 +238,17 @@ void PhantomBlockForest::initialize( const BlockStateDeterminationFunction & fun
    std::vector< BlockReconstruction::NeighborhoodReconstructionBlock > neighbors;
 
    std::map< BlockID, std::pair< uint_t, Set<SUID> > > & localMap = blockNeighborhood[ process ];
-   for( auto it = localMap.begin(); it != localMap.end(); ++it )
-      neighbors.emplace_back( it->first, it->second.first, it->second.second, aabbReconstruction );
+   neighbors.reserve(localMap.size());
+   for(auto & it : localMap)
+      neighbors.emplace_back( it.first, it.second.first, it.second.second, aabbReconstruction );
 
    BlockReconstruction::NeighborhoodReconstruction< PhantomBlock > neighborhoodReconstruction( blockforest_.getDomain(),
                                                                                                blockforest_.isXPeriodic(),
                                                                                                blockforest_.isYPeriodic(),
                                                                                                blockforest_.isZPeriodic() );
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it ) // TODO: can be done in parallel with OpenMP
-      neighborhoodReconstruction( it->second.get(), neighbors );
+   for(auto & block : blocks_) // TODO: can be done in parallel with OpenMP
+      neighborhoodReconstruction( block.second.get(), neighbors );
 
    updateNeighborhood();
 }
@@ -260,9 +261,9 @@ void PhantomBlockForest::assignBlockData( const PhantomBlockDataAssignmentFuncti
    {
       std::vector< std::pair< const PhantomBlock *, walberla::any > > blockData;
    
-      for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+      for(auto & it : blocks_)
       {
-         auto & block = it->second;
+         auto & block = it.second;
          WALBERLA_ASSERT_NOT_NULLPTR( block.get() );
          blockData.emplace_back( block.get(), walberla::any() );
       }
@@ -294,9 +295,9 @@ bool PhantomBlockForest::calculateMigrationInformation( const MigrationPreparati
    {
       std::vector< std::pair< const PhantomBlock *, uint_t > > targetProcess;
    
-      for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+      for(auto & it : blocks_)
       {
-         auto & block = it->second;
+         auto & block = it.second;
          WALBERLA_ASSERT_NOT_NULLPTR( block.get() );
          targetProcess.emplace_back( block.get(), block->getTargetProcess() );
       }
@@ -304,8 +305,9 @@ bool PhantomBlockForest::calculateMigrationInformation( const MigrationPreparati
       bool runAgain = function( targetProcess, processesToRecvFrom_, *this, iteration );
 
       WALBERLA_CHECK_EQUAL( targetProcess.size(), blocks_.size() );
-      for( auto it = processesToRecvFrom_.begin(); it != processesToRecvFrom_.end(); ++it )
-         WALBERLA_CHECK_LESS( *it, uint_c( MPIManager::instance()->numProcesses() ) );
+
+      for( auto rank: processesToRecvFrom_ )
+         WALBERLA_CHECK_LESS( rank, uint_c( MPIManager::instance()->numProcesses() ) );
       
       auto bit = blocks_.begin();
       for( auto it = targetProcess.begin(); it != targetProcess.end(); ++it )
@@ -344,18 +346,18 @@ void PhantomBlockForest::migrate( const PhantomBlockDataPackFunction & packBlock
 
    std::map< uint_t, std::vector< PhantomBlock * > > blocksToSend;
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+   for(auto & it : blocks_)
    {
-      auto & block = it->second;
+      auto & block = it.second;
       WALBERLA_ASSERT_NOT_NULLPTR( block.get() );
       if( block->getTargetProcess() != process )
          blocksToSend[ block->getTargetProcess() ].push_back( block.get() );
    }
 
    std::set< mpi::MPIRank > ranksToRecvFrom;
-   for( auto p = processesToRecvFrom_.begin(); p != processesToRecvFrom_.end(); ++p )
-      if( *p != process )
-         ranksToRecvFrom.insert( static_cast< mpi::MPIRank >(*p) );
+   for(uint_t p : processesToRecvFrom_)
+      if( p != process )
+         ranksToRecvFrom.insert( static_cast< mpi::MPIRank >(p) );
 
    // TODO: use OpenMP buffer system?
    mpi::BufferSystem bufferSystem( MPIManager::instance()->comm(), 1944 ); // phantomblockforest = 112 104 97 110 116 111 109 98 108 111 99 107 102 111 114 101 115 116 + 3
@@ -373,9 +375,8 @@ void PhantomBlockForest::migrate( const PhantomBlockDataPackFunction & packBlock
       // TODO: Is the data amount reduction really necessary? Is it even a good idea?!
 
       buffer << uint_c( blocks.size() );
-      for( auto block = blocks.begin(); block != blocks.end(); ++block )
+      for(auto pBlock : blocks)
       {
-         auto * pBlock = *block;
          WALBERLA_ASSERT_NOT_NULLPTR( pBlock );
 
          buffer << pBlock->getId() << pBlock->getState();
@@ -516,8 +517,8 @@ void PhantomBlockForest::updateNeighborhood()
    if( blockforest_.insertBuffersIntoProcessNetwork() )
    {
       std::map< mpi::MPIRank, mpi::MPISize > ranksToRecvFrom;
-      for( auto n = neighborhood_.begin(); n != neighborhood_.end(); ++n )
-         ranksToRecvFrom[ static_cast< mpi::MPIRank >(*n) ] = mpi::BufferSizeTrait<int>::size;
+      for(uint_t & n : neighborhood_)
+         ranksToRecvFrom[ static_cast< mpi::MPIRank >(n) ] = mpi::BufferSizeTrait<int>::size;
 
       mpi::BufferSystem bufferSystem( MPIManager::instance()->comm(), 1942 ); // phantomblockforest = 112 104 97 110 116 111 109 98 108 111 99 107 102 111 114 101 115 116 + 1
       bufferSystem.setReceiverInfo( ranksToRecvFrom );
@@ -546,19 +547,19 @@ void PhantomBlockForest::updateNeighborhood()
    }
 
    const uint_t process = blockforest_.getProcess();
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+   for(auto & it : blocks_)
    {
-      auto & block = it->second;
+      auto & block = it.second;
       WALBERLA_ASSERT_NOT_NULLPTR( block.get() );
       const auto & neighborhood = block->getNeighborhood();
-      for( auto n = neighborhood.begin(); n != neighborhood.end(); ++n )
-         if( n->getProcess() != process )
-            neighbors.insert( n->getProcess() );
+      for(const auto & n : neighborhood)
+         if( n.getProcess() != process )
+            neighbors.insert( n.getProcess() );
    }
 
    neighborhood_.clear();
-   for( auto n = neighbors.begin(); n != neighbors.end(); ++n )
-      neighborhood_.push_back( *n );
+   for(uint_t neighbor : neighbors)
+      neighborhood_.push_back( neighbor );
 }
 
 
@@ -575,13 +576,13 @@ void PhantomBlockForest::prepareMigration()
 
    const uint_t process = blockforest_.getProcess();
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+   for(auto & block : blocks_)
    {
-      blockProcessMap[ process ][ it->first ] = it->second->getTargetProcess();
-      auto & neighbors = it->second->getNeighborhood();
-      for( auto n = neighbors.begin(); n != neighbors.end(); ++n )
-         if( n->getProcess() != process )
-            ranksToRecvFrom.insert( numeric_cast< mpi::MPIRank >( n->getProcess() ) );
+      blockProcessMap[ process ][ block.first ] = block.second->getTargetProcess();
+      auto & neighbors = block.second->getNeighborhood();
+      for(const auto & neighbor : neighbors)
+         if( neighbor.getProcess() != process )
+            ranksToRecvFrom.insert( numeric_cast< mpi::MPIRank >( neighbor.getProcess() ) );
    }
    WALBERLA_ASSERT( ( blocks_.empty() && blockProcessMap.empty() ) || ( blockProcessMap.size() == uint_t(1) ) );
 
@@ -589,10 +590,10 @@ void PhantomBlockForest::prepareMigration()
    mpi::BufferSystem bufferSystem( MPIManager::instance()->comm(), 1943 ); // phantomblockforest = 112 104 97 110 116 111 109 98 108 111 99 107 102 111 114 101 115 116 + 2
    bufferSystem.setReceiverInfo( ranksToRecvFrom, true ); // true = the size of a message from A to B varies
 
-   for( auto rank = ranksToRecvFrom.begin(); rank != ranksToRecvFrom.end(); ++rank )
+   for(int rank : ranksToRecvFrom)
    {
-      WALBERLA_ASSERT_UNEQUAL( uint_c(*rank), process );
-      bufferSystem.sendBuffer( *rank ) << blockProcessMap[ process ];
+      WALBERLA_ASSERT_UNEQUAL( uint_c(rank), process );
+      bufferSystem.sendBuffer( rank ) << blockProcessMap[ process ];
    }
 
    bufferSystem.sendAll();
@@ -604,9 +605,9 @@ void PhantomBlockForest::prepareMigration()
       recvIt.buffer() >> blockProcessMap[ uint_c( recvIt.rank() ) ];
    }
 
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+   for(auto & it : blocks_)
    {
-      auto & block = it->second;
+      auto & block = it.second;
       for( uint_t n = uint_t(0); n != block->getNeighborhoodSize(); ++n )
       {
          const uint_t p = block->getNeighborProcess(n);
@@ -624,20 +625,20 @@ void PhantomBlockForest::prepareMigration()
    ranksToRecvFrom.clear();
 
    const auto & blocks = blockforest_.getBlockMap();
-   for( auto it = blocks.begin(); it != blocks.end(); ++it )
+   for(const auto & block : blocks)
    {
-      auto & targets = it->second->getTargetProcess();
-      for( auto tp = targets.begin(); tp != targets.end(); ++tp )
-         if( *tp != process )
-            ranksToRecvFrom.insert( numeric_cast< mpi::MPIRank >( *tp ) );
+      auto & targets = block.second->getTargetProcess();
+      for(uint_t target : targets)
+         if( target != process )
+            ranksToRecvFrom.insert( numeric_cast< mpi::MPIRank >( target ) );
    }
    
    mpi::BufferSystem linkBufferSystem( MPIManager::instance()->comm(), 1945 ); // phantomblockforest = 112 104 97 110 116 111 109 98 108 111 99 107 102 111 114 101 115 116 + 4
    linkBufferSystem.setReceiverInfo( ranksToRecvFrom, true ); // true = the size of a message from A to B varies
    
-   for( auto it = blocks_.begin(); it != blocks_.end(); ++it )
+   for(auto & it : blocks_)
    {
-      auto & block = it->second;
+      auto & block = it.second;
       auto & id = block->getId();
       auto & sources = block->getSourceProcess();
       
diff --git a/src/blockforest/PhantomBlockForest.h b/src/blockforest/PhantomBlockForest.h
index 92211a7fc7d70c6075e951f83405b0496a8a349b..e1ab5bab05bc91942baf11dff35bd0671f8012ba 100644
--- a/src/blockforest/PhantomBlockForest.h
+++ b/src/blockforest/PhantomBlockForest.h
@@ -114,7 +114,7 @@ inline shared_ptr< PhantomBlock > PhantomBlockForest::getBlock( const BlockID &
    auto it = blocks_.find( id );
    if( it != blocks_.end() )
       return it->second;
-   return shared_ptr< PhantomBlock >();
+   return {};
 }
 
 
diff --git a/src/blockforest/SetupBlock.cpp b/src/blockforest/SetupBlock.cpp
index 7924a61ba14b4f5fdb1ddc26f6852c6efd83605d..3c8535c14335fa80a0a3f184bc3e458cec2401b5 100644
--- a/src/blockforest/SetupBlock.cpp
+++ b/src/blockforest/SetupBlock.cpp
@@ -35,10 +35,10 @@ void SetupBlock::assembleNeighborhood() {
 
    std::set< SetupBlock* > neighborhood;
 
-   for( uint_t n = 0; n != 26; ++n )
-      for( uint_t i = 0; i != neighborhoodSection_[n].size(); ++i )
-         if( neighborhood.insert( neighborhoodSection_[n][i] ).second )
-            neighborhood_.push_back( neighborhoodSection_[n][i] );
+   for( auto & nsec: neighborhoodSection_ )
+      for(auto block : nsec)
+         if( neighborhood.insert(block ).second )
+            neighborhood_.push_back(block );
 }
 
 
diff --git a/src/blockforest/SetupBlock.h b/src/blockforest/SetupBlock.h
index f700743fa3d8d8e619458567e2f887af1dd3e083..47f17f58a965d8ef84f0286165f93205c6d38ec3 100644
--- a/src/blockforest/SetupBlock.h
+++ b/src/blockforest/SetupBlock.h
@@ -49,7 +49,7 @@ public:
                       const real_t xmax, const real_t ymax, const real_t zmax, // excl.
                       const uint_t level );
 
-   ~SetupBlock() { for( uint_t i = 0; i != children_.size(); ++i ) delete children_[i]; }
+   ~SetupBlock() { for(auto & child : children_) delete child; }
 
    const BlockID& getId()            const { return Id_; }
          uint_t   getProcess()       const { return process_; }
@@ -142,7 +142,7 @@ private:
    SetupBlock*                 father_;
    std::vector< SetupBlock* >  children_;
 
-   std::vector< SetupBlock* >  neighborhoodSection_[26]; // the 26 neighborhood sections
+   std::array< std::vector< SetupBlock* >, 26 >  neighborhoodSection_; // the 26 neighborhood sections
    std::vector< SetupBlock* >  neighborhood_;            // all neighbor blocks
 
    uint_t index_{ 0 }; ///< used during static load balancing with METIS
diff --git a/src/blockforest/SetupBlockForest.cpp b/src/blockforest/SetupBlockForest.cpp
index b8d454d45c9d1ddc921343e98bca41db609642eb..f91b61e7f67164db6a18416ca0bde2e9e57ed9c4 100644
--- a/src/blockforest/SetupBlockForest.cpp
+++ b/src/blockforest/SetupBlockForest.cpp
@@ -72,14 +72,14 @@ uint_t SetupBlockForest::getNumberOfBlocks( const uint_t level ) const
 
    uint_t count( uint_t(0) );
 
-   for( uint_t i = 0; i != forest_.size(); ++i ) {
+   for(auto coarseBlock : forest_) {
 
-      if( forest_[i] == nullptr )
+      if(coarseBlock == nullptr )
          continue;
 
       std::stack< SetupBlock* > stack;
 
-      stack.push( forest_[i] );
+      stack.push(coarseBlock );
 
       while( !stack.empty() ) {
 
@@ -293,16 +293,16 @@ void SetupBlockForest::getBlocks( std::vector< const SetupBlock* >& blocks ) con
 
    // ATTENTION: the vector 'blocks' is not emptied
 
-   for( uint_t i = 0; i != forest_.size(); ++i ) {
+   for(auto coarseBlock : forest_) {
 
-      if( forest_[i] == nullptr )
+      if(coarseBlock == nullptr )
          continue;
 
       // depth-first search
 
       std::stack< SetupBlock* > stack;
 
-      stack.push( forest_[i] );
+      stack.push(coarseBlock );
 
       while( !stack.empty() ) {
 
@@ -326,16 +326,16 @@ void SetupBlockForest::getBlocks( std::vector< SetupBlock* >& blocks ) {
 
    // ATTENTION: the vector 'blocks' is not emptied
 
-   for( uint_t i = 0; i != forest_.size(); ++i ) {
+   for(auto & coarseBlock : forest_) {
 
-      if( forest_[i] == nullptr )
+      if(coarseBlock == nullptr )
          continue;
 
       // depth-first search
 
       std::stack< SetupBlock* > stack;
 
-      stack.push( forest_[i] );
+      stack.push(coarseBlock );
 
       while( !stack.empty() ) {
 
@@ -359,14 +359,14 @@ void SetupBlockForest::getBlocks( std::vector< const SetupBlock* >& blocks, cons
 
    // ATTENTION: the vector 'blocks' is not emptied
 
-   for( uint_t i = 0; i != forest_.size(); ++i ) {
+   for(auto coarseBlock : forest_) {
 
-      if( forest_[i] == nullptr )
+      if(coarseBlock == nullptr )
          continue;
 
       std::stack< SetupBlock* > stack;
 
-      stack.push( forest_[i] );
+      stack.push(coarseBlock );
 
       while( !stack.empty() ) {
 
@@ -390,14 +390,14 @@ void SetupBlockForest::getBlocks( std::vector< SetupBlock* >& blocks, const uint
 
    // ATTENTION: the vector 'blocks' is not emptied
 
-   for( uint_t i = 0; i != forest_.size(); ++i ) {
+   for(auto & coarseBlock : forest_) {
 
-      if( forest_[i] == nullptr )
+      if(coarseBlock == nullptr )
          continue;
 
       std::stack< SetupBlock* > stack;
 
-      stack.push( forest_[i] );
+      stack.push(coarseBlock );
 
       while( !stack.empty() ) {
 
@@ -486,8 +486,8 @@ void SetupBlockForest::getProcessSpecificBlocks( std::vector< const SetupBlock*
 
    const std::vector< SetupBlock* >& processBlocks = blockDistribution_[ process ];
 
-   for( uint_t i = 0; i < processBlocks.size(); ++i )
-      blocks.push_back( processBlocks[i] );
+   for(auto processBlock : processBlocks)
+      blocks.push_back( processBlock );
 }
 
 
@@ -501,8 +501,8 @@ void SetupBlockForest::getBlocksOverlappedByAABB( std::vector< SetupBlock* >& bl
        aabb.zMin() >= domain_.zMax() || aabb.zMax() <= domain_.zMin() )
       return;
 
-   uint_t min[3];
-   uint_t max[3];
+   std::array< uint_t, 3 > min;
+   std::array< uint_t, 3 > max;
 
    mapAABBToBoundingForestCoordinates( aabb, min, max );
 
@@ -599,7 +599,7 @@ uint_t SetupBlockForest::mapPointToTreeIndex( const real_t px, const real_t py,
 
 
 
-void SetupBlockForest::mapAABBToBoundingForestCoordinates( const AABB& aabb, uint_t (&min)[3], uint_t (&max)[3] ) const {
+void SetupBlockForest::mapAABBToBoundingForestCoordinates( const AABB& aabb, std::array< uint_t, 3 > & min, std::array< uint_t, 3 > & max ) const {
 
    // ATTENTION: min[3] incl., max[3] excl.
 
@@ -698,8 +698,8 @@ void SetupBlockForest::init( const AABB& domain, const uint_t xSize, const uint_
                       "(xSize (= " << xSize << ") * ySize (= " << ySize << ") * zSize (= " << zSize << "))!" )
 
    if( !forest_.empty() ) {
-      for( uint_t i = 0; i != forest_.size(); ++i ) {
-         if( forest_[i] != nullptr ) delete forest_[i];
+      for(auto & coarseBlock : forest_) {
+         delete coarseBlock;
       }
       forest_.clear();
    }
@@ -744,8 +744,8 @@ void SetupBlockForest::init( const AABB& domain, const uint_t xSize, const uint_
    if( !rootBlockExclusionFunctions.empty() )
       WALBERLA_LOG_PROGRESS( "Initializing SetupBlockForest: Calling root block exclusion callback functions ..." )
 
-   for( uint_t i = 0; i != rootBlockExclusionFunctions.size(); ++i )
-      rootBlockExclusionFunctions[i]( excludeBlock, rootBlockAABB );
+   for(const auto & rootBlockExclusionFunction : rootBlockExclusionFunctions)
+      rootBlockExclusionFunction( excludeBlock, rootBlockAABB );
 
    // creation of all root blocks
 
@@ -865,8 +865,8 @@ void SetupBlockForest::createForest( const Set<SUID>& selector ) {
 
       // MARK ALL BLOCKS THAT NEED TO BE SPLIT
 
-      for( uint_t i = 0; i < refinementSelectionFunctions.size(); ++i )
-         refinementSelectionFunctions[i]( *this );
+      for(const auto & refinementSelectionFunction : refinementSelectionFunctions)
+         refinementSelectionFunction( *this );
 
       // GET ALL BLOCKS (= ALL LEAVES)
 
@@ -901,8 +901,8 @@ void SetupBlockForest::createForest( const Set<SUID>& selector ) {
       // IDENTIFY ALL BLOCKS THAT ARE MARKED TO BE SPLIT
 
       std::vector< SetupBlock* > blocksToSplit;
-      for( uint_t i = 0; i < blocks.size(); ++i )
-         if( blocks[i]->isMarked() ) blocksToSplit.push_back( blocks[i] );
+      for(auto & block : blocks)
+         if( block->isMarked() ) blocksToSplit.push_back( block );
 
       numberOfBlocks_ += blocksToSplit.size() * 7;
 
@@ -938,9 +938,9 @@ void SetupBlockForest::createForest( const Set<SUID>& selector ) {
          WALBERLA_LOG_PROGRESS( "Initializing SetupBlockForest: Calling block exclusion callback functions on child blocks ..." )
          for( uint_t c = 0; c != 8; ++c )
          {
-            for( uint_t j = 0; j != blockExclusionFunctions.size(); ++j )
+            for(const auto & blockExclusionFunction : blockExclusionFunctions)
             {
-               if(blockExclusionFunctions[j]( *blocksToSplit[ uint_c(i) ]->getChild(c)))
+               if(blockExclusionFunction( *blocksToSplit[ uint_c(i) ]->getChild(c)))
                {
                   WALBERLA_LOG_DETAIL( "Initializing SetupBlockForest: Excluding child block with ID " << blocksToSplit[ uint_c(i) ]->getChild(c)->getId() <<
                                       "\n                               - AABB: " << blocksToSplit[ uint_c(i) ]->getChild(c)->getAABB() <<
@@ -956,9 +956,7 @@ void SetupBlockForest::createForest( const Set<SUID>& selector ) {
 
       std::set< SetupBlock* > blocksToUpdate;
 
-      for( uint_t i = 0; i < blocksToSplit.size(); ++i ) {
-
-         SetupBlock* const block = blocksToSplit[i];
+      for(auto block : blocksToSplit) {
 
          for( uint_t c = 0; c != 8; ++c )
          {
@@ -1071,9 +1069,9 @@ void SetupBlockForest::updateNeighborhood( std::vector< SetupBlock* >& blocks )
                WALBERLA_ASSERT_LESS_EQUAL( neighborhoodSectionBlocks.size(), 1 )
             }
 #endif
-            for( uint_t j = 0; j != neighborhoodSectionBlocks.size(); ++j )
-               if(neighborhoodSectionBlocks[j] != nullptr)
-                  block->addNeighbor( n, neighborhoodSectionBlocks[j] );
+            for(auto & neighborhoodSectionBlock : neighborhoodSectionBlocks)
+               if(neighborhoodSectionBlock != nullptr)
+                  block->addNeighbor( n, neighborhoodSectionBlock );
          }
 
          neighborhoodSectionBlocks.clear();
@@ -1146,8 +1144,8 @@ void SetupBlockForest::createNeighborhood() {
                WALBERLA_ASSERT_EQUAL( neighborhoodSectionBlocks.size(), 1 )
             }
 #endif
-            for( uint_t j = 0; j != neighborhoodSectionBlocks.size(); ++j )
-               block->addNeighbor( n, neighborhoodSectionBlocks[j] );
+            for(auto & neighborhoodSectionBlock : neighborhoodSectionBlocks)
+               block->addNeighbor( n, neighborhoodSectionBlock );
          }
 
          neighborhoodSectionBlocks.clear();
@@ -1192,8 +1190,8 @@ void SetupBlockForest::assignAllBlocksToRootProcess()
    std::vector< SetupBlock* > blocks;
    getBlocks( blocks );
 
-   for( uint_t i = 0; i != blocks.size(); ++i )
-      blocks[i]->assignTargetProcess( uint_c(0) );
+   for(auto & block : blocks)
+      block->assignTargetProcess( uint_c(0) );
 
    calculateProcessDistributionFinalization();
 }
@@ -1395,9 +1393,9 @@ void SetupBlockForest::calculateProcessDistribution_LevelwiseMetis( const uint_t
       else
       {
          uint_t targetProcess = 0;
-         for( auto blockIt = blocks.begin(); blockIt != blocks.end(); ++blockIt )
+         for(auto & block : blocks)
          {
-            (*blockIt)->assignTargetProcess( targetProcess++ );
+            block->assignTargetProcess( targetProcess++ );
          }
 
       }
@@ -1484,16 +1482,16 @@ void SetupBlockForest::calculateProcessDistribution_Greedy( const uint_t   numbe
       distributition.insert( distributition.end(), i );
 
    numberOfWorkerProcesses = 0;
-   for( auto block = blocks.begin(); block != blocks.end(); ++block )
+   for(auto & block : blocks)
    {
       auto process = distributition.begin();
       while( process != distributition.end() )
       {
-         if( memory[ *process ] + (*block)->getMemory() <= memoryLimit )
+         if( memory[ *process ] + block->getMemory() <= memoryLimit )
          {
-            workload[ *process ] += (*block)->getWorkload();
-            memory[ *process ]   += (*block)->getMemory();
-            (*block)->assignTargetProcess( *process );
+            workload[ *process ] += block->getWorkload();
+            memory[ *process ]   += block->getMemory();
+            block->assignTargetProcess( *process );
             WALBERLA_ASSERT_LESS_EQUAL( *process, numberOfWorkerProcesses )
             numberOfWorkerProcesses = std::max( numberOfWorkerProcesses, *process + uint_c(1) );
             break;
@@ -1551,28 +1549,28 @@ void SetupBlockForest::balanceLoadHelper( const TargetProcessAssignmentFunction
 
    std::vector< bool > processHasBlocks( numberOfWorkerProcesses, false );
 
-   for( auto block = blocks.begin(); block != blocks.end(); ++block )
+   for(auto & block : blocks)
    {
-      WALBERLA_CHECK_LESS( (*block)->getTargetProcess(), numberOfWorkerProcesses )
-      processHasBlocks[ (*block)->getTargetProcess() ] = true;
+      WALBERLA_CHECK_LESS( block->getTargetProcess(), numberOfWorkerProcesses )
+      processHasBlocks[ block->getTargetProcess() ] = true;
    }
 
-   for( auto it = processHasBlocks.begin(); it != processHasBlocks.end(); ++it )
-      WALBERLA_CHECK( *it )
+   for( bool has: processHasBlocks )
+      WALBERLA_CHECK( has )
 
    // make sure that the per process memory limit is satisfied
 
    if( perProcessMemoryLimit > memory_t(0) )
    {
       std::vector< memory_t > memory( numberOfWorkerProcesses, memory_c(0) );
-      for( auto block = blocks.begin(); block != blocks.end(); ++block )
+      for(auto & block : blocks)
       {
-         const uint_t targetProcess = (*block)->getTargetProcess();
-         if( memory[ targetProcess ] + (*block)->getMemory() > perProcessMemoryLimit )
+         const uint_t targetProcess = block->getTargetProcess();
+         if( memory[ targetProcess ] + block->getMemory() > perProcessMemoryLimit )
             WALBERLA_ABORT( "Load balancing failed: A distribution to " << numberOfProcesses << " processes given a memory limit of \"" << perProcessMemoryLimit <<
                             "\" is impossible.\n                       (Are the memory coefficients correctly assigned to all blocks via "
                             "a callback function that was registered with \"addWorkloadMemorySUIDAssignmentFunction()\"?)" )
-         memory[ targetProcess ] += (*block)->getMemory();
+         memory[ targetProcess ] += block->getMemory();
       }
    }
 
@@ -1646,15 +1644,15 @@ void SetupBlockForest::calculateProcessDistributionFinalization( const bool reor
 
    blockDistribution_.clear();
    blockDistribution_.resize( numberOfProcesses_ );
-   for( uint_t i = 0; i != blocks.size(); ++i )
-      blockDistribution_[ blocks[i]->getProcess() ].push_back( blocks[i] );
+   for(auto & block : blocks)
+      blockDistribution_[ block->getProcess() ].push_back( block );
 
 #ifndef NDEBUG
    std::vector< bool > processHasBlocks( numberOfProcesses_, false );
 
-   for( uint_t i = 0; i != blocks.size(); ++i ) {
-      WALBERLA_ASSERT_LESS( blocks[i]->getProcess(), numberOfProcesses_ )
-      processHasBlocks[ blocks[i]->getProcess() ] = true;
+   for(auto & block : blocks) {
+      WALBERLA_ASSERT_LESS( block->getProcess(), numberOfProcesses_ )
+      processHasBlocks[ block->getProcess() ] = true;
    }
 
    for( uint_t i = 0; i != numberOfProcesses_; ++i )
@@ -1695,15 +1693,15 @@ void SetupBlockForest::saveToFile( const char* const filename ) const {
 
    // number of coarse/root blocks in each direction
 
-   for( uint_t i = 0; i != 3; ++i ) {
-      uintToByteArray( size_[i], buffer, offset, 4 );
+   for(uint_t i : size_) {
+      uintToByteArray( i, buffer, offset, 4 );
       offset += 4;
    }
 
    // domain periodicity
 
-   for( uint_t i = 0; i != 3; ++i ) {
-      uintToByteArray( periodic_[i] ? uint_c(1) : uint_c(0), buffer, offset, 1 );
+   for(bool i : periodic_) {
+      uintToByteArray( i ? uint_c(1) : uint_c(0), buffer, offset, 1 );
       ++offset;
    }
 
@@ -1741,8 +1739,8 @@ void SetupBlockForest::saveToFile( const char* const filename ) const {
    Set<SUID> suids;
 
    for( uint_t i = 0; i != numberOfProcesses_; ++i ) {
-      for( uint_t j = 0; j != blockDistribution_[i].size(); ++j )
-         suids += blockDistribution_[i][j]->getState();
+      for(auto j : blockDistribution_[i])
+         suids += j->getState();
    }
 
    // number of SUIDs
@@ -1762,15 +1760,15 @@ void SetupBlockForest::saveToFile( const char* const filename ) const {
    // for every SUID ...
 
    uint_t i = 0;
-   for( Set<SUID>::const_iterator it = suids.begin(); it != suids.end(); ++it ) {
+   for(auto suid : suids) {
 
       std::vector< bool > suidBoolVec( 8 * suidBytes );
       suidBoolVec[i] =  true;
-      suidMap[ *it ] = suidBoolVec;
+      suidMap[ suid ] = suidBoolVec;
 
       // length of its identifier string
 
-      const uint_t length = it->getIdentifier().length();
+      const uint_t length = suid.getIdentifier().length();
       WALBERLA_CHECK_LESS( length, 256, "SUID identifiers are allowed to consist of 255 characters at most when saving the block structure to file!" )
 
       buffer.resize( 1 + length );
@@ -1778,7 +1776,7 @@ void SetupBlockForest::saveToFile( const char* const filename ) const {
 
       // the identifier string
 
-      const char* str = it->getIdentifier().c_str();
+      const char* str = suid.getIdentifier().c_str();
       for( uint_t j = 0; j != length; ++j )
          buffer[1+j] = *reinterpret_cast< const uint8_t* >( str + j );
 
@@ -1832,11 +1830,11 @@ void SetupBlockForest::saveToFile( const char* const filename ) const {
                std::vector< bool > suidBoolVec( 8 * suidBytes );
 
                const Set<SUID>& state = block->getState();
-               for( Set<SUID>::const_iterator suid = state.begin(); suid != state.end(); ++suid ) {
-                  WALBERLA_ASSERT( suidMap.find( *suid ) != suidMap.end() );
+               for(auto suid : state) {
+                  WALBERLA_ASSERT( suidMap.find( suid ) != suidMap.end() );
                   //Elementwise OR of all elements
                   for (uint_t k = 0;k  < suidBoolVec.size(); ++k) {
-                     suidBoolVec[k] = suidBoolVec[k] || suidMap.find( *suid )->second[k];
+                     suidBoolVec[k] = suidBoolVec[k] || suidMap.find( suid )->second[k];
                   }
                }
 
@@ -1874,8 +1872,8 @@ void SetupBlockForest::saveToFile( const char* const filename ) const {
       uintToByteArray( uint_c( neighbors.size() ), buffer, offset, 2 );
       offset += 2;
 
-      for( std::set< uint_t >::iterator it = neighbors.begin(); it != neighbors.end(); ++it ) {
-         uintToByteArray( *it, buffer, offset, processIdBytes );
+      for(uint_t neighbor : neighbors) {
+         uintToByteArray( neighbor, buffer, offset, processIdBytes );
          offset += processIdBytes;
       }
 
@@ -1905,13 +1903,12 @@ void SetupBlockForest::writeVTKOutput( const std::string & filestem ) const
    std::vector< const SetupBlock* > blocks;
    getBlocks( blocks );
 
-   for( uint_t i = 0; i != blocks.size(); ++i )
-      if( blocks[i]->getMemory() > 0 ) ++allocatedBlocks;
+   for(auto & block : blocks)
+      if( block->getMemory() > 0 ) ++allocatedBlocks;
 
    outfile << "POINTS " << ( 8 * allocatedBlocks ) << " " << typeToString<real_t>() << "\n\n";
 
-   for( uint_t i = 0; i != blocks.size(); ++i ) {
-      const SetupBlock* const block = blocks[i];
+   for(auto block : blocks) {
       if( block->getMemory() > 0 ) {
          for( uint_t z = 0; z != 2; ++z ) {
             for( uint_t y = 0; y != 2; ++y ) {
@@ -1948,17 +1945,17 @@ void SetupBlockForest::writeVTKOutput( const std::string & filestem ) const
    outfile << "\n\nSCALARS workload double 1"
            <<   "\nLOOKUP_TABLE default\n";
 
-   for( uint_t i = 0; i != blocks.size(); ++i ) {
-      if( blocks[i]->getMemory() > 0 )
-         outfile << blocks[i]->getWorkload() << "\n";
+   for(auto & block : blocks) {
+      if( block->getMemory() > 0 )
+         outfile << block->getWorkload() << "\n";
    }
 
    outfile << "\n\nSCALARS process int 1"
            <<   "\nLOOKUP_TABLE default\n";
 
-   for( uint_t i = 0; i != blocks.size(); ++i ) {
-      if( blocks[i]->getMemory() > 0 )
-         outfile << blocks[i]->getProcess() << "\n";
+   for(auto & block : blocks) {
+      if( block->getMemory() > 0 )
+         outfile << block->getProcess() << "\n";
    }
 
 #ifdef WALBERLA_BLOCKFOREST_PRIMITIVE_BLOCKID
@@ -1966,9 +1963,9 @@ void SetupBlockForest::writeVTKOutput( const std::string & filestem ) const
    outfile << "\n\nSCALARS blockId unsigned_long 1"
            <<   "\nLOOKUP_TABLE default\n";
 
-   for( uint_t i = 0; i != blocks.size(); ++i ) {
-      if( blocks[i]->getMemory() > 0 )
-         outfile << blocks[i]->getId().getTreeId() << "\n";
+   for(auto & block : blocks) {
+      if( block->getMemory() > 0 )
+         outfile << block->getId().getTreeId() << "\n";
    }
 
 #endif // WALBERLA_BLOCKFOREST_PRIMITIVE_BLOCKID
@@ -1976,9 +1973,9 @@ void SetupBlockForest::writeVTKOutput( const std::string & filestem ) const
    outfile << "\n\nSCALARS level double 1"
            <<   "\nLOOKUP_TABLE colors\n";
 
-   for( uint_t i = 0; i != blocks.size(); ++i ) {
-      if( blocks[i]->getMemory() > 0 )
-         outfile << (( depth_ == 0 ) ? 0 : ( static_cast< double >( blocks[i]->getLevel() ) / static_cast< double >( depth_ ) )) << "\n";
+   for(auto & block : blocks) {
+      if( block->getMemory() > 0 )
+         outfile << (( depth_ == 0 ) ? 0 : ( static_cast< double >( block->getLevel() ) / static_cast< double >( depth_ ) )) << "\n";
    }
 
    outfile << "\n\nLOOKUP_TABLE colors " << ( depth_ + 1 );
@@ -2012,8 +2009,8 @@ void SetupBlockForest::writeCSV( const std::string & filestem ) const
       for( uint_t i = 0; i <= depth_; ++i )
       {
          uint_t n = uint_t(0);
-         for( auto block = blocks->begin(); block != blocks->end(); ++block )
-            if( (*block)->getLevel() == i ) ++n;
+         for(auto block : *blocks)
+            if( block->getLevel() == i ) ++n;
          outfile << "," << n;
       }
       outfile << "\n";
@@ -2028,8 +2025,8 @@ void SetupBlockForest::writeCSV( const std::string & filestem ) const
 void SetupBlockForest::toStream( std::ostream & os ) const
 {
    uint_t discardedRootBlocks = uint_t(0);
-   for( auto block = forest_.begin(); block != forest_.end(); ++block )
-      if( *block == nullptr ) ++discardedRootBlocks;
+   for(auto block : forest_)
+      if( block == nullptr ) ++discardedRootBlocks;
 
    os << "- AABB: " << domain_ << "\n"
       << "- initial decomposition: " << size_[0] << " x " << size_[1] << " x " << size_[2] << " (= forest size)\n"
@@ -2053,18 +2050,18 @@ void SetupBlockForest::toStream( std::ostream & os ) const
          std::vector< real_t > workload      ( depth_ + 2, real_t(0) );
          std::vector< uint_t > numberOfBlocks( depth_ + 2, uint_t(0) );
 
-         for( auto block = begin(); block != end(); ++block )
+         for(const auto & block : *this)
          {
-            const auto level = block->getLevel();
+            const auto level = block.getLevel();
 
-            space[ level ]          += block->getAABB().volume();
-            memory[ level ]         += real_c( block->getMemory() );
-            workload[ level ]       += real_c( block->getWorkload() );
+            space[ level ]          += block.getAABB().volume();
+            memory[ level ]         += real_c( block.getMemory() );
+            workload[ level ]       += real_c( block.getWorkload() );
             numberOfBlocks[ level ] += uint_t(1);
 
-            space.back()          += block->getAABB().volume();
-            memory.back()         += real_c( block->getMemory() );
-            workload.back()       += real_c( block->getWorkload() );
+            space.back()          += block.getAABB().volume();
+            memory.back()         += real_c( block.getMemory() );
+            workload.back()       += real_c( block.getWorkload() );
             numberOfBlocks.back() += uint_t(1);
          }
 
@@ -2089,23 +2086,23 @@ void SetupBlockForest::toStream( std::ostream & os ) const
 
       WALBERLA_ASSERT_EQUAL( numberOfProcesses_, blockDistribution_.size() )
 
-      for( auto process = blockDistribution_.begin(); process != blockDistribution_.end(); ++process )
+      for( auto & process: blockDistribution_ )
       {
          std::vector< uint_t >     processBlocks  ( depth_ + 2, uint_t(0) );
          std::vector< memory_t >   processMemory  ( depth_ + 2, memory_t(0) );
          std::vector< workload_t > processWorkload( depth_ + 2, workload_t(0) );
 
-         for( auto block = process->begin(); block != process->end(); ++block )
+         for(auto block : process)
          {
-            const auto level = (*block)->getLevel();
+            const auto level = block->getLevel();
 
             processBlocks[level]   += uint_t(1);
-            processMemory[level]   += (*block)->getMemory();
-            processWorkload[level] += (*block)->getWorkload();
+            processMemory[level]   += block->getMemory();
+            processWorkload[level] += block->getWorkload();
 
             processBlocks.back()   += uint_t(1);
-            processMemory.back()   += (*block)->getMemory();
-            processWorkload.back() += (*block)->getWorkload();
+            processMemory.back()   += block->getMemory();
+            processWorkload.back() += block->getWorkload();
          }
 
          for( uint_t i = 0; i < depth_ + 2; ++i )
@@ -2147,14 +2144,14 @@ void SetupBlockForest::toStream( std::ostream & os ) const
          std::vector< real_t > space( depth_ + 2, real_t(0) );
          std::vector< uint_t > numberOfBlocks( depth_ + 2, uint_t(0) );
 
-         for( auto block = begin(); block != end(); ++block )
+         for(const auto & block : *this)
          {
-            const auto level = block->getLevel();
+            const auto level = block.getLevel();
 
-            space[ level ] += block->getAABB().volume();
+            space[ level ] += block.getAABB().volume();
             numberOfBlocks[ level ] += uint_t(1);
 
-            space.back() += block->getAABB().volume();
+            space.back() += block.getAABB().volume();
             numberOfBlocks.back() += uint_t(1);
          }
 
diff --git a/src/blockforest/SetupBlockForest.h b/src/blockforest/SetupBlockForest.h
index 1d105148f1d1c6beff3114d70b26099528ede467..26445f8c050a7fecc625c2385cf418e0f4b38f24 100644
--- a/src/blockforest/SetupBlockForest.h
+++ b/src/blockforest/SetupBlockForest.h
@@ -183,10 +183,10 @@ public:
    uint_t getNumberOfBlocks( const uint_t level ) const;
 
    inline const_iterator begin() const;
-   inline const_iterator end()   const { return const_iterator( this, nullptr ); }
+   inline const_iterator end()   const { return { this, nullptr }; }
 
    inline iterator begin();
-   inline iterator end() { return iterator( this, nullptr ); }
+   inline iterator end() { return { this, nullptr }; }
 
    const SetupBlock* getFirstBlock() const;
          SetupBlock* getFirstBlock();
@@ -235,7 +235,7 @@ public:
 
    uint_t mapPointToTreeIndex( const real_t px, const real_t py, const real_t pz ) const;
 
-   void mapAABBToBoundingForestCoordinates( const AABB& aabb, uint_t (&min)[3], uint_t (&max)[3] ) const;
+   void mapAABBToBoundingForestCoordinates( const AABB& aabb, std::array< uint_t, 3 > & min, std::array< uint_t, 3 > & max ) const;
 
    static void getRootBlockAABB( AABB& aabb, const AABB& domain,
                                  const real_t rootBlockXSize, const real_t rootBlockYSize, const real_t rootBlockZSize,
@@ -380,9 +380,9 @@ private:
    uint_t numberOfBlocks_{ 0 };
 
    AABB   domain_;           // the simulation space/region
-   real_t rootBlockSize_[3]; // [(domain x width) / size_[0]], etc. [equivalent to the size of each root block's bounding box]
-   uint_t size_[3];          // number of coarse blocks on the initial grid (= number of octree root blocks) in each direction
-   bool   periodic_[3];
+   std::array< real_t, 3 > rootBlockSize_; // [(domain x width) / size_[0]], etc. [equivalent to the size of each root block's bounding box]
+   std::array< uint_t, 3 > size_;          // number of coarse blocks on the initial grid (= number of octree root blocks) in each direction
+   std::array< bool, 3 >   periodic_;
 
    uint_t  depth_{ 0 }; // depth := number of levels - 1
    uint_t  treeIdDigits_{ 0 };
@@ -420,9 +420,9 @@ inline SetupBlockForest::SetupBlockForest() {
 
 inline SetupBlockForest::~SetupBlockForest() {
 
-   for( uint_t i = 0; i != forest_.size(); ++i )
+   for(auto & coarseBlock : forest_)
    {
-      if( forest_[i] != nullptr ) delete forest_[i];
+      delete coarseBlock;
    }
 }
 
@@ -435,7 +435,7 @@ inline SetupBlockForest::const_iterator SetupBlockForest::begin() const {
    if( block == nullptr )
       return end();
 
-   return SetupBlockForest::const_iterator( this, block );
+   return { this, block };
 }
 
 
@@ -447,7 +447,7 @@ inline SetupBlockForest::iterator SetupBlockForest::begin() {
    if( block == nullptr )
       return end();
 
-   return SetupBlockForest::iterator( this, block );
+   return { this, block };
 }
 
 
@@ -623,8 +623,8 @@ inline void SetupBlockForest::initWorkloadMemorySUID( const Set<SUID>& selector
       WALBERLA_LOG_PROGRESS( "Initializing SetupBlockForest: Assigning workload, memory requirements, and SUIDs to blocks ..." )
    }
 
-   for( uint_t i = 0; i != workloadMemorySUIDAssignmentFunctions.size(); ++i )
-      workloadMemorySUIDAssignmentFunctions[i]( *this );
+   for(const auto & workloadMemorySUIDAssignmentFunction : workloadMemorySUIDAssignmentFunctions)
+      workloadMemorySUIDAssignmentFunction( *this );
 }
 
 
@@ -633,8 +633,9 @@ inline void SetupBlockForest::updateNeighborhood( std::set< SetupBlock* >& block
 
    std::vector< SetupBlock* > blocks;
 
-   for( auto it = blocksToUpdate.begin(); it != blocksToUpdate.end(); ++it )
-      blocks.push_back( *it );
+   blocks.reserve(blocksToUpdate.size());
+   for(auto it : blocksToUpdate)
+      blocks.push_back( it );
 
    updateNeighborhood( blocks );
 }
@@ -737,8 +738,8 @@ public:
 
    void operator()( SetupBlockForest & forest )
    {
-      for( auto function = function_.begin(); function != function_.end(); ++function )
-         (*function)( forest );
+      for(auto & function : function_)
+         function( forest );
    }
 
 private:
diff --git a/src/blockforest/StructuredBlockForest.h b/src/blockforest/StructuredBlockForest.h
index 4e1f0cb5f9619f29a63c9f195b4f44bac909985c..14af31ca27201569f5faf0fd24ed50a8eafa4355 100644
--- a/src/blockforest/StructuredBlockForest.h
+++ b/src/blockforest/StructuredBlockForest.h
@@ -189,7 +189,7 @@ private:
 
    shared_ptr< BlockForest > blockForest_;
 
-   uint_t blockCells_[3];
+   std::array< uint_t, 3 > blockCells_;
 
 }; // class StructuredBlockForest
 
@@ -205,8 +205,12 @@ inline StructuredBlockForest::StructuredBlockForest( const shared_ptr< BlockFore
 
    blockForest_( blockForest ) {
 
+    auto resetCallback = [this]() {
+        StructuredBlockForest::resetCellDecompositionInStorage(*this);
+    };
+
    blockForest_->addRefreshCallbackFunctionBeforeBlockDataIsUnpacked(
-            BlockForest::RefreshCallbackWrappper( std::bind( resetCellDecompositionInStorage, std::ref(*this) ) ) );
+            BlockForest::RefreshCallbackWrappper( resetCallback ) );
 
    blockCells_[0] = blockXCells;
    blockCells_[1] = blockYCells;
diff --git a/src/blockforest/communication/DirectionBasedReduceScheme.h b/src/blockforest/communication/DirectionBasedReduceScheme.h
index 138e3f7131c52306e57e0caa199f47913704fce8..9c4792e06eb8762c2f1231a33bb07c972bcd60ee 100644
--- a/src/blockforest/communication/DirectionBasedReduceScheme.h
+++ b/src/blockforest/communication/DirectionBasedReduceScheme.h
@@ -225,16 +225,16 @@ void DirectionBasedReduceScheme<dir_>::copyIntoMPIBuffers()
    {
       for( size_t nb = 0u; nb < localCopy_[b].size(); ++nb )
       {
-         for(size_t s = 0u; s < packInfos_.size(); ++s)
+         for(auto & packInfo : packInfos_)
          {
-            packInfos_[s]->communicateLocal( localBlocks_[b], localCopy_[b][nb], dir_ );
+            packInfo->communicateLocal( localBlocks_[b], localCopy_[b][nb], dir_ );
          }
       }
 
       for( size_t nb = 0u; nb < remoteSend_[b].size(); ++nb )
       {
          bool headerWritten = false;
-         for(size_t s = 0u; s < packInfos_.size(); ++s)
+         for(auto & packInfo : packInfos_)
          {
             //Packing of MPI Buffer
             uint_t rank,nx,ny,nz;
@@ -249,7 +249,7 @@ void DirectionBasedReduceScheme<dir_>::copyIntoMPIBuffers()
             }
 
             // Call Packer
-            packInfos_[s]->packData( localBlocks_[b], dir_, buffer );
+            packInfo->packData( localBlocks_[b], dir_, buffer );
          }
       }
    }
@@ -260,8 +260,8 @@ void DirectionBasedReduceScheme<dir_>::copyIntoMPIBuffers()
 template< stencil::Direction dir_ >
 void DirectionBasedReduceScheme<dir_>::copyFromMPIBuffers()
 {
-   for(size_t s = 0u; s < packInfos_.size(); ++s){
-      packInfos_[s]->reset();
+   for(auto & packInfo : packInfos_){
+      packInfo->reset();
    }
 
    //  --------  Loop over all incoming messages  -------------------------------------
@@ -277,10 +277,10 @@ void DirectionBasedReduceScheme<dir_>::copyFromMPIBuffers()
          // Get receiving block
          Block * rBlock = blockForest_->getBlockForest().getBlock(rBlockID);
 
-         for(size_t s = 0u; s < packInfos_.size(); ++s)
+         for(auto & packInfo : packInfos_)
          {
             // Call Unpacker
-            packInfos_[s]->unpackData( rBlock, stencil::inverseDir[dir_], buffer );
+            packInfo->unpackData( rBlock, stencil::inverseDir[dir_], buffer );
          }
       }
    }
diff --git a/src/blockforest/communication/NonUniformBufferedScheme.h b/src/blockforest/communication/NonUniformBufferedScheme.h
index 0a6a453abacef502f5620d2d9c3c59514e9e8fc6..ee69a0e76eba5a5da38ca382855e8e1baa881d2f 100644
--- a/src/blockforest/communication/NonUniformBufferedScheme.h
+++ b/src/blockforest/communication/NonUniformBufferedScheme.h
@@ -159,7 +159,7 @@ protected:
    static void writeHeader( SendBuffer & buffer, const BlockID & sender, const BlockID & receiver, const stencil::Direction & dir );
    static void  readHeader( RecvBuffer & buffer,       BlockID & sender,       BlockID & receiver,       stencil::Direction & dir );
 
-   static void send( SendBuffer & buffer, std::vector< SendBufferFunction > & functions );
+   static void send( SendBuffer & buffer, const std::vector< SendBufferFunction > & functions );
           void receive( RecvBuffer & buffer );
 
    void localBufferPacking( INDEX i, uint_t j, uint_t bufferIndex, const PackInfo & packInfo,
@@ -709,8 +709,11 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationEqualLevel( const uint
 
       for( auto & sender : sendFunctions)
       {
-         bufferSystem->addSendingFunction  ( int_c(sender.first), std::bind(  NonUniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender.second ) );
-         bufferSystem->addReceivingFunction( int_c(sender.first), std::bind( &NonUniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) );
+         auto sendingFunc = [sfunc = sender.second](SendBuffer & sbuf) { NonUniformBufferedScheme< Stencil >::send(sbuf, sfunc); };
+         bufferSystem->addSendingFunction  ( int_c(sender.first), sendingFunc );
+
+         auto receivingFunc = [this](RecvBuffer & rbuf){ this->receive(rbuf); };
+         bufferSystem->addReceivingFunction( int_c(sender.first), receivingFunc );
       }
 
       setupBeforeNextCommunication = char(0);
@@ -851,11 +854,15 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationCoarseToFine( const ui
 
       resetBufferSystem( bufferSystem );
 
-      for( auto const &sender : sendFunctions )
-         bufferSystem->addSendingFunction( int_c(sender.first), std::bind(  NonUniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender.second ) );
+      for( auto const &sender : sendFunctions ){
+          auto sendingFunc = [sfunc = sender.second](SendBuffer & sbuf) { NonUniformBufferedScheme< Stencil >::send(sbuf, sfunc); };
+          bufferSystem->addSendingFunction( int_c(sender.first), sendingFunc );
+      }
 
-      for(auto receiver : ranksToReceiveFrom)
-         bufferSystem->addReceivingFunction( int_c(receiver), std::bind( &NonUniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) );
+      for(auto receiver : ranksToReceiveFrom){
+          auto receivingFunc = [this](RecvBuffer & rbuf){ this->receive(rbuf); };
+          bufferSystem->addReceivingFunction( int_c(receiver), receivingFunc );
+      }
 
       setupBeforeNextCommunication = char(0);
    }
@@ -996,11 +1003,15 @@ void NonUniformBufferedScheme<Stencil>::startCommunicationFineToCoarse( const ui
 
       resetBufferSystem( bufferSystem );
 
-      for( auto const &sender : sendFunctions )
-         bufferSystem->addSendingFunction( int_c(sender.first), std::bind(  NonUniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender.second ) );
+      for( auto const &sender : sendFunctions ){
+          auto sendingFunc = [sfunc = sender.second](SendBuffer & sbuf) { NonUniformBufferedScheme< Stencil >::send(sbuf, sfunc); };
+          bufferSystem->addSendingFunction( int_c(sender.first), sendingFunc );
+      }
 
-      for(auto receiver : ranksToReceiveFrom)
-         bufferSystem->addReceivingFunction( int_c(receiver), std::bind( &NonUniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) );
+      for(auto receiver : ranksToReceiveFrom){
+          auto receivingFunc = [this](RecvBuffer & rbuf){ this->receive(rbuf); };
+          bufferSystem->addReceivingFunction( int_c(receiver), receivingFunc );
+      }
 
       setupBeforeNextCommunication = char(0);
    }
@@ -1141,7 +1152,7 @@ void NonUniformBufferedScheme<Stencil>::readHeader( RecvBuffer & buffer, BlockID
 
 
 template< typename Stencil >
-void NonUniformBufferedScheme<Stencil>::send( SendBuffer & buffer, std::vector< SendBufferFunction > & functions )
+void NonUniformBufferedScheme<Stencil>::send( SendBuffer & buffer, const std::vector< SendBufferFunction > & functions )
 {
    for(auto & function : functions)
       function( buffer );
diff --git a/src/blockforest/communication/UniformBufferedScheme.h b/src/blockforest/communication/UniformBufferedScheme.h
index e7cbd6c631ad0751f486ab4071aee310d58ef06f..b47f7c74dceba6616c965284e2a6d250ed976063 100644
--- a/src/blockforest/communication/UniformBufferedScheme.h
+++ b/src/blockforest/communication/UniformBufferedScheme.h
@@ -169,7 +169,7 @@ protected:
    static void writeHeader( SendBuffer & buffer, const BlockID & id, const stencil::Direction & dir );
    static void  readHeader( RecvBuffer & buffer,       BlockID & id,       stencil::Direction & dir );
 
-   static void send   ( SendBuffer & buffer, std::vector< SendBufferFunction > & functions );
+   static void send   ( SendBuffer & buffer, const std::vector< SendBufferFunction > & functions );
           void receive( RecvBuffer & buffer );
 
    void localBufferPacking  ( const uint_t index, const PackInfo & packInfo, const Block * sender,   const stencil::Direction & dir );
@@ -253,15 +253,15 @@ void UniformBufferedScheme<Stencil>::startCommunication()
 
    communicationInProgress_ = true;
 
-   for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
-      ( *packInfo )->beforeStartCommunication();
+   for(auto & packInfo : packInfos_)
+      packInfo->beforeStartCommunication();
 
    bool constantSizes = true;
    bool threadsafeReceive = true;
-   for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
+   for(auto & packInfo : packInfos_)
    {
-      if( !( *packInfo )->constantDataExchange() ) constantSizes = false;
-      if( !( *packInfo )->threadsafeReceiving()  ) threadsafeReceive = false;
+      if( !packInfo->constantDataExchange() ) constantSizes = false;
+      if( !packInfo->threadsafeReceiving()  ) threadsafeReceive = false;
    }
 
    // Redo setup if a PackInfo has changed its requirements
@@ -301,7 +301,7 @@ void UniformBufferedScheme<Stencil>::startCommunication()
             WALBERLA_ASSERT( block->neighborhoodSectionHasEquallySizedBlock(neighborIdx) );
             WALBERLA_ASSERT_EQUAL( block->getNeighborhoodSectionSize(neighborIdx), uint_t(1) );
 
-            const BlockID & nBlockId = block->getNeighborId( neighborIdx, uint_t(0) );
+            const BlockID nBlockId = block->getNeighborId( neighborIdx, uint_t(0) );
 
             if( !selectable::isSetSelected( block->getNeighborState( neighborIdx, uint_t(0) ), requiredBlockSelectors_, incompatibleBlockSelectors_ ) )
                continue;
@@ -311,7 +311,7 @@ void UniformBufferedScheme<Stencil>::startCommunication()
                auto neighbor = dynamic_cast< Block * >( forest->getBlock(nBlockId) );
                WALBERLA_ASSERT_EQUAL( neighbor->getProcess(), block->getProcess() );
 
-               for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
+               for(auto & packInfo : packInfos_)
                {
                   if( localMode_ == BUFFER )
                   {
@@ -319,24 +319,28 @@ void UniformBufferedScheme<Stencil>::startCommunication()
                      localBuffers_.push_back( buffer );
                      const uint_t index = uint_c( localBuffers_.size() ) - uint_t(1);
 
-                     VoidFunction pack = std::bind( &UniformBufferedScheme<Stencil>::localBufferPacking, this,
-                                                      index, std::cref( *packInfo ), block, *dir );
+                     VoidFunction pack = [this, index, pi=packInfo, block, direction = *dir]() {
+                        this->localBufferPacking(index, pi, block, direction);
+                     };
 
                      threadsafeLocalCommunication_.push_back( pack );
 
-                     VoidFunction unpack = std::bind( &UniformBufferedScheme<Stencil>::localBufferUnpacking, this,
-                                                        index, std::cref( *packInfo ), neighbor, *dir  );
+                     VoidFunction unpack = [this, index, pi=packInfo, neighbor, direction=*dir]() {
+                        this->localBufferUnpacking(index, pi, neighbor, direction);
+                     };
 
-                     if( (*packInfo)->threadsafeReceiving() )
+                     if( packInfo->threadsafeReceiving() )
                         threadsafeLocalCommunicationUnpack_.push_back( unpack );
                      else
                         localCommunicationUnpack_.push_back( unpack );
                   }
                   else
                   {
-                     VoidFunction localCommunicationFunction = std::bind( &walberla::communication::UniformPackInfo::communicateLocal,
-                                                                            *packInfo, block, neighbor, *dir );
-                     if( (*packInfo)->threadsafeReceiving() )
+                     VoidFunction localCommunicationFunction = [pi=packInfo, block, neighbor, direction = *dir](){
+                        pi->communicateLocal(block, neighbor, direction);
+                     };
+
+                     if( packInfo->threadsafeReceiving() )
                         threadsafeLocalCommunication_.push_back( localCommunicationFunction );
                      else
                         localCommunication_.push_back( localCommunicationFunction );
@@ -347,12 +351,21 @@ void UniformBufferedScheme<Stencil>::startCommunication()
             {
                auto nProcess = block->getNeighborProcess( neighborIdx, uint_t(0) );
 
-               if( !packInfos_.empty() )
-                  sendFunctions[ nProcess ].push_back( std::bind( UniformBufferedScheme<Stencil>::writeHeader, std::placeholders::_1, nBlockId, *dir ) );
+               if( !packInfos_.empty() ){
+                  auto writeHeader = [bId=nBlockId, direction = *dir](SendBuffer & buf){
+                     UniformBufferedScheme<Stencil>::writeHeader(buf, bId, direction);
+                  };
+                  sendFunctions[ nProcess ].push_back( writeHeader );
+               }
+                  
 
-               for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
-                  sendFunctions[ nProcess ].push_back( std::bind( &walberla::communication::UniformPackInfo::packData,
-                                                                     *packInfo, block, *dir,  std::placeholders::_1 ) );
+               for(auto & packInfo : packInfos_){
+                  auto packData = [pi = packInfo, block, direction = *dir](SendBuffer & buf){
+                     pi->packData(block, direction, buf);
+                  };
+                  sendFunctions[ nProcess ].push_back( packData );
+               }
+                  
             }
          }
       }
@@ -364,10 +377,13 @@ void UniformBufferedScheme<Stencil>::startCommunication()
       bufferSystem_.enforceSerialSends( false );
       bufferSystem_.enforceSerialRecvs( !threadsafeReceive );
 
-      for( auto sender = sendFunctions.begin(); sender != sendFunctions.end(); ++sender )
+      for( const auto& sIt : sendFunctions )
       {
-         bufferSystem_.addSendingFunction  ( int_c(sender->first), std::bind(  UniformBufferedScheme<Stencil>::send, std::placeholders::_1, sender->second ) );
-         bufferSystem_.addReceivingFunction( int_c(sender->first), std::bind( &UniformBufferedScheme<Stencil>::receive, this, std::placeholders::_1 ) );
+         auto sendingFunc = [sfunc = sIt.second](auto & sbuf) { UniformBufferedScheme< Stencil >::send(sbuf, sfunc); };
+         bufferSystem_.addSendingFunction  (int_c(sIt.first), sendingFunc );
+
+         auto receivingFunc = [this](auto & rbuf) { this->receive(rbuf); };
+         bufferSystem_.addReceivingFunction( int_c(sIt.first), receivingFunc );
       }
 
       setupBeforeNextCommunication_ = false;
@@ -382,8 +398,8 @@ void UniformBufferedScheme<Stencil>::startCommunication()
    
    if( localMode_ == START )
    {
-      for( auto function = localCommunication_.begin(); function != localCommunication_.end(); ++function )
-         (*function)();
+      for(auto & function : localCommunication_)
+         function();
 
       const int threadsafeLocalCommunicationSize = int_c( threadsafeLocalCommunication_.size() );
 #ifdef _OPENMP
@@ -402,8 +418,8 @@ void UniformBufferedScheme<Stencil>::startCommunication()
          threadsafeLocalCommunication_[uint_c(i)]();
    }
 
-   for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
-      ( *packInfo )->afterStartCommunication();
+   for(auto & packInfo : packInfos_)
+      packInfo->afterStartCommunication();
 }
 
 
@@ -414,15 +430,15 @@ void UniformBufferedScheme<Stencil>::wait()
    if( packInfos_.empty() || !communicationInProgress_ )
       return;
 
-   for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
-      (*packInfo)->beforeWait();
+   for(auto & packInfo : packInfos_)
+      packInfo->beforeWait();
 
    // LOCAL
 
    if( localMode_ == WAIT )
    {
-      for( auto function = localCommunication_.begin(); function != localCommunication_.end(); ++function )
-         (*function)();
+      for(auto & function : localCommunication_)
+         function();
 
       const int threadsafeLocalCommunicationSize = int_c( threadsafeLocalCommunication_.size() );
 #ifdef _OPENMP
@@ -433,8 +449,8 @@ void UniformBufferedScheme<Stencil>::wait()
    }
    else if( localMode_ == BUFFER )
    {
-      for( auto function = localCommunicationUnpack_.begin(); function != localCommunicationUnpack_.end(); ++function )
-         (*function)();
+      for(auto & function : localCommunicationUnpack_)
+         function();
 
       const int threadsafeLocalCommunicationUnpackSize = int_c( threadsafeLocalCommunicationUnpack_.size() );
 #ifdef _OPENMP
@@ -448,8 +464,8 @@ void UniformBufferedScheme<Stencil>::wait()
 
    bufferSystem_.wait();
 
-   for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
-      ( *packInfo )->afterWait();
+   for(auto & packInfo : packInfos_)
+      packInfo->afterWait();
 
    communicationInProgress_ = false;
 }
@@ -475,10 +491,10 @@ void UniformBufferedScheme<Stencil>::readHeader( RecvBuffer & buffer, BlockID &
 
 
 template< typename Stencil >
-void UniformBufferedScheme<Stencil>::send( SendBuffer & buffer, std::vector< SendBufferFunction > & functions )
+void UniformBufferedScheme<Stencil>::send( SendBuffer & buffer, const std::vector< SendBufferFunction > & functions )
 {
-   for( auto function = functions.begin(); function != functions.end(); ++function )
-      (*function)( buffer );
+   for(auto & function : functions)
+      function( buffer );
 }
 
 
@@ -500,8 +516,8 @@ void UniformBufferedScheme<Stencil>::receive( RecvBuffer & buffer )
 
          auto block = dynamic_cast< Block * >( forest->getBlock(blockID) );
 
-         for( auto packInfo = packInfos_.begin(); packInfo != packInfos_.end(); ++packInfo )
-            (*packInfo)->unpackData( block, stencil::inverseDir[dir], buffer );
+         for(auto & packInfo : packInfos_)
+            packInfo->unpackData( block, stencil::inverseDir[dir], buffer );
       }
    }
 }
diff --git a/src/blockforest/communication/UniformDirectScheme.impl.h b/src/blockforest/communication/UniformDirectScheme.impl.h
index 7f61c164aad3bbc23d0bcfd11b4f45dfa209ab1b..edbdac408b4b781ef89615d2974ef2c3f1448497 100644
--- a/src/blockforest/communication/UniformDirectScheme.impl.h
+++ b/src/blockforest/communication/UniformDirectScheme.impl.h
@@ -98,9 +98,9 @@ void UniformDirectScheme<Stencil>::setup()
    WALBERLA_ASSERT( !communicationRunning_ );
 
    WALBERLA_DEBUG_SECTION() {
-      for( auto it = mpiRequests_.begin(); it != mpiRequests_.end(); ++it )
+      for( [[maybe_unused]] auto req: mpiRequests_ )
       {
-         WALBERLA_ASSERT_EQUAL( *it, MPI_REQUEST_NULL );
+         WALBERLA_ASSERT_EQUAL( req, MPI_REQUEST_NULL );
       }
    }
 
diff --git a/src/blockforest/loadbalancing/Cartesian.cpp b/src/blockforest/loadbalancing/Cartesian.cpp
index 4645286d55e015d92a79486f45c7dd24279b9390..818d60e646cad18ea427982c6bb89ed007067580 100644
--- a/src/blockforest/loadbalancing/Cartesian.cpp
+++ b/src/blockforest/loadbalancing/Cartesian.cpp
@@ -51,12 +51,12 @@ uint_t CartesianDistribution::operator()( SetupBlockForest & forest, const uint_
    if( !processIdMap_->empty() )
       WALBERLA_CHECK_EQUAL( processIdMap_->size(), numberOfProcesses );
 
-   uint_t partitions[3];
+   std::array< uint_t, 3 > partitions;
    partitions[0] = numberOfXProcesses_;
    partitions[1] = numberOfYProcesses_;
    partitions[2] = numberOfZProcesses_;
 
-   std::vector< uint_t > indices[3];
+   std::array< std::vector< uint_t >, 3 > indices;
 
    for( uint_t i = 0; i != 3; ++i )
    {
@@ -80,11 +80,11 @@ uint_t CartesianDistribution::operator()( SetupBlockForest & forest, const uint_
 
             forest.getBlocks( partitionBlocks, indices[0][x], indices[1][y], indices[2][z], indices[0][x+1], indices[1][y+1], indices[2][z+1] );
 
-            for( auto block = partitionBlocks.begin(); block != partitionBlocks.end(); ++block )
+            for(auto & partitionBlock : partitionBlocks)
             {
                const uint_t index = z * partitions[0] * partitions[1] + y * partitions[0] + x;
 
-               (*block)->assignTargetProcess( ( !processIdMap_->empty() ) ? (*processIdMap_)[ index ] : index );
+               partitionBlock->assignTargetProcess( ( !processIdMap_->empty() ) ? (*processIdMap_)[ index ] : index );
             }
          }
       }
diff --git a/src/blockforest/loadbalancing/DynamicCurve.h b/src/blockforest/loadbalancing/DynamicCurve.h
index 6b6c9736612a0b4181112363624e559e1fd1e3fc..3ce5475d87221313762293e748c7e630ccc20079 100644
--- a/src/blockforest/loadbalancing/DynamicCurve.h
+++ b/src/blockforest/loadbalancing/DynamicCurve.h
@@ -177,7 +177,7 @@ private:
 
    bool weightedBlocks() const
    {
-      return ! std::is_same< PhantomData_T, NoPhantomData >::value;
+      return ! std::is_same_v< PhantomData_T, NoPhantomData >;
    }
    
    template< typename T >
@@ -239,10 +239,10 @@ void DynamicCurveBalance< PhantomData_T >::allGatherWeighted( std::vector< std::
 {  
    std::vector< std::pair< BlockID, weight_t > > localBlocks;
 
-   for( auto it = targetProcess.begin(); it != targetProcess.end(); ++it )
+   for(auto & processIt : targetProcess)
    {
-      weight_t weight = it->first->template getData< PhantomData_T >().weight();
-      localBlocks.push_back( std::make_pair( it->first->getId(), weight ) );
+      weight_t weight = processIt.first->template getData< PhantomData_T >().weight();
+      localBlocks.push_back( std::make_pair(processIt.first->getId(), weight ) );
    }
    
    mpi::SendBuffer sendBuffer;
@@ -285,8 +285,9 @@ void DynamicCurveBalance< PhantomData_T >::allGatherNoWeight( std::vector< std::
 {
    std::vector< BlockID > localBlocks;
 
-   for( auto it = targetProcess.begin(); it != targetProcess.end(); ++it )
-      localBlocks.push_back( it->first->getId() );
+   localBlocks.reserve(targetProcess.size());
+   for(auto & processIt : targetProcess)
+      localBlocks.push_back(processIt.first->getId() );
    
    mpi::SendBuffer sendBuffer;
    mpi::RecvBuffer recvBuffer;
@@ -328,10 +329,10 @@ void DynamicCurveBalance< PhantomData_T >::masterWeighted( std::vector< std::pai
 {
    std::vector< std::pair< BlockID, weight_t > > localBlocks;
 
-   for( auto it = targetProcess.begin(); it != targetProcess.end(); ++it )
+   for(auto & processIt : targetProcess)
    {
-      weight_t weight = it->first->template getData< PhantomData_T >().weight();
-      localBlocks.push_back( std::make_pair( it->first->getId(), weight ) );
+      weight_t weight = processIt.first->template getData< PhantomData_T >().weight();
+      localBlocks.push_back( std::make_pair(processIt.first->getId(), weight ) );
    } 
    
    std::set< mpi::MPIRank > ranksToRecvFrom;
@@ -405,8 +406,9 @@ void DynamicCurveBalance< PhantomData_T >::masterNoWeight( std::vector< std::pai
 {
    std::vector< BlockID > localBlocks;
 
-   for( auto it = targetProcess.begin(); it != targetProcess.end(); ++it )
-      localBlocks.push_back( it->first->getId() );
+   localBlocks.reserve(targetProcess.size());
+   for(auto & processIt : targetProcess)
+      localBlocks.push_back(processIt.first->getId() );
    
    std::set< mpi::MPIRank > ranksToRecvFrom;
 
@@ -776,10 +778,8 @@ void DynamicCurveBalance< PhantomData_T >::balanceWeighted( const std::vector< s
    for( uint_t p = uint_t(0); p != processes; ++p )
       targets[p].resize( allBlocks[p].size() );
    
-   for( uint_t i = 0; i < blocksPerLevel.size(); ++i )
+   for(const auto & blocks : blocksPerLevel)
    {
-      const std::vector< std::pair< pid_t, idx_t > > & blocks = blocksPerLevel[i];
-      
       long double totalWeight( 0 );
       for( auto block = blocks.begin(); block != blocks.end(); ++block )
       {
@@ -831,10 +831,8 @@ void DynamicCurveBalance< PhantomData_T >::balanceNoWeight( const std::vector< s
    for( uint_t p = uint_t(0); p != processes; ++p )
       targets[p].resize( allBlocks[p].size() );
    
-   for( uint_t i = 0; i < blocksPerLevel.size(); ++i )
+   for(const auto & blocks : blocksPerLevel)
    {
-      const std::vector< std::pair< pid_t, idx_t > > & blocks = blocksPerLevel[i];
-
       const uint_t base = uint_c( blocks.size() ) / processes;
       const uint_t rest = uint_c( blocks.size() ) % processes;
 
@@ -934,8 +932,8 @@ void DynamicCurveBalance< PhantomData_T >::finalAssignment( const uint_t index,
    for( uint_t i = uint_t(0); i != targetProcess.size(); ++i )
       targetProcess[i].second = uint_c( targets[index][i] );
 
-   for( auto s = sender[index].begin(); s != sender[index].end(); ++s )
-      processesToRecvFrom.insert( uint_c(*s) ) ;
+   for(pid_t s : sender[index])
+      processesToRecvFrom.insert( uint_c(s) ) ;
 }
 
 template< typename PhantomData_T >
diff --git a/src/blockforest/loadbalancing/DynamicDiffusive.h b/src/blockforest/loadbalancing/DynamicDiffusive.h
index 920e3c309dc7e97eb54f1323a2cdda8ff4d34455..6778bbe7c0ee25bb4c5725d9e2f085dba3e95f12 100644
--- a/src/blockforest/loadbalancing/DynamicDiffusive.h
+++ b/src/blockforest/loadbalancing/DynamicDiffusive.h
@@ -58,10 +58,8 @@ public:
 
    DynamicDiffusionBalance( const uint_t maxIterations, const uint_t flowIterations, const bool levelwise = true ) :
       mode_( DIFFUSION_PUSHPULL ), maxIterations_( maxIterations ),
-      defineProcessWeightLimitByMultipleOfMaxBlockWeight_( true ), checkForEarlyAbort_( true ), abortThreshold_( 1.0 ),
-      adaptOutflowWithGlobalInformation_( true ), adaptInflowWithGlobalInformation_( true ),
-      flowIterations_( flowIterations ), flowIterationsIncreaseStart_( maxIterations ), flowIterationsIncrease_( 0.0 ),
-      regardConnectivity_( true ), disregardConnectivityStart_( maxIterations ), outflowExceedFactor_( 1.0 ), inflowExceedFactor_( 1.0 ),
+      flowIterations_( flowIterations ), flowIterationsIncreaseStart_( maxIterations ),
+      disregardConnectivityStart_( maxIterations ),
       levelwise_(levelwise)
    {}
    
@@ -116,7 +114,7 @@ private:
 
    double weight( const PhantomBlock * block ) const
    {
-      return std::is_same< PhantomData_T, NoPhantomData >::value ? 1.0 :
+      return std::is_same_v< PhantomData_T, NoPhantomData > ? 1.0 :
                numeric_cast< double >( block->template getData< PhantomData_T >().weight() );
    }
 
@@ -124,20 +122,20 @@ private:
    
    uint_t maxIterations_;
    
-   bool defineProcessWeightLimitByMultipleOfMaxBlockWeight_; // only evaluated when checkForEarlyAbort_ == true or adaptOutflowWithGlobalInformation_ == true
-   bool checkForEarlyAbort_;
-   double abortThreshold_; // only evaluated when checkForEarlyAbort_ == true
-   bool adaptOutflowWithGlobalInformation_;
-   bool adaptInflowWithGlobalInformation_;
+   bool defineProcessWeightLimitByMultipleOfMaxBlockWeight_ { true }; // only evaluated when checkForEarlyAbort_ == true or adaptOutflowWithGlobalInformation_ == true
+   bool checkForEarlyAbort_{ true };
+   double abortThreshold_{ 1.0 }; // only evaluated when checkForEarlyAbort_ == true
+   bool adaptOutflowWithGlobalInformation_{ true };
+   bool adaptInflowWithGlobalInformation_{ true };
    
    uint_t flowIterations_;
    uint_t flowIterationsIncreaseStart_;
-   double flowIterationsIncrease_;
+   double flowIterationsIncrease_{ 0.0 };
    
-   bool regardConnectivity_;
+   bool regardConnectivity_{ true };
    uint_t disregardConnectivityStart_;
-   double outflowExceedFactor_;
-   double inflowExceedFactor_;
+   double outflowExceedFactor_{ 1.0 };
+   double inflowExceedFactor_{ 1.0 };
    
    math::IntRandom< uint_t > random_;
 
@@ -172,10 +170,10 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
    
    //fill processWeight with total weight per level
    //find maxBlockWeight per level
-   for( auto it = targetProcess.begin(); it != targetProcess.end(); ++it )
+   for(auto & targetProces : targetProcess)
    {
-      const uint_t level = levelwise_ ? it->first->getLevel() : uint_t(0);
-      const auto blockWeight = weight( it->first );
+      const uint_t level = levelwise_ ? targetProces.first->getLevel() : uint_t(0);
+      const auto blockWeight = weight( targetProces.first );
       WALBERLA_ASSERT_LESS( level, levels );
       WALBERLA_CHECK_GREATER_EQUAL( blockWeight, 0.0 );
       processWeight[ level ] += blockWeight;
@@ -190,8 +188,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
       avgProcessWeight = processWeight;
       mpi::allReduceInplace( avgProcessWeight, mpi::SUM, MPIManager::instance()->comm() );
       const double numProcesses = double_c( MPIManager::instance()->numProcesses() );
-      for( auto it = avgProcessWeight.begin(); it != avgProcessWeight.end(); ++it )
-         *it /= numProcesses;
+      for(double & it : avgProcessWeight)
+         it /= numProcesses;
       mpi::allReduceInplace( maxBlockWeight, mpi::MAX, MPIManager::instance()->comm() );
    }
    
@@ -235,8 +233,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
    // alpha exchange
 
    std::map< mpi::MPIRank, mpi::MPISize > alphaRanksToRecvFrom;
-   for( auto n = neighborhood.begin(); n != neighborhood.end(); ++n )
-      alphaRanksToRecvFrom[ static_cast< mpi::MPIRank >(*n) ] = mpi::BufferSizeTrait<double>::size;
+   for(uint_t n : neighborhood)
+      alphaRanksToRecvFrom[ static_cast< mpi::MPIRank >(n) ] = mpi::BufferSizeTrait<double>::size;
 
    mpi::BufferSystem alphaBufferSystem( MPIManager::instance()->comm(), 1708 ); // dynamicdiffusion = 100 121 110 097 109 105 099 100 105 102 102 117 115 105 111 110
    alphaBufferSystem.setReceiverInfo( alphaRanksToRecvFrom );
@@ -270,15 +268,15 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
    // calculate flow for every edge (process-process connection) for every level
    
    std::map< mpi::MPIRank, mpi::MPISize > ranksToRecvFrom;
-   for( auto n = neighborhood.begin(); n != neighborhood.end(); ++n )
-      ranksToRecvFrom[ static_cast< mpi::MPIRank >(*n) ] = numeric_cast< mpi::MPISize >( levelsToProcess * mpi::BufferSizeTrait<double>::size );
+   for(uint_t n : neighborhood)
+      ranksToRecvFrom[ static_cast< mpi::MPIRank >(n) ] = numeric_cast< mpi::MPISize >( levelsToProcess * mpi::BufferSizeTrait<double>::size );
 
    mpi::BufferSystem bufferSystem( MPIManager::instance()->comm(), 1709 ); // dynamicdiffusion = 100 121 110 097 109 105 099 100 105 102 102 117 115 105 111 110 + 1
    bufferSystem.setReceiverInfo( ranksToRecvFrom );
 
    std::map< uint_t, std::vector< double > > flow; //process rank -> flow on every level
-   for( auto n = neighborhood.begin(); n != neighborhood.end(); ++n )
-      flow[*n].resize( levels, 0.0 );
+   for(uint_t n : neighborhood)
+      flow[n].resize( levels, 0.0 );
    
    std::vector< double > localWeight( processWeight ); //per level
    
@@ -291,10 +289,10 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
    {
       WALBERLA_ASSERT_EQUAL( localWeight.size(), levels );
 
-      for( auto rank = ranksToRecvFrom.begin(); rank != ranksToRecvFrom.end(); ++rank )
+      for(auto & rank : ranksToRecvFrom)
          for( uint_t l = uint_t(0); l < levels; ++l )
             if( processLevel[l] )
-               bufferSystem.sendBuffer( rank->first ) << localWeight[l];
+               bufferSystem.sendBuffer( rank.first ) << localWeight[l];
       
       bufferSystem.sendAll();
       
@@ -323,26 +321,26 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
       }
    }
    
-   for( auto it = targetProcess.begin(); it != targetProcess.end(); ++it )
-      it->second = blockforest.getProcess();
+   for(auto & targetProces : targetProcess)
+      targetProces.second = blockforest.getProcess();
    
    if( mode_ == DIFFUSION_PUSH || ( mode_ == DIFFUSION_PUSHPULL && (iteration & uint_t(1)) == uint_t(0) ) )  // sending processes decide which blocks are exchanged
    {      
       // calculate accumulated outflow for every level
       
       std::vector< double > outflow( levels, 0.0 );
-      for( auto it = flow.begin(); it != flow.end(); ++it )
+      for(auto & it : flow)
          for( uint_t l = uint_t(0); l < levels; ++l )
-            outflow[l] += std::max( it->second[l], 0.0 );
+            outflow[l] += std::max( it.second[l], 0.0 );
       
       // use global information to adapt outflow
       
       if( adaptOutflowWithGlobalInformation_ )
       {
          std::vector< double > inflow( levels, 0.0 );
-         for( auto it = flow.begin(); it != flow.end(); ++it )
+         for(auto & it : flow)
             for( uint_t l = uint_t(0); l < levels; ++l )
-               inflow[l] += std::min( it->second[l], 0.0 );
+               inflow[l] += std::min( it.second[l], 0.0 );
 
          std::vector< double > flowScaleFactor( levels, 1.0 );
          for( uint_t l = uint_t(0); l < levels; ++l )
@@ -369,10 +367,10 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
             }
          }
 
-         for( auto it = flow.begin(); it != flow.end(); ++it )
+         for(auto & it : flow)
             for( uint_t l = uint_t(0); l < levels; ++l )
-               if( it->second[l] > 0.0 )
-                  it->second[l] *= flowScaleFactor[l];
+               if( it.second[l] > 0.0 )
+                  it.second[l] *= flowScaleFactor[l];
       }
       
       // determine which blocks are send to which process
@@ -472,14 +470,14 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
                      }
                   }
                   std::set< uint_t > assigned;
-                  for( auto type = connectionType.begin(); type != connectionType.end(); ++type )
+                  for(auto & type : connectionType)
                   {
-                     for( auto index = type->begin(); index != type->end(); ++index )
+                     for(uint_t index : type)
                      {
-                        if( assigned.find(*index) == assigned.end() )
+                        if( assigned.find(index) == assigned.end() )
                         {
-                           candidates.push_back(*index); // -> this order leads to a prioritization of face over edge over corner connections (if everything else is equal)
-                           assigned.insert(*index);
+                           candidates.push_back(index); // -> this order leads to a prioritization of face over edge over corner connections (if everything else is equal)
+                           assigned.insert(index);
                         }
                      }
                   }
@@ -559,11 +557,11 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
 
                // only blocks that do not exceed the entire process outflow are viable candidates
                std::vector< uint_t > viableCandidates;
-               for( auto candidate = candidates.begin(); candidate != candidates.end(); ++candidate )
+               for(uint_t & candidate : candidates)
                {
-                  if( weight( targetProcess[ *candidate ].first ) <= ( outflowExcess + outflow[l] ) ) // ( outflowExceedFactor_ * outflow[l] ) )
+                  if( weight( targetProcess[ candidate ].first ) <= ( outflowExcess + outflow[l] ) ) // ( outflowExceedFactor_ * outflow[l] ) )
                   {
-                     viableCandidates.push_back( *candidate );
+                     viableCandidates.push_back( candidate );
                   }
                }
 
@@ -607,18 +605,18 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
       // calculate accumulated inflow for every level
       
       std::vector< double > inflow( levels, 0.0 ); // inflow is saved as a positive number!
-      for( auto it = flow.begin(); it != flow.end(); ++it )
+      for(auto & it : flow)
          for( uint_t l = uint_t(0); l < levels; ++l )
-            inflow[l] -= std::min( it->second[l], 0.0 );
+            inflow[l] -= std::min( it.second[l], 0.0 );
       
       // use global information to adapt inflow
       
       if( adaptInflowWithGlobalInformation_ )
       {
          std::vector< double > outflow( levels, 0.0 );
-         for( auto it = flow.begin(); it != flow.end(); ++it )
+         for(auto & it : flow)
             for( uint_t l = uint_t(0); l < levels; ++l )
-               outflow[l] += std::max( it->second[l], 0.0 );
+               outflow[l] += std::max( it.second[l], 0.0 );
 
          std::vector< double > flowScaleFactor( levels, 1.0 );
          for( uint_t l = uint_t(0); l < levels; ++l )
@@ -636,10 +634,10 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
             }
          }
 
-         for( auto it = flow.begin(); it != flow.end(); ++it )
+         for(auto & it : flow)
             for( uint_t l = uint_t(0); l < levels; ++l )
-               if( it->second[l] < 0.0 )
-                  it->second[l] *= flowScaleFactor[l];
+               if( it.second[l] < 0.0 )
+                  it.second[l] *= flowScaleFactor[l];
       }
       
       // determine blocks with connections to neighbors processes, sort these blocks by their connection type, and
@@ -649,11 +647,11 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
       std::vector< std::vector< uint_t > > blocksConnectedToOtherProcesses; // sorted by level
       std::vector< std::vector< uint_t > > allBlocks; // sorted by level
       
-      for( auto n = neighborhood.begin(); n != neighborhood.end(); ++n )
+      for(uint_t n : neighborhood)
       {
-         blocksForNeighbors[*n].resize( levels );
+         blocksForNeighbors[n].resize( levels );
          for( uint_t l = uint_t(0); l < levels; ++l )
-            blocksForNeighbors[*n][l].resize( 8 ); // 0 = full face (same level), 1 = full face (different level), 2 = part face,
+            blocksForNeighbors[n][l].resize( 8 ); // 0 = full face (same level), 1 = full face (different level), 2 = part face,
                                                    // 3 = full edge (same level), 4 = full edge (different level), 5 = part edge,
                                                    // 6 = corner (same level), 7 = corner (different level)
       }
@@ -750,32 +748,32 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
                if( regardConnectivity_ && iteration < disregardConnectivityStart_ )
                {
                   std::set< uint_t > assigned;
-                  for( auto type = it->second[l].begin(); type != it->second[l].end(); ++type )
+                  for(auto & type : it->second[l])
                   {
-                     for( auto index = type->begin(); index != type->end(); ++index )
+                     for(uint_t index : type)
                      {
-                        if( assigned.find(*index) == assigned.end() )
+                        if( assigned.find(index) == assigned.end() )
                         {
-                           const auto * block = targetProcess[*index].first;
+                           const auto * block = targetProcess[index].first;
                            blocksForNeighborsUnsorted[np].push_back( std::make_pair( block->getId(), weight(block) ) ); // -> this order leads to a prioritization of face over edge over corner connections
-                           assigned.insert(*index);
+                           assigned.insert(index);
                         }
                      }
                   }
-                  for( auto index = blocksConnectedToOtherProcesses[l].begin(); index != blocksConnectedToOtherProcesses[l].end(); ++index )
+                  for(uint_t & index : blocksConnectedToOtherProcesses[l])
                   {
-                     if( assigned.find(*index) == assigned.end() )
+                     if( assigned.find(index) == assigned.end() )
                      {
-                        const auto * block = targetProcess[*index].first;
+                        const auto * block = targetProcess[index].first;
                         blocksForNeighborsUnsorted[np].push_back( std::make_pair( block->getId(), weight(block) ) );
-                        assigned.insert(*index);
+                        assigned.insert(index);
                      }
                   }
-                  for( auto index = allBlocks[l].begin(); index != allBlocks[l].end(); ++index )
+                  for(uint_t & index : allBlocks[l])
                   {
-                     if( assigned.find(*index) == assigned.end() )
+                     if( assigned.find(index) == assigned.end() )
                      {
-                        const auto * block = targetProcess[*index].first;
+                        const auto * block = targetProcess[index].first;
                         blocksForNeighborsUnsorted[np].push_back( std::make_pair( block->getId(), weight(block) ) );
                      }
                   }
@@ -783,8 +781,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
                else
                {
                   std::vector< uint_t > blocksToPick;
-                  for( auto index = allBlocks[l].begin(); index != allBlocks[l].end(); ++index )
-                     blocksToPick.push_back( *index );
+                  for(uint_t & index : allBlocks[l])
+                     blocksToPick.push_back( index );
                   while( ! blocksToPick.empty() )
                   {
                      const uint_t pickedBlock = random_( uint_t(0), uint_c( blocksToPick.size() ) - uint_t(1) );
@@ -807,14 +805,14 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
       }
 
       std::set< mpi::MPIRank > neighborsToRecvFrom;
-      for( auto n = neighborhood.begin(); n != neighborhood.end(); ++n )
-         neighborsToRecvFrom.insert( static_cast< mpi::MPIRank >(*n) );
+      for(uint_t n : neighborhood)
+         neighborsToRecvFrom.insert( static_cast< mpi::MPIRank >(n) );
 
       mpi::BufferSystem neighborsBufferSystem( MPIManager::instance()->comm(), 1710 ); // dynamicdiffusion = 100 121 110 097 109 105 099 100 105 102 102 117 115 105 111 110 + 2
       neighborsBufferSystem.setReceiverInfo( neighborsToRecvFrom, true );
       
-      for( auto rank = neighborsToRecvFrom.begin(); rank != neighborsToRecvFrom.end(); ++rank )
-         neighborsBufferSystem.sendBuffer( *rank ) << blocksForNeighborsUnsorted[ uint_c( *rank ) ];
+      for(mpi::MPIRank rank : neighborsToRecvFrom)
+         neighborsBufferSystem.sendBuffer( rank ) << blocksForNeighborsUnsorted[ uint_c( rank ) ];
       
       neighborsBufferSystem.sendAll();
       
@@ -877,11 +875,11 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
       
                // only blocks that do not exceed the entire process inflow are viable candidates
                std::vector< std::pair< BlockID, double > > viableCandidates;
-               for( auto candidate = candidates.begin(); candidate != candidates.end(); ++candidate )
+               for(const auto & candidate : candidates)
                {
-                  if( pickedBlocks.find( candidate->first ) == pickedBlocks.end() && candidate->second <= ( inflowExcess + inflow[l] ) )
+                  if( pickedBlocks.find( candidate.first ) == pickedBlocks.end() && candidate.second <= ( inflowExcess + inflow[l] ) )
                   {
-                     viableCandidates.push_back( *candidate );
+                     viableCandidates.push_back( candidate );
                   }
                }
 
@@ -922,8 +920,8 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
       
       // tell neighbors about blocks we want to fetch
       
-      for( auto rank = neighborsToRecvFrom.begin(); rank != neighborsToRecvFrom.end(); ++rank )
-         neighborsBufferSystem.sendBuffer( *rank ) << blocksToFetch[ uint_c( *rank ) ];
+      for(mpi::MPIRank rank : neighborsToRecvFrom)
+         neighborsBufferSystem.sendBuffer( rank ) << blocksToFetch[ uint_c( rank ) ];
       
       neighborsBufferSystem.sendAll();
       
@@ -939,11 +937,11 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
       
       std::map< BlockID, std::vector< uint_t > > processToSendTo;
       
-      for( auto it = blocksToSend.begin(); it != blocksToSend.end(); ++it )
+      for(auto & it : blocksToSend)
       {
-         const uint_t p = it->first;
-         for( auto id = it->second.begin(); id != it->second.end(); ++id )
-            processToSendTo[ *id ].push_back( p );
+         const uint_t p = it.first;
+         for(auto & id : it.second)
+            processToSendTo[ id ].push_back( p );
       }
       
       for( auto it = processToSendTo.begin(); it != processToSendTo.end(); ++it )
@@ -972,16 +970,16 @@ bool DynamicDiffusionBalance< PhantomData_T >::operator()( std::vector< std::pai
    // synchronize with neighbors if blocks are exchanged
 
    std::map< uint_t, uint8_t > sendBlocksToNeighbor;
-   for( auto n = neighborhood.begin(); n != neighborhood.end(); ++n )
-      sendBlocksToNeighbor[*n] = uint8_t(0);
+   for(uint_t n : neighborhood)
+      sendBlocksToNeighbor[n] = uint8_t(0);
 
-   for( auto it = targetProcess.begin(); it != targetProcess.end(); ++it )
-      if( it->second != blockforest.getProcess() )
-         sendBlocksToNeighbor[ it->second ] = uint8_t(1);
+   for(auto & targetProces : targetProcess)
+      if( targetProces.second != blockforest.getProcess() )
+         sendBlocksToNeighbor[ targetProces.second ] = uint8_t(1);
 
    std::map< mpi::MPIRank, mpi::MPISize > blocksRanksToRecvFrom;
-   for( auto n = neighborhood.begin(); n != neighborhood.end(); ++n )
-      blocksRanksToRecvFrom[ static_cast< mpi::MPIRank >(*n) ] = mpi::BufferSizeTrait<uint8_t>::size;
+   for(uint_t n : neighborhood)
+      blocksRanksToRecvFrom[ static_cast< mpi::MPIRank >(n) ] = mpi::BufferSizeTrait<uint8_t>::size;
 
    mpi::BufferSystem blocksBufferSystem( MPIManager::instance()->comm(), 1711 ); // dynamicdiffusion = 100 121 110 097 109 105 099 100 105 102 102 117 115 105 111 110 + 3
    blocksBufferSystem.setReceiverInfo( blocksRanksToRecvFrom );
diff --git a/src/blockforest/loadbalancing/DynamicParMetis.cpp b/src/blockforest/loadbalancing/DynamicParMetis.cpp
index 062ce75851ef4d9f7eb36cae9a23e0383b2ebf3e..b66677352752744c43878be2ebf7feb70d56fc3e 100644
--- a/src/blockforest/loadbalancing/DynamicParMetis.cpp
+++ b/src/blockforest/loadbalancing/DynamicParMetis.cpp
@@ -64,17 +64,17 @@ std::map< blockforest::BlockID, uint_t > getBlockIdToSequenceMapping( const Phan
    std::map< blockforest::BlockID, uint_t > mapping;
 
    uint_t sequenceId = blockSequenceRange.first;
-   for( auto it = targetProcess.begin(); it != targetProcess.end(); ++it )
-      mapping.insert( std::make_pair( it->first->getId(), sequenceId++ ) );
+   for(const auto & targetProces : targetProcess)
+      mapping.insert( std::make_pair( targetProces.first->getId(), sequenceId++ ) );
    WALBERLA_ASSERT_EQUAL( sequenceId, blockSequenceRange.second );
 
    const std::vector<uint_t>& neighborProcesses = phantomForest.getNeighboringProcesses();
    
    mpi::BufferSystem bs( comm );
 
-   for( auto it = neighborProcesses.begin(); it != neighborProcesses.end(); ++it )
+   for(uint_t neighborProcesse : neighborProcesses)
    {
-      auto destRank = mpi::translateRank(mpi::MPIManager::instance()->comm(), comm, int_c(*it));
+      auto destRank = mpi::translateRank(mpi::MPIManager::instance()->comm(), comm, int_c(neighborProcesse));
       if (destRank != -1)
          bs.sendBuffer( destRank ) << mapping;
    }
@@ -88,9 +88,9 @@ std::map< blockforest::BlockID, uint_t > getBlockIdToSequenceMapping( const Phan
       std::map< blockforest::BlockID, uint_t > remoteMapping;
       it.buffer() >> remoteMapping;
 
-      for( auto remoteIt = remoteMapping.begin(); remoteIt != remoteMapping.end(); ++remoteIt )
+      for(auto & remoteIt : remoteMapping)
       {
-         auto result = mapping.insert( *remoteIt );
+         auto result = mapping.insert( remoteIt );
          WALBERLA_UNUSED( result );
          WALBERLA_ASSERT( result.second, "BlockId should be unique!" );
       }
@@ -164,14 +164,14 @@ bool DynamicParMetis::operator()( std::vector< std::pair< const PhantomBlock *,
          switch( edgeSource_ )
          {
          case PARMETIS_EDGES_FROM_FOREST:
-            for( auto nit = block.getNeighborhood().begin(); nit != block.getNeighborhood().end(); ++nit )
+            for(const auto & nit : block.getNeighborhood())
             {
-               auto mapIt = mapping.find( nit->getId() );
+               auto mapIt = mapping.find( nit.getId() );
                WALBERLA_ASSERT_UNEQUAL( mapIt, mapping.end(), "BlockId of neighbor is not contained in sequence mapping!" );
                WALBERLA_CHECK_GREATER_EQUAL( mapIt->second, 0 );
                WALBERLA_CHECK_LESS( mapIt->second, vtxdist.back() );
                adjncy.push_back( int64_c( mapIt->second ) );
-               auto edgeWeightIt = bi.getEdgeWeights().find( nit->getId() );
+               auto edgeWeightIt = bi.getEdgeWeights().find( nit.getId() );
                WALBERLA_CHECK_GREATER_EQUAL( edgeWeightIt->second, 0 );
                adjwgt.push_back( edgeWeightIt == bi.getEdgeWeights().end() ? int64_t( 1 ) : edgeWeightIt->second );
             }
@@ -269,11 +269,11 @@ bool DynamicParMetis::operator()( std::vector< std::pair< const PhantomBlock *,
 
    // Determine which processes will receive a block from this process
    std::vector<uint8_t> isSendingBlockToProcess( uint_c(MPIManager::instance()->numProcesses()), uint8_t( 0 ) );
-   for( auto it = part.begin(); it != part.end(); ++it )
+   for( auto proc : part )
    {
-      WALBERLA_ASSERT_GREATER_EQUAL( *it, 0 );
-      WALBERLA_ASSERT_LESS( *it, MPIManager::instance()->numProcesses() );
-      isSendingBlockToProcess[uint_c(*it)] = uint8_t( 1 );
+      WALBERLA_ASSERT_GREATER_EQUAL( proc, 0 );
+      WALBERLA_ASSERT_LESS( proc, MPIManager::instance()->numProcesses() );
+      isSendingBlockToProcess[uint_c(proc)] = uint8_t( 1 );
    }
    isSendingBlockToProcess[uint_c(MPIManager::instance()->rank())] = uint8_t( 0 );
 
diff --git a/src/blockforest/loadbalancing/StaticCurve.cpp b/src/blockforest/loadbalancing/StaticCurve.cpp
index e90ec3bc10ac72a04ebbfe9ce6609552c4276158..7d6ddc15ba9ffe7469c171fa602cb32891c378b5 100644
--- a/src/blockforest/loadbalancing/StaticCurve.cpp
+++ b/src/blockforest/loadbalancing/StaticCurve.cpp
@@ -46,16 +46,16 @@ uint_t StaticLevelwiseCurveBalance::operator()( SetupBlockForest & forest, const
    {
       std::vector< SetupBlock * > blocksOnLevel;
 
-      for( auto block = blocks.begin(); block != blocks.end(); ++block )
-         if( (*block)->getLevel() == level )
-            blocksOnLevel.push_back( *block );
+      for(auto & block : blocks)
+         if( block->getLevel() == level )
+            blocksOnLevel.push_back( block );
 
       const uint_t nBlocks = blocksOnLevel.size();
 
       if( nBlocks <= ( numberOfProcesses - border ) )
       {
-         for( auto block = blocksOnLevel.begin(); block != blocksOnLevel.end(); ++block )
-            (*block)->assignTargetProcess( border++ );
+         for(auto & block : blocksOnLevel)
+            block->assignTargetProcess( border++ );
 
          WALBERLA_ASSERT_LESS_EQUAL( border, numberOfProcesses );
 
@@ -107,15 +107,15 @@ uint_t StaticLevelwiseCurveBalanceWeighted::operator()( SetupBlockForest & fores
    {
       std::vector< SetupBlock * > blocksOnLevel;
 
-      for( auto block = blocks.begin(); block != blocks.end(); ++block )
-         if( (*block)->getLevel() == level )
-            blocksOnLevel.push_back( *block );
+      for(auto & block : blocks)
+         if( block->getLevel() == level )
+            blocksOnLevel.push_back( block );
 
       workload_t totalWeight( 0 );
-      for( auto block = blocksOnLevel.begin(); block != blocksOnLevel.end(); ++block )
+      for(auto & block : blocksOnLevel)
       {
-         WALBERLA_ASSERT( !( (*block)->getWorkload() < workload_t(0) ) );
-         totalWeight += (*block)->getWorkload();
+         WALBERLA_ASSERT( !( block->getWorkload() < workload_t(0) ) );
+         totalWeight += block->getWorkload();
       }
 
       uint_t c( uint_t(0) );
diff --git a/src/blockforest/loadbalancing/StaticParMetis.cpp b/src/blockforest/loadbalancing/StaticParMetis.cpp
index c712bab5971dcda1afb3588afb7cea487c3107ca..c68f6430c050741fa1f9959b58c2aef9e367dd00 100644
--- a/src/blockforest/loadbalancing/StaticParMetis.cpp
+++ b/src/blockforest/loadbalancing/StaticParMetis.cpp
@@ -108,16 +108,16 @@ uint_t StaticLevelwiseParMetis::operator()( SetupBlockForest & forest, const uin
          xadj.push_back( int64_c( adjncy.size() ) );
 
 
-         for( auto nit = block.getNeighborhood().begin(); nit != block.getNeighborhood().end(); ++nit )
+         for(auto nit : block.getNeighborhood())
          {
-            if( (*nit)->getLevel() != level )
+            if( nit->getLevel() != level )
                continue; // ignore neighbor blocks on other levels
 
-            adjncy.push_back( int64_c( (*nit)->getIndex() ) );
+            adjncy.push_back( int64_c( nit->getIndex() ) );
 
             if(weightsToUse_ == PARMETIS_EDGE_WEIGHTS || weightsToUse_ == PARMETIS_BOTH_WEIGHTS)
             {
-               blockPairs.emplace_back( blocks[i], *nit );
+               blockPairs.emplace_back( blocks[i], nit );
             }
          }
 
@@ -151,11 +151,11 @@ uint_t StaticLevelwiseParMetis::operator()( SetupBlockForest & forest, const uin
       int64_t numflag = 0; // C-style ordering
       int64_t ncon = 1; // Number of constraints
       int64_t ndims = 3; // Number of dimensions
-      double ubvec[] = { real_t( 1.05 ) }; // imbalance tolerance
+      std::array< double, 1 > ubvec = { real_t( 1.05 ) }; // imbalance tolerance
       int64_t nparts = int64_c( numberOfProcesses ); // number of subdomains
       MPI_Comm comm = MPIManager::instance()->comm();
       std::vector<double> tpwgts( uint_c(nparts * ncon), 1.0 / double_c( nparts ) ); // vertex weight fraction that is stored in a subdomain
-      int64_t options[] = { int64_t( 1 ), int64_t( 0 ), int64_t( 23 ), int64_t( 1 ) };
+      std::array< int64_t, 4 > options = { int64_t( 1 ), int64_t( 0 ), int64_t( 23 ), int64_t( 1 ) };
 
       // add dummy element to circumvent null pointer check if less blocks than processes
       adjncy.resize( std::max( adjncy.size(), size_t(1) ) );
@@ -169,12 +169,12 @@ uint_t StaticLevelwiseParMetis::operator()( SetupBlockForest & forest, const uin
       {
       case PARMETIS_PART_GEOM_KWAY:
          parmetisTimer.start();
-         metisResult = core::ParMETIS_V3_PartGeomKway( ptr( vtxdist ), ptr( xadj ), ptr( adjncy ), ptr( vwgt ), ptr( adjwgt ), &wgtflag, &numflag, &ndims, ptr( xyz ), &ncon, &nparts, ptr( tpwgts ), ubvec, options, &edgecut, ptr( part ), &comm );
+         metisResult = core::ParMETIS_V3_PartGeomKway( ptr( vtxdist ), ptr( xadj ), ptr( adjncy ), ptr( vwgt ), ptr( adjwgt ), &wgtflag, &numflag, &ndims, ptr( xyz ), &ncon, &nparts, ptr( tpwgts ), ubvec.data(), options.data(), &edgecut, ptr( part ), &comm );
          parmetisTimer.end();
          break;
       case PARMETIS_PART_KWAY:
          parmetisTimer.start();
-         metisResult = core::ParMETIS_V3_PartKway( ptr( vtxdist ), ptr( xadj ), ptr( adjncy ), ptr( vwgt ), ptr( adjwgt ), &wgtflag, &numflag, &ncon, &nparts, ptr( tpwgts ), ubvec, options, &edgecut, ptr( part ), &comm );
+         metisResult = core::ParMETIS_V3_PartKway( ptr( vtxdist ), ptr( xadj ), ptr( adjncy ), ptr( vwgt ), ptr( adjwgt ), &wgtflag, &numflag, &ncon, &nparts, ptr( tpwgts ), ubvec.data(), options.data(), &edgecut, ptr( part ), &comm );
          parmetisTimer.end();
          break;
       }
@@ -197,9 +197,9 @@ uint_t StaticLevelwiseParMetis::operator()( SetupBlockForest & forest, const uin
 
    //count number of used processes
    std::vector<bool> processUsed( numberOfProcesses, false );
-   for(auto blockIt = forest.begin(); blockIt != forest.end(); ++blockIt)
+   for(auto & blockIt : forest)
    {
-      processUsed[ blockIt->getTargetProcess() ] = true;
+      processUsed[ blockIt.getTargetProcess() ] = true;
    }
 
    return uint_c(std::count( processUsed.begin(), processUsed.end(), true ));
diff --git a/src/blockforest/loadbalancing/level_determination/MinMaxLevelDetermination.cpp b/src/blockforest/loadbalancing/level_determination/MinMaxLevelDetermination.cpp
index f301fb84480776edd84c2b6894a8d62a1e8582ab..445551c91f396b80ba5a0e574739abf5362759e5 100644
--- a/src/blockforest/loadbalancing/level_determination/MinMaxLevelDetermination.cpp
+++ b/src/blockforest/loadbalancing/level_determination/MinMaxLevelDetermination.cpp
@@ -29,26 +29,26 @@ void MinMaxLevelDetermination::operator()( std::vector< std::pair< const Block *
                                            std::vector< const Block * > &,
                                            const BlockForest & /*forest*/ )
 {
-   for( auto it = minTargetLevels.begin(); it != minTargetLevels.end(); ++it )
+   for(auto & minTargetLevel : minTargetLevels)
    {
-      const auto infoIt = ic_->find(it->first->getId());
+      const auto infoIt = ic_->find(minTargetLevel.first->getId());
       WALBERLA_ASSERT_UNEQUAL( infoIt, ic_->end() );
 
-      it->second = it->first->getLevel(); //keep everything as it is
+      minTargetLevel.second = minTargetLevel.first->getLevel(); //keep everything as it is
 
       //check for refinement
       if (infoIt->second.computationalWeight > maxBodies_)
       {
-         it->second = it->first->getLevel() + uint_t(1);
+         minTargetLevel.second = minTargetLevel.first->getLevel() + uint_t(1);
          continue;
       }
 
       //check for coarsening
-      if ((it->first->getLevel() > 0) && (infoIt->second.computationalWeight < minBodies_))
+      if ((minTargetLevel.first->getLevel() > 0) && (infoIt->second.computationalWeight < minBodies_))
       {
-         if (getOrCreateCoarseInfo(it->first->getId())->second.computationalWeight < maxBodies_)
+         if (getOrCreateCoarseInfo(minTargetLevel.first->getId())->second.computationalWeight < maxBodies_)
          {
-            it->second = it->first->getLevel() - uint_t(1);
+            minTargetLevel.second = minTargetLevel.first->getLevel() - uint_t(1);
          }
          continue;
       }
diff --git a/src/blockforest/loadbalancing/weight_assignment/MetisAssignmentFunctor.h b/src/blockforest/loadbalancing/weight_assignment/MetisAssignmentFunctor.h
index 6e4d062a84daff6b3c054ccd6a861e75b455e451..cf2540335981ab5fec3da7341939352ca645140e 100644
--- a/src/blockforest/loadbalancing/weight_assignment/MetisAssignmentFunctor.h
+++ b/src/blockforest/loadbalancing/weight_assignment/MetisAssignmentFunctor.h
@@ -53,9 +53,9 @@ public:
                   forest.getBlockForest().isPeriodic(2)}};
       const math::AABB domain     = forest.getBlockForest().getDomain();
 
-      for( auto it = blockData.begin(); it != blockData.end(); ++it )
+      for(auto & it : blockData)
       {
-         const PhantomBlock * block = it->first;
+         const PhantomBlock * block = it.first;
          //only change of one level is supported!
          WALBERLA_ASSERT_LESS( abs(int_c(block->getLevel()) - int_c(block->getSourceLevel())), 2 );
 
@@ -66,19 +66,18 @@ public:
          blockforest::DynamicParMetisBlockInfo info( 0 );
          info.setVertexWeight( int64_c(weight) );
          info.setVertexSize( int64_c( weight ) );
-         info.setVertexCoords( it->first->getAABB().center() );
-         for( uint_t nb = uint_t(0); nb < it->first->getNeighborhoodSize(); ++nb )
+         info.setVertexCoords( it.first->getAABB().center() );
+         for( uint_t nb = uint_t(0); nb < it.first->getNeighborhoodSize(); ++nb )
          {
             const real_t dx(1.0);
-            info.setEdgeWeight( it->first->getNeighborId(nb),
+            info.setEdgeWeight( it.first->getNeighborId(nb),
                                 static_cast<blockforest::DynamicParMetisBlockInfo::weight_t>(
                                 domain_decomposition::periodicIntersectionVolume( periodic,
                                                                                   domain,
-                                                                                  it->first->getAABB(),
-                                                                                  it->first->getNeighborAABB(nb).getExtended(dx))) );
+                                                                                  it.first->getAABB(),
+                                                                                  it.first->getNeighborAABB(nb).getExtended(dx))) );
          }
-         it->second = info;
-         continue;
+         it.second = info;
       }
    }
 
diff --git a/src/blockforest/loadbalancing/weight_assignment/WeightAssignmentFunctor.h b/src/blockforest/loadbalancing/weight_assignment/WeightAssignmentFunctor.h
index 2fdec3bed1c2cb6ae4f056873f692cc9fcb42b59..cbde2883b01eedc59d6d806390e099a47fda58da 100644
--- a/src/blockforest/loadbalancing/weight_assignment/WeightAssignmentFunctor.h
+++ b/src/blockforest/loadbalancing/weight_assignment/WeightAssignmentFunctor.h
@@ -45,15 +45,15 @@ public:
 
    void operator()( std::vector< std::pair< const PhantomBlock *, walberla::any > > & blockData, const PhantomBlockForest & )
    {
-      for( auto it = blockData.begin(); it != blockData.end(); ++it )
+      for(auto & it : blockData)
       {
-         const PhantomBlock * block = it->first;
+         const PhantomBlock * block = it.first;
          //only change of one level is supported!
          WALBERLA_CHECK_LESS( abs(int_c(block->getLevel()) - int_c(block->getSourceLevel())), 2 );
 
          auto infoIt = ic_->find( block->getId()/*.getFatherId()*/ );
          WALBERLA_CHECK_UNEQUAL( infoIt, ic_->end() );
-         it->second = PhantomBlockWeight( double_c(infoIt->second.computationalWeight) + baseWeight_ );
+         it.second = PhantomBlockWeight( double_c(infoIt->second.computationalWeight) + baseWeight_ );
       }
    }
 
diff --git a/src/boundary/Boundary.h b/src/boundary/Boundary.h
index 24b74f64383c24f5386a0b45935dd87f25169ec1..39ed5d478a465a24300d37b235ad64ff0beea054 100644
--- a/src/boundary/Boundary.h
+++ b/src/boundary/Boundary.h
@@ -117,11 +117,11 @@ template< typename flag_t >
 class Boundary {
 public:
 
-   static_assert( std::is_unsigned<flag_t>::value, "You are trying to instantiate walberla::boundary::Boundary with "
+   static_assert( std::is_unsigned_v<flag_t>, "You are trying to instantiate walberla::boundary::Boundary with "
                                                      "a flag_t which is not an unsigned integer!" );
 
 #ifndef NDEBUG
-   Boundary( const BoundaryUID & boundaryUID ) : boundaryUID_( boundaryUID ), mask_(0), maskSet_(false) {}
+   Boundary( const BoundaryUID & boundaryUID ) : boundaryUID_( boundaryUID ), mask_(0) {}
 
    void   setMask( const flag_t mask ) { WALBERLA_ASSERT( !maskSet_ ); mask_ = mask; maskSet_ = true; } // called by BoundaryHandler
    flag_t getMask() const { WALBERLA_ASSERT( maskSet_ ); return mask_; }
@@ -142,7 +142,7 @@ protected:
                  // If part of this mask is set for a specific cell, this boundary class/condition is responsible for the corresponding boundary treatment.
 
 #ifndef NDEBUG
-   bool maskSet_; // only used in debug mode!
+   bool maskSet_{false}; // only used in debug mode!
 #endif
 
 }; // class Boundary
@@ -156,7 +156,7 @@ struct isThreadSafe
 };
 
 template< typename Boundary_T >
-struct isThreadSafe< Boundary_T, typename std::enable_if< Boundary_T::threadsafe >::type >
+struct isThreadSafe< Boundary_T, typename std::enable_if_t< Boundary_T::threadsafe > >
 {
    static const bool value = Boundary_T::threadsafe;
 };
diff --git a/src/boundary/BoundaryHandling.h b/src/boundary/BoundaryHandling.h
index a3bff17631f979719fe1354c0a00b2b8c75f8b23..28a074e980da3257981323286050ed13521935a1 100644
--- a/src/boundary/BoundaryHandling.h
+++ b/src/boundary/BoundaryHandling.h
@@ -52,11 +52,11 @@ namespace boundary {
 namespace internal {
 #if defined(__GLIBCXX__) && (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE < 7)
 template< typename T >
-struct tuple_size : std::tuple_size<std::tuple<>>
+struct tuple_size : std::tuple_size_v<std::tuple<>>
 {};
 
 template< typename... Members >
-struct tuple_size< std::tuple<Members...> > : std::tuple_size<std::tuple<Members...>>
+struct tuple_size_v< std::tuple<Members...> > : std::tuple_size_v<std::tuple<Members...>>
 {};
 #else
 using std::tuple_size;
@@ -380,31 +380,31 @@ private:
 
    CellInterval getGhostLayerCellInterval( const uint_t numberOfGhostLayersToInclude ) const;
 
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   typename std::enable_if<(N!=-1), void>::type setupBoundaryConditions(       BoundariesTuple & boundaryConditions );
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1  >
-   typename std::enable_if<(N==-1), void>::type setupBoundaryConditions( const BoundariesTuple & ) const {}
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   typename std::enable_if_t<(N!=-1), void> setupBoundaryConditions(       BoundariesTuple & boundaryConditions );
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1  >
+   typename std::enable_if_t<(N==-1), void> setupBoundaryConditions( const BoundariesTuple & ) const {}
 
    inline std::vector< BoundaryUID > getBoundaryUIDs() const;
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type getBoundaryUIDs( const BoundariesTuple & boundaryConditions, std::vector< BoundaryUID > & uids ) const;
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type getBoundaryUIDs( const BoundariesTuple &, std::vector< BoundaryUID > & ) const {}
-
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), BoundaryUID>::type getBoundaryUID( const BoundariesTuple & boundaryConditions, const flag_t flag ) const;
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), BoundaryUID>::type getBoundaryUID( const BoundariesTuple &, const flag_t flagUID ) const;
-
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), bool>::type containsBoundaryCondition( const BoundariesTuple & boundaryConditions, const BoundaryUID & uid ) const;
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), bool>::type containsBoundaryCondition( const BoundariesTuple &, const BoundaryUID & ) const { return false; }
-
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), flag_t>::type getBoundaryMask( const BoundariesTuple & boundaryConditions, const BoundaryUID & uid ) const;
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), flag_t>::type getBoundaryMask( const BoundariesTuple &, const BoundaryUID & ) const { return numeric_cast<flag_t>(0); }
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), void> getBoundaryUIDs( const BoundariesTuple & boundaryConditions, std::vector< BoundaryUID > & uids ) const;
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), void> getBoundaryUIDs( const BoundariesTuple &, std::vector< BoundaryUID > & ) const {}
+
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), BoundaryUID> getBoundaryUID( const BoundariesTuple & boundaryConditions, const flag_t flag ) const;
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), BoundaryUID> getBoundaryUID( const BoundariesTuple &, const flag_t flagUID ) const;
+
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), bool> containsBoundaryCondition( const BoundariesTuple & boundaryConditions, const BoundaryUID & uid ) const;
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), bool> containsBoundaryCondition( const BoundariesTuple &, const BoundaryUID & ) const { return false; }
+
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), flag_t> getBoundaryMask( const BoundariesTuple & boundaryConditions, const BoundaryUID & uid ) const;
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), flag_t> getBoundaryMask( const BoundariesTuple &, const BoundaryUID & ) const { return numeric_cast<flag_t>(0); }
 
    //** Get Boundary Class (private helper functions) ******************************************************************
    /*! \name Get Boundary Class (private helper functions) */
@@ -412,9 +412,9 @@ private:
 
    // matching type (-> Boundary_T) not yet found ...
 
-   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline const typename std::enable_if<(N!=0), Boundary_T>::type & getBoundaryCondition( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
-                                                   typename std::enable_if< std::is_same< Boundary_T, typename std::tuple_element<N, BoundariesTuple>::type >::value >::type* /*dummy*/ = nullptr ) const
+   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline const typename std::enable_if_t<(N!=0), Boundary_T> & getBoundaryCondition( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
+                                                   typename std::enable_if_t< std::is_same_v< Boundary_T, typename std::tuple_element_t<N, BoundariesTuple> > >* /*dummy*/ = nullptr ) const
    {
       if( uid == std::get<N>( boundaryConditions ).getUID() )
          return std::get<N>( boundaryConditions );
@@ -422,9 +422,9 @@ private:
          return getBoundaryCondition_TypeExists< Boundary_T, BoundariesTuple, N-1 >( uid, boundaryConditions );
    }
 
-   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline const typename std::enable_if<(N==0), Boundary_T>::type & getBoundaryCondition( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
-                                                   typename std::enable_if< std::is_same< Boundary_T, typename std::tuple_element<N, BoundariesTuple>::type >::value >::type* /*dummy*/ = nullptr ) const
+   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline const typename std::enable_if_t<(N==0), Boundary_T> & getBoundaryCondition( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
+                                                   typename std::enable_if_t< std::is_same_v< Boundary_T, typename std::tuple_element_t<N, BoundariesTuple> > >* /*dummy*/ = nullptr ) const
    {
       if( uid == std::get<N>( boundaryConditions ).getUID() )
          return std::get<N>( boundaryConditions );
@@ -437,27 +437,27 @@ private:
    }
 
    template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline const typename std::enable_if<(N!=0), Boundary_T>::type & getBoundaryCondition( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
-                                                   typename std::enable_if< std::is_same< typename std::is_same< Boundary_T, typename std::tuple_element<N, BoundariesTuple>::type >::type,
-                                                                                              std::false_type >::value >::type* /*dummy*/ = nullptr,
-                                                   typename std::enable_if< (N>0) >::type* /*dummy*/ = nullptr ) const
+   inline const typename std::enable_if_t<(N!=0), Boundary_T> & getBoundaryCondition( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
+                                                   typename std::enable_if_t< std::is_same_v< typename std::is_same< Boundary_T, typename std::tuple_element_t<N, BoundariesTuple> >::type,
+                                                                                              std::false_type > >* /*dummy*/ = nullptr,
+                                                   typename std::enable_if_t< (N>0) >* /*dummy*/ = nullptr ) const
    {
       return getBoundaryCondition< Boundary_T, BoundariesTuple, N-1 >( uid, boundaryConditions );
    }
 
-   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline const typename std::enable_if<(N==0), Boundary_T>::type & getBoundaryCondition( const BoundaryUID & /*uid*/, const BoundariesTuple & /*boundaryConditions*/,
-                                                   typename std::enable_if< std::is_same< typename std::is_same< Boundary_T, typename std::tuple_element<0, BoundariesTuple>::type >::type,
-                                                                                              std::false_type >::value >::type* /*dummy*/ = 0 ) const
+   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline const typename std::enable_if_t<(N==0), Boundary_T> & getBoundaryCondition( const BoundaryUID & /*uid*/, const BoundariesTuple & /*boundaryConditions*/,
+                                                   typename std::enable_if_t< std::is_same_v< typename std::is_same< Boundary_T, typename std::tuple_element_t<0, BoundariesTuple> >::type,
+                                                                                              std::false_type > >* /*dummy*/ = 0 ) const
    {
       static_assert( sizeof(Boundary_T) == 0, "The requested boundary class is not part of this boundary handling." );
    }
 
    // matching type (-> Boundary_T) exists!
 
-   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline const typename std::enable_if<(N!=0), Boundary_T>::type & getBoundaryCondition_TypeExists( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
-                                                              typename std::enable_if< std::is_same< Boundary_T, typename std::tuple_element<N, BoundariesTuple>::type >::value >::type* /*dummy*/ = nullptr ) const
+   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline const typename std::enable_if_t<(N!=0), Boundary_T> & getBoundaryCondition_TypeExists( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
+                                                              typename std::enable_if_t< std::is_same_v< Boundary_T, typename std::tuple_element_t<N, BoundariesTuple> > >* /*dummy*/ = nullptr ) const
    {
       if( uid == std::get<N>( boundaryConditions ).getUID() )
          return std::get<N>( boundaryConditions );
@@ -465,9 +465,9 @@ private:
          return getBoundaryCondition_TypeExists< Boundary_T, BoundariesTuple, N-1 >( uid, boundaryConditions );
    }
 
-   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline const typename std::enable_if<(N==0), Boundary_T>::type & getBoundaryCondition_TypeExists( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
-                                                              typename std::enable_if< std::is_same< Boundary_T, typename std::tuple_element<0, BoundariesTuple>::type >::value >::type* /*dummy*/ = 0 ) const
+   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline const typename std::enable_if_t<(N==0), Boundary_T> & getBoundaryCondition_TypeExists( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
+                                                              typename std::enable_if_t< std::is_same_v< Boundary_T, typename std::tuple_element_t<0, BoundariesTuple> > >* /*dummy*/ = 0 ) const
    {
       if( uid == std::get<0>( boundaryConditions ).getUID() )
          return std::get<0>( boundaryConditions );
@@ -479,18 +479,18 @@ private:
 #endif
    }
 
-   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline const typename std::enable_if<(N!=0), Boundary_T>::type & getBoundaryCondition_TypeExists( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
-                                                              typename std::enable_if< std::is_same< typename std::is_same< Boundary_T, typename std::tuple_element<N, BoundariesTuple>::type >::type,
-                                                                                                         std::false_type >::value >::type* /*dummy*/ = 0 ) const
+   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline const typename std::enable_if_t<(N!=0), Boundary_T> & getBoundaryCondition_TypeExists( const BoundaryUID & uid, const BoundariesTuple & boundaryConditions,
+                                                              typename std::enable_if_t< std::is_same_v< typename std::is_same< Boundary_T, typename std::tuple_element_t<N, BoundariesTuple> >::type,
+                                                                                                         std::false_type > >* /*dummy*/ = 0 ) const
    {
       return getBoundaryCondition_TypeExists< Boundary_T, BoundariesTuple, N-1 >( uid, boundaryConditions );
    }
 
-   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline const typename std::enable_if<(N==0), Boundary_T>::type & getBoundaryCondition_TypeExists( const BoundaryUID & uid, const BoundariesTuple & /*boundaryConditions*/,
-                                                              typename std::enable_if< std::is_same< typename std::is_same< Boundary_T, typename std::tuple_element<0, BoundariesTuple>::type >::type,
-                                                                                                         std::false_type >::value >::type* /*dummy*/ = nullptr ) const
+   template< typename Boundary_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline const typename std::enable_if_t<(N==0), Boundary_T> & getBoundaryCondition_TypeExists( const BoundaryUID & uid, const BoundariesTuple & /*boundaryConditions*/,
+                                                              typename std::enable_if_t< std::is_same_v< typename std::is_same< Boundary_T, typename std::tuple_element_t<0, BoundariesTuple> >::type,
+                                                                                                         std::false_type > >* /*dummy*/ = nullptr ) const
    {
       WALBERLA_ABORT( "The requested boundary condition " << uid.getIdentifier() << " is not part of this boundary handling." );
 
@@ -503,15 +503,15 @@ private:
 
    inline uint_t numberOfMatchingBoundaryConditions( const BoundaryUID & uid ) const;
 
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), uint_t>::type numberOfMatchingBoundaryConditions( const BoundariesTuple & boundaryConditions, const BoundaryUID & uid ) const;
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), uint_t>::type numberOfMatchingBoundaryConditions( const BoundariesTuple &, const BoundaryUID & ) const { return uint_c(0); }
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), uint_t> numberOfMatchingBoundaryConditions( const BoundariesTuple & boundaryConditions, const BoundaryUID & uid ) const;
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), uint_t> numberOfMatchingBoundaryConditions( const BoundariesTuple &, const BoundaryUID & ) const { return uint_c(0); }
 
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), uint_t>::type numberOfMatchingBoundaryConditions( const BoundariesTuple & boundaryConditions, const flag_t mask ) const;
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), uint_t>::type numberOfMatchingBoundaryConditions( const BoundariesTuple &, const flag_t ) const { return uint_c(0); }
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), uint_t> numberOfMatchingBoundaryConditions( const BoundariesTuple & boundaryConditions, const flag_t mask ) const;
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), uint_t> numberOfMatchingBoundaryConditions( const BoundariesTuple &, const flag_t ) const { return uint_c(0); }
 
    inline bool checkFlagField( const uint_t numberOfGhostLayersToInclude = 0 ) const;
 
@@ -520,35 +520,35 @@ private:
    //** Set Boundary Cells (private helper functions) ******************************************************************
    /*! \name Set Boundary Cells (private helper functions) */
    //@{
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), shared_ptr<BoundaryConfiguration>>::type createBoundaryConfiguration( const BoundariesTuple & boundaryConditions,
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), shared_ptr<BoundaryConfiguration>> createBoundaryConfiguration( const BoundariesTuple & boundaryConditions,
                                                                          const BoundaryUID & uid, const Config::BlockHandle & config ) const;
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), shared_ptr<BoundaryConfiguration>>::type createBoundaryConfiguration( const BoundariesTuple &, const BoundaryUID & uid,
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), shared_ptr<BoundaryConfiguration>> createBoundaryConfiguration( const BoundariesTuple &, const BoundaryUID & uid,
                                                                          const Config::BlockHandle & ) const;
 
    inline void addNearBoundary( const CellInterval & cells );
    inline void addBoundary( const flag_t flag, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
 
    template< typename BoundariesTuple, int N = internal::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type setBoundary(       BoundariesTuple & boundaryConditions, const flag_t flag,
+   inline typename std::enable_if_t<(N!=-1), void> setBoundary(       BoundariesTuple & boundaryConditions, const flag_t flag,
                                                                                         const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
                                                                                         const BoundaryConfiguration & parameter );
    template< typename BoundariesTuple, int N = internal::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type setBoundary( const BoundariesTuple &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t,
+   inline typename std::enable_if_t<(N==-1), void> setBoundary( const BoundariesTuple &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t,
                                                               const BoundaryConfiguration & ) const;
 
    template< typename BoundariesTuple, int N = internal::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type setBoundary(       BoundariesTuple & boundaryConditions, const flag_t flag, const CellInterval & cells,
+   inline typename std::enable_if_t<(N!=-1), void> setBoundary(       BoundariesTuple & boundaryConditions, const flag_t flag, const CellInterval & cells,
                                                                                         const BoundaryConfiguration & parameter );
    template< typename BoundariesTuple, int N = internal::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type setBoundary( const BoundariesTuple &, const flag_t, const CellInterval &, const BoundaryConfiguration & ) const;
+   inline typename std::enable_if_t<(N==-1), void> setBoundary( const BoundariesTuple &, const flag_t, const CellInterval &, const BoundaryConfiguration & ) const;
 
    template< typename BoundariesTuple, int N = internal::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type setBoundary(       BoundariesTuple & boundaryConditions, const flag_t flag, const CellVector & cells,
+   inline typename std::enable_if_t<(N!=-1), void> setBoundary(       BoundariesTuple & boundaryConditions, const flag_t flag, const CellVector & cells,
                                                                                         const BoundaryConfiguration & parameter );
    template< typename BoundariesTuple, int N = internal::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type setBoundary( const BoundariesTuple &, const flag_t, const CellVector &, const BoundaryConfiguration & ) const;
+   inline typename std::enable_if_t<(N==-1), void> setBoundary( const BoundariesTuple &, const flag_t, const CellVector &, const BoundaryConfiguration & ) const;
    //@}
    //*******************************************************************************************************************
 
@@ -556,40 +556,40 @@ private:
    /*! \name Remove Boundary Cells (private helper functions) */
    //@{
    template< typename BoundariesTuple, int N = internal::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type removeBoundary(       BoundariesTuple & boundaryConditions, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
+   inline typename std::enable_if_t<(N!=-1), void> removeBoundary(       BoundariesTuple & boundaryConditions, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
                                                                                            const bool checkNearBoundaryFlags = true );
    template< typename BoundariesTuple, int N = internal::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type removeBoundary( const BoundariesTuple &, const cell_idx_t, const cell_idx_t, const cell_idx_t, const bool ) const { WALBERLA_CHECK( false ); }
+   inline typename std::enable_if_t<(N==-1), void> removeBoundary( const BoundariesTuple &, const cell_idx_t, const cell_idx_t, const cell_idx_t, const bool ) const { WALBERLA_CHECK( false ); }
    //@}
    //*******************************************************************************************************************
 
    //** Boundary Treatment (private helper functions) ******************************************************************
    /*! \name Boundary Treatment (private helper functions) */
    //@{
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type treatDirection( BoundariesTuple & boundaryConditions, const uint_t index,
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), void> treatDirection( BoundariesTuple & boundaryConditions, const uint_t index,
                                const std::vector< std::vector< std::pair< Cell, stencil::Direction > > > & cellDirectionPairs );
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type treatDirection( const BoundariesTuple &, const uint_t,
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), void> treatDirection( const BoundariesTuple &, const uint_t,
                                const std::vector< std::vector< std::pair< Cell, stencil::Direction > > > & ) const {}
 
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type treatDirection(       BoundariesTuple & boundaryConditions, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), void> treatDirection(       BoundariesTuple & boundaryConditions, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
                                                                                            const stencil::Direction dir,
                                                                                            const cell_idx_t nx, const cell_idx_t ny, const cell_idx_t nz );
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type treatDirection( const BoundariesTuple & , const cell_idx_t, const cell_idx_t, const cell_idx_t, const stencil::Direction,
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), void> treatDirection( const BoundariesTuple & , const cell_idx_t, const cell_idx_t, const cell_idx_t, const stencil::Direction,
                                                                   const cell_idx_t, const cell_idx_t, const cell_idx_t ) const { WALBERLA_CHECK( false ); }
 
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type beforeBoundaryTreatment(       BoundariesTuple & boundaryConditions );
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type beforeBoundaryTreatment( const BoundariesTuple & ) const {}
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), void> beforeBoundaryTreatment(       BoundariesTuple & boundaryConditions );
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), void> beforeBoundaryTreatment( const BoundariesTuple & ) const {}
 
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type afterBoundaryTreatment(       BoundariesTuple & boundaryConditions );
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type afterBoundaryTreatment( const BoundariesTuple & ) const {}
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), void> afterBoundaryTreatment(       BoundariesTuple & boundaryConditions );
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), void> afterBoundaryTreatment( const BoundariesTuple & ) const {}
    //@}
    //*******************************************************************************************************************
 
@@ -609,11 +609,11 @@ private:
    template< typename Buffer_T >
    inline void pack( Buffer_T & buffer, const flag_t mask, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const;
 
-   template< typename Buffer_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type pack( const BoundariesTuple & boundaryConditions, Buffer_T & buffer,
+   template< typename Buffer_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), void> pack( const BoundariesTuple & boundaryConditions, Buffer_T & buffer,
                      const flag_t mask, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const;
-   template< typename Buffer_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   typename std::enable_if<(N==-1), void>::type pack( const BoundariesTuple &, Buffer_T &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t )
+   template< typename Buffer_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   typename std::enable_if_t<(N==-1), void> pack( const BoundariesTuple &, Buffer_T &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t )
               const { WALBERLA_CHECK( false ); }
 
    template< typename Buffer_T >
@@ -622,19 +622,19 @@ private:
    template< typename Buffer_T >
    inline void unpackBoundary( Buffer_T & buffer, const flag_t flag, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
 
-   template< typename Buffer_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type unpackBoundary( BoundariesTuple & boundaryConditions, Buffer_T & buffer, const flag_t flag,
+   template< typename Buffer_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N!=-1), void> unpackBoundary( BoundariesTuple & boundaryConditions, Buffer_T & buffer, const flag_t flag,
                                const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
-   template< typename Buffer_T, typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type unpackBoundary( const BoundariesTuple &, Buffer_T &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t)
+   template< typename Buffer_T, typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   inline typename std::enable_if_t<(N==-1), void> unpackBoundary( const BoundariesTuple &, Buffer_T &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t)
                                const { WALBERLA_CHECK( false ); }
    //@}
    //*******************************************************************************************************************
 
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   typename std::enable_if<(N!=-1), void>::type getBoundaryConditions( const BoundariesTuple & boundaryConditions, std::vector< std::string > & bcs ) const;
-   template< typename BoundariesTuple, int N = std::tuple_size<BoundariesTuple>::value - 1 >
-   typename std::enable_if<(N==-1), void>::type getBoundaryConditions( const BoundariesTuple &, std::vector< std::string > & ) const {}
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   typename std::enable_if_t<(N!=-1), void> getBoundaryConditions( const BoundariesTuple & boundaryConditions, std::vector< std::string > & bcs ) const;
+   template< typename BoundariesTuple, int N = std::tuple_size_v<BoundariesTuple> - 1 >
+   typename std::enable_if_t<(N==-1), void> getBoundaryConditions( const BoundariesTuple &, std::vector< std::string > & ) const {}
 
    template< typename T > static void valueToStream( std::ostream & os, const T       value ) { os << value; }
                           static void valueToStream( std::ostream & os, const  int8_t value ) { os <<  int_c( value ); }
@@ -2154,8 +2154,8 @@ inline void BoundaryHandling< FlagField_T, Stencil, Boundaries... >::operator()(
 
       if( dirty_ )
       {
-         for( uint_t i = 0; i != rebuildCellDirectionPairs_.size(); ++i )
-            rebuildCellDirectionPairs_[i] = true;
+         for(auto && rebuildCellDirectionPair : rebuildCellDirectionPairs_)
+            rebuildCellDirectionPair = true;
          dirty_ = false;
       }
 
@@ -2370,8 +2370,8 @@ inline void BoundaryHandling< FlagField_T, Stencil, Boundaries... >::toStream( s
    std::vector< std::string > boundaryConditions;
    getBoundaryConditions( boundaryConditions_, boundaryConditions );
 
-   for( auto bc = boundaryConditions.begin(); bc != boundaryConditions.end(); ++bc )
-      os << "- " << *bc << "\n";
+   for(auto & boundaryCondition : boundaryConditions)
+      os << "- " << boundaryCondition << "\n";
 
    os << "\nFlags/Masks:"
       << "\n- near boundary: "; valueToStream( os, nearBoundary_ );
@@ -2412,9 +2412,9 @@ CellInterval BoundaryHandling< FlagField_T, Stencil, Boundaries... >::getGhostLa
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setupBoundaryConditions( BoundariesTuple & boundaryConditions )
+typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setupBoundaryConditions( BoundariesTuple & boundaryConditions )
 {
-   using BoundaryType = typename std::tuple_element<N, BoundariesTuple>::type;
+   using BoundaryType = typename std::tuple_element_t<N, BoundariesTuple>;
    BoundaryType & boundaryCondition = std::get<N>( boundaryConditions );
 
    if( numberOfMatchingBoundaryConditions( boundaryCondition.getUID() ) != 1 )
@@ -2425,12 +2425,12 @@ typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Sten
    std::vector< FlagUID > uids;
    boundaryCondition.pushFlags( uids );
 
-   for( auto uid = uids.begin(); uid != uids.end(); ++uid )
+   for(auto & uid : uids)
    {
-      if( flagField_->flagExists( *uid ) )
-         mask = static_cast<flag_t>( mask | flagField_->getFlag( *uid ) );
+      if( flagField_->flagExists( uid ) )
+         mask = static_cast<flag_t>( mask | flagField_->getFlag( uid ) );
       else
-         mask = static_cast<flag_t>( mask | flagField_->registerFlag( *uid ) );
+         mask = static_cast<flag_t>( mask | flagField_->registerFlag( uid ) );
    }
    WALBERLA_ASSERT_EQUAL( boundary_ & mask, flag_t(0) ); // every boundary condition must have a unique mask/set of FlagUIDs
 
@@ -2459,7 +2459,7 @@ inline std::vector< BoundaryUID > BoundaryHandling< FlagField_T, Stencil, Bounda
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::getBoundaryUIDs( const BoundariesTuple & boundaryConditions,
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::getBoundaryUIDs( const BoundariesTuple & boundaryConditions,
                                                                               std::vector< BoundaryUID > & uids ) const
 {
    uids.push_back( std::get<N>( boundaryConditions ).getUID() );
@@ -2470,7 +2470,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), BoundaryUID>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::getBoundaryUID( const BoundariesTuple & boundaryConditions,
+inline typename std::enable_if_t<(N!=-1), BoundaryUID> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::getBoundaryUID( const BoundariesTuple & boundaryConditions,
                                                                                     const flag_t flag ) const
 {
    const auto & boundaryCondition = std::get<N>( boundaryConditions );
@@ -2489,7 +2489,7 @@ inline typename std::enable_if<(N!=-1), BoundaryUID>::type BoundaryHandling< Fla
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N==-1), BoundaryUID>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::getBoundaryUID( const BoundariesTuple &,
+inline typename std::enable_if_t<(N==-1), BoundaryUID> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::getBoundaryUID( const BoundariesTuple &,
                                                                                     const flag_t flag ) const
 {
    if( !flagField_->isRegistered( flag ) )
@@ -2509,7 +2509,7 @@ inline typename std::enable_if<(N==-1), BoundaryUID>::type BoundaryHandling< Fla
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::containsBoundaryCondition( const BoundariesTuple & boundaryConditions,
+inline typename std::enable_if_t<(N!=-1), bool> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::containsBoundaryCondition( const BoundariesTuple & boundaryConditions,
                                                                                         const BoundaryUID & uid ) const
 {
    if( std::get<N>( boundaryConditions ).getUID() == uid )
@@ -2521,7 +2521,7 @@ inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), typename BoundaryHandling< FlagField_T, Stencil, Boundaries... >::flag_t>::type
+inline typename std::enable_if_t<(N!=-1), typename BoundaryHandling< FlagField_T, Stencil, Boundaries... >::flag_t>
    BoundaryHandling< FlagField_T, Stencil, Boundaries... >::getBoundaryMask( const BoundariesTuple & boundaryConditions,
                                                                      const BoundaryUID & uid ) const
 {
@@ -2544,7 +2544,7 @@ inline uint_t BoundaryHandling< FlagField_T, Stencil, Boundaries... >::numberOfM
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::numberOfMatchingBoundaryConditions( const BoundariesTuple & boundaryConditions,
+inline typename std::enable_if_t<(N!=-1), uint_t> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::numberOfMatchingBoundaryConditions( const BoundariesTuple & boundaryConditions,
                                                                                                  const BoundaryUID & uid ) const
 {
    return ( ( std::get<N>( boundaryConditions ).getUID() == uid ) ? uint_c(1) : uint_c(0) ) +
@@ -2555,7 +2555,7 @@ inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandling< FlagFiel
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::numberOfMatchingBoundaryConditions( const BoundariesTuple & boundaryConditions,
+inline typename std::enable_if_t<(N!=-1), uint_t> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::numberOfMatchingBoundaryConditions( const BoundariesTuple & boundaryConditions,
                                                                                                  const flag_t mask ) const
 {
    return ( ( ( std::get<N>( boundaryConditions ).getMask() & mask ) != 0 ) ? uint_c(1) : uint_c(0) ) +
@@ -2585,13 +2585,12 @@ inline bool BoundaryHandling< FlagField_T, Stencil, Boundaries... >::checkFlagFi
       WALBERLA_ASSERT( innerBB_.contains( cells ) );
 
       CellVector nearBoundaryCells;
-      for( auto cellDirectionPairs = cellDirectionPairs_[numberOfGhostLayersToInclude].begin();
-               cellDirectionPairs != cellDirectionPairs_[numberOfGhostLayersToInclude].end(); ++cellDirectionPairs )
-         for( auto cellDirectionPair = cellDirectionPairs->begin(); cellDirectionPair != cellDirectionPairs->end(); ++cellDirectionPair )
-            nearBoundaryCells.push_back( cellDirectionPair->first );
+      for(const auto & cellDirectionPairs : cellDirectionPairs_[numberOfGhostLayersToInclude])
+         for(const auto & cellDirectionPair : cellDirectionPairs)
+            nearBoundaryCells.push_back( cellDirectionPair.first );
 
-      for( auto cell = nearBoundaryCells.begin(); cell != nearBoundaryCells.end(); ++cell )
-         if( !flagField_->isFlagSet( cell->x(), cell->y(), cell->z(), nearBoundary_ ) )
+      for(auto & nearBoundaryCell : nearBoundaryCells)
+         if( !flagField_->isFlagSet( nearBoundaryCell.x(), nearBoundaryCell.y(), nearBoundaryCell.z(), nearBoundary_ ) )
             return false;
 
       CellSet nearBoundarySet( nearBoundaryCells );
@@ -2637,10 +2636,10 @@ inline void BoundaryHandling< FlagField_T, Stencil, Boundaries... >::addDomain(
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), shared_ptr<BoundaryConfiguration>>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::createBoundaryConfiguration( const BoundariesTuple & boundaryConditions,
+inline typename std::enable_if_t<(N!=-1), shared_ptr<BoundaryConfiguration>> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::createBoundaryConfiguration( const BoundariesTuple & boundaryConditions,
                                                                                                                        const BoundaryUID & uid, const Config::BlockHandle & config ) const
 {
-   using BoundaryType = typename std::tuple_element<N, BoundariesTuple>::type;
+   using BoundaryType = typename std::tuple_element_t<N, BoundariesTuple>;
    const BoundaryType & boundaryCondition = std::get<N>( boundaryConditions );
    
    if( boundaryCondition.getUID() == uid )
@@ -2651,7 +2650,7 @@ inline typename std::enable_if<(N!=-1), shared_ptr<BoundaryConfiguration>>::type
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N==-1), shared_ptr<BoundaryConfiguration>>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::createBoundaryConfiguration( const BoundariesTuple &,
+inline typename std::enable_if_t<(N==-1), shared_ptr<BoundaryConfiguration>> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::createBoundaryConfiguration( const BoundariesTuple &,
                                                                                                                        const BoundaryUID & uid, const Config::BlockHandle & ) const
 {
    WALBERLA_CHECK( false, "There is no boundary condition registered at boundary handling " << uid_ << " for a boundary with UID" << uid << "." );
@@ -2707,7 +2706,7 @@ inline void BoundaryHandling< FlagField_T, Stencil, Boundaries... >::addBoundary
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( BoundariesTuple & boundaryConditions, const flag_t flag,
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( BoundariesTuple & boundaryConditions, const flag_t flag,
                                                                           const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
                                                                           const BoundaryConfiguration & parameter )
 {
@@ -2726,7 +2725,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N==-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( const BoundariesTuple &, const flag_t flag,
+inline typename std::enable_if_t<(N==-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( const BoundariesTuple &, const flag_t flag,
                                                                           const cell_idx_t, const cell_idx_t, const cell_idx_t,
                                                                           const BoundaryConfiguration & ) const
 {
@@ -2744,7 +2743,7 @@ inline typename std::enable_if<(N==-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( BoundariesTuple & boundaryConditions, const flag_t flag,
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( BoundariesTuple & boundaryConditions, const flag_t flag,
                                                                           const CellInterval & cells, const BoundaryConfiguration & parameter )
 {
    WALBERLA_ASSERT( outerBB_.contains( cells ) );
@@ -2779,7 +2778,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N==-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( const BoundariesTuple &, const flag_t flag,
+inline typename std::enable_if_t<(N==-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( const BoundariesTuple &, const flag_t flag,
                                                                           const CellInterval &, const BoundaryConfiguration & ) const
 {
    if( flagField_->isRegistered( flag ) )
@@ -2796,7 +2795,7 @@ inline typename std::enable_if<(N==-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( BoundariesTuple & boundaryConditions, const flag_t flag,
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( BoundariesTuple & boundaryConditions, const flag_t flag,
                                                                           const CellVector & cells, const BoundaryConfiguration & parameter )
 {
    if( cells.empty() )
@@ -2805,8 +2804,8 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_
    auto & boundaryCondition = std::get<N>( boundaryConditions );
    if( ( boundaryCondition.getMask() & flag ) == flag )
    {
-      for( auto cell = cells.begin(); cell != cells.end(); ++cell )
-         addBoundary( flag, cell->x(), cell->y(), cell->z() );
+      for(auto cell : cells)
+         addBoundary( flag, cell.x(), cell.y(), cell.z() );
 
       boundaryCondition.registerCells( flag, cells.begin(), cells.end(), parameter );
    }
@@ -2816,7 +2815,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N==-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( const BoundariesTuple &, const flag_t flag,
+inline typename std::enable_if_t<(N==-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::setBoundary( const BoundariesTuple &, const flag_t flag,
                                                                           const CellVector &, const BoundaryConfiguration & ) const
 {
    if( flagField_->isRegistered( flag ) )
@@ -2833,7 +2832,7 @@ inline typename std::enable_if<(N==-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::removeBoundary( BoundariesTuple & boundaryConditions,
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::removeBoundary( BoundariesTuple & boundaryConditions,
                                                                              const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
                                                                              const bool checkNearBoundaryFlags )
 {
@@ -2891,7 +2890,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::treatDirection( BoundariesTuple & boundaryConditions, const uint_t index,
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::treatDirection( BoundariesTuple & boundaryConditions, const uint_t index,
                                                                              const std::vector< std::vector< std::pair< Cell, stencil::Direction > > > & cellDirectionPairs )
 {
    auto & boundaryCondition = std::get<N>( boundaryConditions );
@@ -2924,7 +2923,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::treatDirection( BoundariesTuple & boundaryConditions,
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::treatDirection( BoundariesTuple & boundaryConditions,
                                                                              const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
                                                                              const stencil::Direction dir,
                                                                              const cell_idx_t nx, const cell_idx_t ny, const cell_idx_t nz )
@@ -2945,7 +2944,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::beforeBoundaryTreatment( BoundariesTuple & boundaryConditions )
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::beforeBoundaryTreatment( BoundariesTuple & boundaryConditions )
 {
    std::get<N>( boundaryConditions ).beforeBoundaryTreatment();
 
@@ -2956,7 +2955,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::afterBoundaryTreatment( BoundariesTuple & boundaryConditions )
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::afterBoundaryTreatment( BoundariesTuple & boundaryConditions )
 {
    std::get<N>( boundaryConditions ).afterBoundaryTreatment();
 
@@ -3096,7 +3095,7 @@ inline void BoundaryHandling< FlagField_T, Stencil, Boundaries... >::pack( Buffe
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename Buffer_T, typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::pack( const BoundariesTuple & boundaryConditions, Buffer_T & buffer,
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::pack( const BoundariesTuple & boundaryConditions, Buffer_T & buffer,
                                                                    const flag_t mask, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const
 {
    const auto & boundaryCondition = std::get<N>( boundaryConditions );
@@ -3142,7 +3141,7 @@ inline void BoundaryHandling< FlagField_T, Stencil, Boundaries... >::unpackBound
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename Buffer_T, typename BoundariesTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::unpackBoundary( BoundariesTuple & boundaryConditions, Buffer_T & buffer,
+inline typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::unpackBoundary( BoundariesTuple & boundaryConditions, Buffer_T & buffer,
                                                                              const flag_t flag,
                                                                              const cell_idx_t x, const cell_idx_t y, const cell_idx_t z )
 {
@@ -3163,7 +3162,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_
 
 template< typename FlagField_T, typename Stencil, typename... Boundaries >
 template< typename BoundariesTuple, int N >
-typename std::enable_if<(N!=-1), void>::type BoundaryHandling< FlagField_T, Stencil, Boundaries... >::getBoundaryConditions( const BoundariesTuple & boundaryConditions,
+typename std::enable_if_t<(N!=-1), void> BoundaryHandling< FlagField_T, Stencil, Boundaries... >::getBoundaryConditions( const BoundariesTuple & boundaryConditions,
                                                                              std::vector< std::string > & bcs ) const
 {
    const auto & boundaryCondition = std::get<N>( boundaryConditions );
diff --git a/src/boundary/BoundaryHandlingCollection.h b/src/boundary/BoundaryHandlingCollection.h
index 7b94d4a0e2c47b12724162ce89c007c850de964d..88d1f8d33029f52a05dba22a8f2cac0a53d58830 100644
--- a/src/boundary/BoundaryHandlingCollection.h
+++ b/src/boundary/BoundaryHandlingCollection.h
@@ -1,15 +1,15 @@
 //======================================================================================================================
 //
-//  This file is part of waLBerla. waLBerla is free software: you can 
+//  This file is part of waLBerla. waLBerla 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.
-//  
-//  waLBerla 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 
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
@@ -230,24 +230,24 @@ private:
    CellInterval getGhostLayerCellInterval( const uint_t numberOfGhostLayersToInclude ) const;
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), bool>::type isEmpty( const HandlersTuple & boundaryHandlers, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const;
+   inline std::enable_if_t<(N!=-1), bool>isEmpty( const HandlersTuple & boundaryHandlers, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), bool>::type isEmpty( const HandlersTuple &, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const { return true; }
+   inline std::enable_if_t<(N==-1), bool>isEmpty( const HandlersTuple &, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const { return true; }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), bool>::type isEmpty( const HandlersTuple & boundaryHandlers, const ConstFlagFieldBaseIterator & it ) const;
+   inline std::enable_if_t<(N!=-1), bool>isEmpty( const HandlersTuple & boundaryHandlers, const ConstFlagFieldBaseIterator & it ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), bool>::type isEmpty( const HandlersTuple &, const ConstFlagFieldBaseIterator & ) const { return true; }
+   inline std::enable_if_t<(N==-1), bool>isEmpty( const HandlersTuple &, const ConstFlagFieldBaseIterator & ) const { return true; }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), bool>::type consideredByAllHandlers( const HandlersTuple & boundaryHandlers, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const;
+   inline std::enable_if_t<(N!=-1), bool>consideredByAllHandlers( const HandlersTuple & boundaryHandlers, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), bool>::type consideredByAllHandlers( const HandlersTuple &, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const { return true; }
+   inline std::enable_if_t<(N==-1), bool>consideredByAllHandlers( const HandlersTuple &, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const { return true; }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), bool>::type consideredByAllHandlers( const HandlersTuple & boundaryHandlers, const ConstFlagFieldBaseIterator & it ) const;
+   inline std::enable_if_t<(N!=-1), bool>consideredByAllHandlers( const HandlersTuple & boundaryHandlers, const ConstFlagFieldBaseIterator & it ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), bool>::type consideredByAllHandlers( const HandlersTuple &, const ConstFlagFieldBaseIterator & ) const { return true; }
+   inline std::enable_if_t<(N==-1), bool>consideredByAllHandlers( const HandlersTuple &, const ConstFlagFieldBaseIterator & ) const { return true; }
 
    //** Get Boundary Handling (private helper functions) ***************************************************************
    /*! \name Get Boundary Handling (private helper functions) */
@@ -257,7 +257,7 @@ private:
 
    template< typename BoundaryHandling_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
    inline const typename std::enable_if<(N!=0), BoundaryHandling_T>::type & getBoundaryHandling( const BoundaryHandlingUID & uid, const HandlersTuple & boundaryHandlers,
-                                                          typename std::enable_if< std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::value >::type* /*dummy*/ = 0 ) const
+                                                          std::enable_if_t< std::is_same_v< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type > >* /*dummy*/ = 0 ) const
    {
       if( uid == std::get<N>( boundaryHandlers ).getUID() )
          return std::get<N>( boundaryHandlers );
@@ -268,7 +268,7 @@ private:
 
    template< typename BoundaryHandling_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
    inline const typename std::enable_if<(N==0), BoundaryHandling_T>::type & getBoundaryHandling( const BoundaryHandlingUID & uid, const HandlersTuple & boundaryHandlers,
-                                                          typename std::enable_if< std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::value >::type* /*dummy*/ = 0 ) const
+                                                          std::enable_if_t< std::is_same_v< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type > >* /*dummy*/ = 0 ) const
    {
       if( uid == std::get<N>( boundaryHandlers ).getUID() )
          return std::get<N>( boundaryHandlers );
@@ -278,16 +278,16 @@ private:
 
    template< typename BoundaryHandling_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
    inline const typename std::enable_if<(N!=0), BoundaryHandling_T>::type & getBoundaryHandling( const BoundaryHandlingUID & uid, const HandlersTuple & boundaryHandlers,
-                                                          typename std::enable_if< std::is_same< typename std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::type,
-                                                                                                     std::false_type >::value >::type* /*dummy*/ = 0 ) const
+                                                          std::enable_if_t< std::is_same_v< typename std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::type,
+                                                                                                     std::false_type > >* /*dummy*/ = 0 ) const
    {
       return getBoundaryHandling< BoundaryHandling_T, HandlersTuple, N-1 >( uid, boundaryHandlers );
    }
 
    template< typename BoundaryHandling_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
    inline const typename std::enable_if<(N==0), BoundaryHandling_T>::type & getBoundaryHandling( const BoundaryHandlingUID & /*uid*/, const HandlersTuple & /*boundaryHandlers*/,
-                                                          typename std::enable_if< std::is_same< typename std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::type,
-                                                                                                     std::false_type >::value >::type* /*dummy*/ = 0 ) const
+                                                          std::enable_if_t< std::is_same_v< typename std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::type,
+                                                                                                     std::false_type > >* /*dummy*/ = 0 ) const
    {
       static_assert( sizeof(BoundaryHandling_T) == 0, "The requested boundary handling is not part of this boundary handling collection." );
    }
@@ -296,7 +296,7 @@ private:
 
    template< typename BoundaryHandling_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
    inline const typename std::enable_if<(N!=0), BoundaryHandling_T>::type & getBoundaryHandling_TypeExists( const BoundaryHandlingUID & uid, const HandlersTuple & boundaryHandlers,
-                                                                     typename std::enable_if< std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::value >::type* /*dummy*/ = 0 ) const
+                                                                     std::enable_if_t< std::is_same_v< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type > >* /*dummy*/ = 0 ) const
    {
       if( uid == std::get<N>( boundaryHandlers ).getUID() )
          return std::get<N>( boundaryHandlers );
@@ -307,7 +307,7 @@ private:
 
    template< typename BoundaryHandling_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
    inline const typename std::enable_if<(N==0), BoundaryHandling_T>::type & getBoundaryHandling_TypeExists( const BoundaryHandlingUID & uid, const HandlersTuple & boundaryHandlers,
-                                                                     typename std::enable_if< std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::value >::type* /*dummy*/ = 0 ) const
+                                                                     std::enable_if_t< std::is_same_v< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type > >* /*dummy*/ = 0 ) const
    {
       if( uid == std::get<N>( boundaryHandlers ).getUID() )
          return std::get<N>( boundaryHandlers );
@@ -317,16 +317,16 @@ private:
 
    template< typename BoundaryHandling_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
    inline const typename std::enable_if<(N!=0), BoundaryHandling_T>::type & getBoundaryHandling_TypeExists( const BoundaryHandlingUID & uid, const HandlersTuple & boundaryHandlers,
-                                                                     typename std::enable_if< std::is_same< typename std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::type,
-                                                                                                                std::false_type >::value >::type* /*dummy*/ = 0 ) const
+                                                                     std::enable_if_t< std::is_same_v< typename std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::type,
+                                                                                                                std::false_type > >* /*dummy*/ = 0 ) const
    {
       return getBoundaryHandling_TypeExists< BoundaryHandling_T, HandlersTuple, N-1 >( uid, boundaryHandlers );
    }
 
    template< typename BoundaryHandling_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
    inline const typename std::enable_if<(N==0), BoundaryHandling_T>::type & getBoundaryHandling_TypeExists( const BoundaryHandlingUID & uid, const HandlersTuple & /*boundaryHandlers*/,
-                                                                     typename std::enable_if< std::is_same< typename std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::type,
-                                                                                                                std::false_type >::value >::type* /*dummy*/ = 0 ) const
+                                                                     std::enable_if_t< std::is_same_v< typename std::is_same< BoundaryHandling_T, typename std::tuple_element<N, HandlersTuple>::type >::type,
+                                                                                                                std::false_type > >* /*dummy*/ = 0 ) const
    {
       WALBERLA_ABORT( "The requested boundary handler " << uid.getIdentifier() << " is not part of this boundary handling collection." );
    }
@@ -334,115 +334,115 @@ private:
    //*******************************************************************************************************************
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type checkForUniqueBoundaryHandlingUIDs( const HandlersTuple & boundaryHandlers ) const;
+   inline std::enable_if_t<(N!=-1), void>checkForUniqueBoundaryHandlingUIDs( const HandlersTuple & boundaryHandlers ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type checkForUniqueBoundaryHandlingUIDs( const HandlersTuple & ) const {}
+   inline std::enable_if_t<(N==-1), void>checkForUniqueBoundaryHandlingUIDs( const HandlersTuple & ) const {}
 
    inline std::vector< BoundaryUID > getBoundaryUIDs() const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type getBoundaryUIDs( const HandlersTuple & boundaryHandlers, std::vector< BoundaryUID > & uids ) const;
+   inline std::enable_if_t<(N!=-1), void>getBoundaryUIDs( const HandlersTuple & boundaryHandlers, std::vector< BoundaryUID > & uids ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type getBoundaryUIDs( const HandlersTuple &, std::vector< BoundaryUID > & ) const {}
+   inline std::enable_if_t<(N==-1), void>getBoundaryUIDs( const HandlersTuple &, std::vector< BoundaryUID > & ) const {}
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), bool>::type checkForIdenticalFlagFields( const HandlersTuple & boundaryHandlers ) const;
+   inline std::enable_if_t<(N!=-1), bool>checkForIdenticalFlagFields( const HandlersTuple & boundaryHandlers ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), bool>::type checkForIdenticalFlagFields( const HandlersTuple & ) const { return true; }
+   inline std::enable_if_t<(N==-1), bool>checkForIdenticalFlagFields( const HandlersTuple & ) const { return true; }
 
    inline uint_t numberOfMatchingBoundaryHandlers( const BoundaryHandlingUID & uid ) const;
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), uint_t>::type numberOfMatchingBoundaryHandlers( const HandlersTuple & boundaryHandlers, const BoundaryHandlingUID & uid ) const;
+   inline std::enable_if_t<(N!=-1), uint_t>numberOfMatchingBoundaryHandlers( const HandlersTuple & boundaryHandlers, const BoundaryHandlingUID & uid ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), uint_t>::type numberOfMatchingBoundaryHandlers( const HandlersTuple &, const BoundaryHandlingUID & ) const { return uint_c(0); }
+   inline std::enable_if_t<(N==-1), uint_t>numberOfMatchingBoundaryHandlers( const HandlersTuple &, const BoundaryHandlingUID & ) const { return uint_c(0); }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), uint_t>::type numberOfMatchingHandlers( const HandlersTuple & boundaryHandlers, const flag_t flag ) const;
+   inline std::enable_if_t<(N!=-1), uint_t>numberOfMatchingHandlers( const HandlersTuple & boundaryHandlers, const flag_t flag ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), uint_t>::type numberOfMatchingHandlers( const HandlersTuple &, const flag_t ) const { return uint_c(0); }
+   inline std::enable_if_t<(N==-1), uint_t>numberOfMatchingHandlers( const HandlersTuple &, const flag_t ) const { return uint_c(0); }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), uint_t>::type numberOfMatchingHandlersForDomain( const HandlersTuple & boundaryHandlers, const flag_t flag ) const;
+   inline std::enable_if_t<(N!=-1), uint_t>numberOfMatchingHandlersForDomain( const HandlersTuple & boundaryHandlers, const flag_t flag ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), uint_t>::type numberOfMatchingHandlersForDomain( const HandlersTuple &, const flag_t ) const { return uint_c(0); }
+   inline std::enable_if_t<(N==-1), uint_t>numberOfMatchingHandlersForDomain( const HandlersTuple &, const flag_t ) const { return uint_c(0); }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), uint_t>::type numberOfMatchingHandlersForBoundary( const HandlersTuple & boundaryHandlers, const flag_t flag ) const;
+   inline std::enable_if_t<(N!=-1), uint_t>numberOfMatchingHandlersForBoundary( const HandlersTuple & boundaryHandlers, const flag_t flag ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), uint_t>::type numberOfMatchingHandlersForBoundary( const HandlersTuple &, const flag_t ) const { return uint_c(0); }
+   inline std::enable_if_t<(N==-1), uint_t>numberOfMatchingHandlersForBoundary( const HandlersTuple &, const flag_t ) const { return uint_c(0); }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), bool>::type containsBoundaryCondition( const HandlersTuple & boundaryHandlers, const BoundaryUID & uid ) const;
+   inline std::enable_if_t<(N!=-1), bool>containsBoundaryCondition( const HandlersTuple & boundaryHandlers, const BoundaryUID & uid ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), bool>::type containsBoundaryCondition( const HandlersTuple &, const BoundaryUID & ) const { return false; }
+   inline std::enable_if_t<(N==-1), bool>containsBoundaryCondition( const HandlersTuple &, const BoundaryUID & ) const { return false; }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), bool>::type containsBoundaryCondition( const HandlersTuple & boundaryHandlers, const flag_t flag ) const;
+   inline std::enable_if_t<(N!=-1), bool>containsBoundaryCondition( const HandlersTuple & boundaryHandlers, const flag_t flag ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), bool>::type containsBoundaryCondition( const HandlersTuple &, const flag_t ) const { return false; }
+   inline std::enable_if_t<(N==-1), bool>containsBoundaryCondition( const HandlersTuple &, const flag_t ) const { return false; }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), flag_t>::type getBoundaryMask( const HandlersTuple & boundaryHandlers, const BoundaryUID & uid ) const;
+   inline std::enable_if_t<(N!=-1), flag_t>getBoundaryMask( const HandlersTuple & boundaryHandlers, const BoundaryUID & uid ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), flag_t>::type getBoundaryMask( const HandlersTuple &, const BoundaryUID & ) const { return numeric_cast<flag_t>(0); }
+   inline std::enable_if_t<(N==-1), flag_t>getBoundaryMask( const HandlersTuple &, const BoundaryUID & ) const { return numeric_cast<flag_t>(0); }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), BoundaryUID>::type getBoundaryUID( const HandlersTuple & boundaryHandlers, const flag_t flag ) const;
+   inline std::enable_if_t<(N!=-1), BoundaryUID>getBoundaryUID( const HandlersTuple & boundaryHandlers, const flag_t flag ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), BoundaryUID>::type getBoundaryUID( const HandlersTuple &, const flag_t ) const;
+   inline std::enable_if_t<(N==-1), BoundaryUID>getBoundaryUID( const HandlersTuple &, const flag_t ) const;
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), shared_ptr<BoundaryConfiguration>>::type createBoundaryConfiguration( const HandlersTuple & boundaryHandlers,
+   inline std::enable_if_t<(N!=-1), shared_ptr<BoundaryConfiguration>>createBoundaryConfiguration( const HandlersTuple & boundaryHandlers,
                                                                          const BoundaryUID & uid, const Config::BlockHandle & config ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), shared_ptr<BoundaryConfiguration>>::type createBoundaryConfiguration( const HandlersTuple &, const BoundaryUID &,
+   inline std::enable_if_t<(N==-1), shared_ptr<BoundaryConfiguration>>createBoundaryConfiguration( const HandlersTuple &, const BoundaryUID &,
                                                                          const Config::BlockHandle & ) const
                                                                                   { WALBERLA_ASSERT( false ); return make_shared<BoundaryConfiguration>(); }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), bool>::type checkConsistency( const HandlersTuple & boundaryHandlers, const CellInterval & cells ) const;
+   inline std::enable_if_t<(N!=-1), bool>checkConsistency( const HandlersTuple & boundaryHandlers, const CellInterval & cells ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), bool>::type checkConsistency( const HandlersTuple &, const CellInterval & ) const { return true; }
+   inline std::enable_if_t<(N==-1), bool>checkConsistency( const HandlersTuple &, const CellInterval & ) const { return true; }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type refresh(       HandlersTuple & boundaryHandlers, const CellInterval & cells );
+   inline std::enable_if_t<(N!=-1), void>refresh(       HandlersTuple & boundaryHandlers, const CellInterval & cells );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type refresh( const HandlersTuple &, const CellInterval & ) const {}
+   inline std::enable_if_t<(N==-1), void>refresh( const HandlersTuple &, const CellInterval & ) const {}
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type refreshOutermostLayer(       HandlersTuple & boundaryHandlers, cell_idx_t thickness );
+   inline std::enable_if_t<(N!=-1), void>refreshOutermostLayer(       HandlersTuple & boundaryHandlers, cell_idx_t thickness );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type refreshOutermostLayer( const HandlersTuple &, cell_idx_t ) const {}
+   inline std::enable_if_t<(N==-1), void>refreshOutermostLayer( const HandlersTuple &, cell_idx_t ) const {}
 
    //** General Flag Handling (private helper functions) ***************************************************************
    /*! \name General Flag Handling (private helper functions) */
    //@{
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-          typename std::enable_if<(N!=-1), void>::type setFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
+          std::enable_if_t<(N!=-1), void>setFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
                         const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const BoundaryConfiguration & parameter );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type setFlag( const HandlersTuple &, const flag_t flag, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
+   inline std::enable_if_t<(N==-1), void>setFlag( const HandlersTuple &, const flag_t flag, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
                         const BoundaryConfiguration & );
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-          typename std::enable_if<(N!=-1), void>::type setFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
+          std::enable_if_t<(N!=-1), void>setFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
                         const CellInterval & cells, const BoundaryConfiguration & parameter );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type setFlag( const HandlersTuple &, const flag_t flag, const CellInterval & cells, const BoundaryConfiguration & );
+   inline std::enable_if_t<(N==-1), void>setFlag( const HandlersTuple &, const flag_t flag, const CellInterval & cells, const BoundaryConfiguration & );
 
    void forceFlagHelper( const flag_t flag, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const BoundaryConfiguration & parameter );
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-          typename std::enable_if<(N!=-1), flag_t>::type flagsToRemove( HandlersTuple & boundaryHandlers, const flag_t flag,
+          std::enable_if_t<(N!=-1), flag_t>flagsToRemove( HandlersTuple & boundaryHandlers, const flag_t flag,
                                 const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), flag_t>::type flagsToRemove( const HandlersTuple &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const { return 0; }
+   inline std::enable_if_t<(N==-1), flag_t>flagsToRemove( const HandlersTuple &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const { return 0; }
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-          typename std::enable_if<(N!=-1), void>::type removeFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
+          std::enable_if_t<(N!=-1), void>removeFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
                            const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type removeFlag( const HandlersTuple &, const flag_t flag, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
+   inline std::enable_if_t<(N==-1), void>removeFlag( const HandlersTuple &, const flag_t flag, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
    //@}
    //*******************************************************************************************************************
 
@@ -450,9 +450,9 @@ private:
    /*! \name Clear Cells (private helper functions) */
    //@{
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-          typename std::enable_if<(N!=-1), flag_t>::type clear( HandlersTuple & boundaryHandlers, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
+          std::enable_if_t<(N!=-1), flag_t>clear( HandlersTuple & boundaryHandlers, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), flag_t>::type clear( const HandlersTuple &, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const { return 0; }
+   inline std::enable_if_t<(N==-1), flag_t>clear( const HandlersTuple &, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const { return 0; }
    //@}
    //*******************************************************************************************************************
 
@@ -460,34 +460,34 @@ private:
    /*! \name Boundary Treatment (private helper functions) */
    //@{
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type execute( HandlersTuple & boundaryHandlers, const uint_t numberOfGhostLayersToInclude );
+   inline std::enable_if_t<(N!=-1), void>execute( HandlersTuple & boundaryHandlers, const uint_t numberOfGhostLayersToInclude );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type execute( const HandlersTuple &, const uint_t ) const {}
+   inline std::enable_if_t<(N==-1), void>execute( const HandlersTuple &, const uint_t ) const {}
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type execute( HandlersTuple & boundaryHandlers, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
+   inline std::enable_if_t<(N!=-1), void>execute( HandlersTuple & boundaryHandlers, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type execute( const HandlersTuple &, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const {}
+   inline std::enable_if_t<(N==-1), void>execute( const HandlersTuple &, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const {}
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type execute( HandlersTuple & boundaryHandlers, const CellInterval & cells );
+   inline std::enable_if_t<(N!=-1), void>execute( HandlersTuple & boundaryHandlers, const CellInterval & cells );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type execute( const HandlersTuple &, const CellInterval & ) const {}
+   inline std::enable_if_t<(N==-1), void>execute( const HandlersTuple &, const CellInterval & ) const {}
 
    template< typename CellIterator, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type execute( HandlersTuple & boundaryHandlers, const CellIterator & begin, const CellIterator & end );
+   inline std::enable_if_t<(N!=-1), void>execute( HandlersTuple & boundaryHandlers, const CellIterator & begin, const CellIterator & end );
    template< typename CellIterator, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type execute( const HandlersTuple &, const CellIterator &, const CellIterator & ) const {}
+   inline std::enable_if_t<(N==-1), void>execute( const HandlersTuple &, const CellIterator &, const CellIterator & ) const {}
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type beforeBoundaryTreatment( HandlersTuple & boundaryHandlers );
+   inline std::enable_if_t<(N!=-1), void>beforeBoundaryTreatment( HandlersTuple & boundaryHandlers );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type beforeBoundaryTreatment( const HandlersTuple & ) const {}
+   inline std::enable_if_t<(N==-1), void>beforeBoundaryTreatment( const HandlersTuple & ) const {}
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type  afterBoundaryTreatment( HandlersTuple & boundaryHandlers );
+   inline std::enable_if_t<(N!=-1), void> afterBoundaryTreatment( HandlersTuple & boundaryHandlers );
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type  afterBoundaryTreatment( const HandlersTuple & ) const {}
+   inline std::enable_if_t<(N==-1), void> afterBoundaryTreatment( const HandlersTuple & ) const {}
    //@}
    //*******************************************************************************************************************
 
@@ -508,23 +508,23 @@ private:
    inline CellInterval getUnpackingInterval( stencil::Direction direction, const uint_t numberOfLayers ) const;
 
    template< typename Buffer_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type pack( const HandlersTuple & boundaryHandlers, Buffer_T & buffer, const flag_t mask,
+   inline std::enable_if_t<(N!=-1), void>pack( const HandlersTuple & boundaryHandlers, Buffer_T & buffer, const flag_t mask,
                      const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const;
    template< typename Buffer_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type pack( const HandlersTuple &, Buffer_T &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const {}
+   inline std::enable_if_t<(N==-1), void>pack( const HandlersTuple &, Buffer_T &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const {}
 
    template< typename Buffer_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type unpack( HandlersTuple & boundaryHandlers, Buffer_T & buffer, const flag_t mask,
+   inline std::enable_if_t<(N!=-1), void>unpack( HandlersTuple & boundaryHandlers, Buffer_T & buffer, const flag_t mask,
                        const cell_idx_t x, const cell_idx_t y, const cell_idx_t z );
    template< typename Buffer_T, typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type unpack( const HandlersTuple &, Buffer_T &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const {}
+   inline std::enable_if_t<(N==-1), void>unpack( const HandlersTuple &, Buffer_T &, const flag_t, const cell_idx_t, const cell_idx_t, const cell_idx_t ) const {}
    //@}
    //*******************************************************************************************************************
 
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N!=-1), void>::type toStream( const HandlersTuple & boundaryHandlers, std::ostream & os ) const;
+   inline std::enable_if_t<(N!=-1), void>toStream( const HandlersTuple & boundaryHandlers, std::ostream & os ) const;
    template< typename HandlersTuple, int N = std::tuple_size<HandlersTuple>::value - 1 >
-   inline typename std::enable_if<(N==-1), void>::type toStream( const HandlersTuple &, std::ostream & ) const {}
+   inline std::enable_if_t<(N==-1), void>toStream( const HandlersTuple &, std::ostream & ) const {}
 
 
 
@@ -1110,9 +1110,7 @@ template< typename Buffer_T >
 void BoundaryHandlingCollection< FlagField_T, Handlers... >::pack( Buffer_T & buffer, stencil::Direction direction, const uint_t numberOfLayers,
                                                              const bool assumeIdenticalFlagMapping ) const
 {
-#ifdef NDEBUG
    if( !assumeIdenticalFlagMapping )
-#endif
       buffer << getFlagMapping();
 
    CellInterval interval = getPackingInterval( direction, numberOfLayers );
@@ -1201,7 +1199,7 @@ CellInterval BoundaryHandlingCollection< FlagField_T, Handlers... >::getGhostLay
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::isEmpty( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), bool>BoundaryHandlingCollection< FlagField_T, Handlers... >::isEmpty( const HandlersTuple & boundaryHandlers,
                                                                        const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const
 {
    if( !(std::get<N>( boundaryHandlers ).isEmpty(x,y,z)) )
@@ -1213,7 +1211,7 @@ inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::isEmpty( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), bool>BoundaryHandlingCollection< FlagField_T, Handlers... >::isEmpty( const HandlersTuple & boundaryHandlers,
                                                                        const ConstFlagFieldBaseIterator & it ) const
 {
    if( !(std::get<N>( boundaryHandlers ).isEmpty(it)) )
@@ -1225,7 +1223,7 @@ inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::consideredByAllHandlers( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), bool>BoundaryHandlingCollection< FlagField_T, Handlers... >::consideredByAllHandlers( const HandlersTuple & boundaryHandlers,
                                                                                          const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const
 {
    if( std::get<N>( boundaryHandlers ).isEmpty(x,y,z) )
@@ -1237,7 +1235,7 @@ inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::consideredByAllHandlers( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), bool>BoundaryHandlingCollection< FlagField_T, Handlers... >::consideredByAllHandlers( const HandlersTuple & boundaryHandlers,
                                                                                          const ConstFlagFieldBaseIterator & it ) const
 {
    if( std::get<N>( boundaryHandlers ).isEmpty(it) )
@@ -1249,7 +1247,7 @@ inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::checkForUniqueBoundaryHandlingUIDs( const HandlersTuple & boundaryHandlers ) const
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::checkForUniqueBoundaryHandlingUIDs( const HandlersTuple & boundaryHandlers ) const
 {
    if( numberOfMatchingBoundaryHandlers( std::get<N>( boundaryHandlers ).getUID() ) != uint_c(1) )
       WALBERLA_ABORT( "Every boundary handler registered at the same boundary handling collection must have a unique boundary handling UID!\n"
@@ -1272,7 +1270,7 @@ inline std::vector< BoundaryUID > BoundaryHandlingCollection< FlagField_T, Handl
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::getBoundaryUIDs( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::getBoundaryUIDs( const HandlersTuple & boundaryHandlers,
                                                                                std::vector< BoundaryUID > & uids ) const
 {
    std::vector< BoundaryUID > handlerUIDs = std::get<N>( boundaryHandlers ).getBoundaryUIDs();
@@ -1284,7 +1282,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::checkForIdenticalFlagFields( const HandlersTuple & boundaryHandlers ) const
+inline std::enable_if_t<(N!=-1), bool>BoundaryHandlingCollection< FlagField_T, Handlers... >::checkForIdenticalFlagFields( const HandlersTuple & boundaryHandlers ) const
 {
    return checkForIdenticalFlagFields< HandlersTuple, N-1 >( boundaryHandlers ) &&
           std::get<N>( boundaryHandlers ).getFlagField() == flagField_ && std::get<N>( boundaryHandlers ).outerBB_ == outerBB_;
@@ -1302,7 +1300,7 @@ inline uint_t BoundaryHandlingCollection< FlagField_T, Handlers... >::numberOfMa
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::numberOfMatchingBoundaryHandlers( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), uint_t>BoundaryHandlingCollection< FlagField_T, Handlers... >::numberOfMatchingBoundaryHandlers( const HandlersTuple & boundaryHandlers,
                                                                                                   const BoundaryHandlingUID & uid ) const
 {
    return ( ( std::get<N>( boundaryHandlers ).getUID() == uid ) ? uint_c(1) : uint_c(0) ) +
@@ -1313,7 +1311,7 @@ inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandlingCollection
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::numberOfMatchingHandlers( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), uint_t>BoundaryHandlingCollection< FlagField_T, Handlers... >::numberOfMatchingHandlers( const HandlersTuple & boundaryHandlers,
                                                                                           const flag_t flag ) const
 {
    return ( ( (std::get<N>( boundaryHandlers ).getBoundaryMask() | std::get<N>( boundaryHandlers ).getDomainMask()) & flag ) == flag ? 1 : 0 ) +
@@ -1324,7 +1322,7 @@ inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandlingCollection
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::numberOfMatchingHandlersForDomain( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), uint_t>BoundaryHandlingCollection< FlagField_T, Handlers... >::numberOfMatchingHandlersForDomain( const HandlersTuple & boundaryHandlers,
                                                                                                    const flag_t flag ) const
 {
    return ( ( std::get<N>( boundaryHandlers ).getDomainMask() & flag ) == flag ? 1 : 0 ) +
@@ -1335,7 +1333,7 @@ inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandlingCollection
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::numberOfMatchingHandlersForBoundary( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), uint_t>BoundaryHandlingCollection< FlagField_T, Handlers... >::numberOfMatchingHandlersForBoundary( const HandlersTuple & boundaryHandlers,
                                                                                                      const flag_t flag ) const
 {
    return ( ( std::get<N>( boundaryHandlers ).getBoundaryMask() & flag ) == flag ? 1 : 0 ) +
@@ -1346,7 +1344,7 @@ inline typename std::enable_if<(N!=-1), uint_t>::type BoundaryHandlingCollection
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::containsBoundaryCondition( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), bool>BoundaryHandlingCollection< FlagField_T, Handlers... >::containsBoundaryCondition( const HandlersTuple & boundaryHandlers,
                                                                                          const BoundaryUID & uid ) const
 {
    if( std::get<N>( boundaryHandlers ).containsBoundaryCondition( uid ) )
@@ -1358,7 +1356,7 @@ inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::containsBoundaryCondition( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), bool>BoundaryHandlingCollection< FlagField_T, Handlers... >::containsBoundaryCondition( const HandlersTuple & boundaryHandlers,
                                                                                          const flag_t flag ) const
 {
    if( std::get<N>( boundaryHandlers ).containsBoundaryCondition( flag ) )
@@ -1370,7 +1368,7 @@ inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), typename BoundaryHandlingCollection< FlagField_T, Handlers... >::flag_t>::type
+inline std::enable_if_t<(N!=-1), typename BoundaryHandlingCollection< FlagField_T, Handlers... >::flag_t>
    BoundaryHandlingCollection< FlagField_T, Handlers... >::getBoundaryMask( const HandlersTuple & boundaryHandlers,
                                                                       const BoundaryUID & uid ) const
 {
@@ -1383,7 +1381,7 @@ inline typename std::enable_if<(N!=-1), typename BoundaryHandlingCollection< Fla
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), BoundaryUID>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::getBoundaryUID( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), BoundaryUID>BoundaryHandlingCollection< FlagField_T, Handlers... >::getBoundaryUID( const HandlersTuple & boundaryHandlers,
                                                                                      const flag_t flag ) const
 {
    const auto & boundaryHandler = std::get<N>( boundaryHandlers );
@@ -1402,7 +1400,7 @@ inline typename std::enable_if<(N!=-1), BoundaryUID>::type BoundaryHandlingColle
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N==-1), BoundaryUID>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::getBoundaryUID( const HandlersTuple &, const flag_t flag ) const
+inline std::enable_if_t<(N==-1), BoundaryUID>BoundaryHandlingCollection< FlagField_T, Handlers... >::getBoundaryUID( const HandlersTuple &, const flag_t flag ) const
 {
    if( !flagField_->isRegistered( flag ) )
       WALBERLA_ABORT( "The requested flag with value " << flag << " is not registered at the flag field and is not handled "\
@@ -1417,7 +1415,7 @@ inline typename std::enable_if<(N==-1), BoundaryUID>::type BoundaryHandlingColle
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), shared_ptr<BoundaryConfiguration>>::type
+inline std::enable_if_t<(N!=-1), shared_ptr<BoundaryConfiguration>>
    BoundaryHandlingCollection< FlagField_T, Handlers... >::createBoundaryConfiguration( const HandlersTuple & boundaryHandlers,
                                                                                   const BoundaryUID & uid, const Config::BlockHandle & config ) const
 {
@@ -1430,7 +1428,7 @@ inline typename std::enable_if<(N!=-1), shared_ptr<BoundaryConfiguration>>::type
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::checkConsistency( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), bool>BoundaryHandlingCollection< FlagField_T, Handlers... >::checkConsistency( const HandlersTuple & boundaryHandlers,
                                                                                 const CellInterval & cells ) const
 {
    return checkConsistency< HandlersTuple, N-1 >( boundaryHandlers, cells ) && std::get<N>( boundaryHandlers ).checkConsistency(cells);
@@ -1440,7 +1438,7 @@ inline typename std::enable_if<(N!=-1), bool>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::refresh( HandlersTuple & boundaryHandlers, const CellInterval & cells )
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::refresh( HandlersTuple & boundaryHandlers, const CellInterval & cells )
 {
    std::get<N>( boundaryHandlers ).refresh( cells );
    refresh< HandlersTuple, N-1 >( boundaryHandlers, cells );
@@ -1450,7 +1448,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::refreshOutermostLayer( HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::refreshOutermostLayer( HandlersTuple & boundaryHandlers,
                                                                                      cell_idx_t thickness )
 {
    std::get<N>( boundaryHandlers ).refreshOutermostLayer( thickness );
@@ -1461,7 +1459,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::setFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
+std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::setFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
                                                                 const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
                                                                 const BoundaryConfiguration & parameter )
 {
@@ -1482,7 +1480,7 @@ typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagFie
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N==-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::setFlag( const HandlersTuple & /*boundaryHandlers*/, const flag_t flag,
+inline std::enable_if_t<(N==-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::setFlag( const HandlersTuple & /*boundaryHandlers*/, const flag_t flag,
                                                                        const cell_idx_t x, const cell_idx_t y, const cell_idx_t z,
                                                                        const BoundaryConfiguration & /*parameter*/ )
 {
@@ -1495,7 +1493,7 @@ inline typename std::enable_if<(N==-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::setFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
+std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::setFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
                                                                 const CellInterval & cells, const BoundaryConfiguration & parameter )
 {
    WALBERLA_ASSERT( outerBB_.contains(cells) );
@@ -1520,7 +1518,7 @@ typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagFie
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N==-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::setFlag( const HandlersTuple & /*boundaryHandlers*/, const flag_t flag,
+inline std::enable_if_t<(N==-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::setFlag( const HandlersTuple & /*boundaryHandlers*/, const flag_t flag,
                                                                        const CellInterval & cells, const BoundaryConfiguration & /*parameter*/ )
 {
    WALBERLA_ASSERT( outerBB_.contains(cells) );
@@ -1556,7 +1554,7 @@ void BoundaryHandlingCollection< FlagField_T, Handlers... >::forceFlagHelper( co
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), typename BoundaryHandlingCollection< FlagField_T, Handlers... >::flag_t>::type
+inline std::enable_if_t<(N!=-1), typename BoundaryHandlingCollection< FlagField_T, Handlers... >::flag_t>
 BoundaryHandlingCollection< FlagField_T, Handlers... >::flagsToRemove( HandlersTuple & boundaryHandlers, const flag_t flag,
                                                                  const cell_idx_t x, const cell_idx_t y, const cell_idx_t z )
 {
@@ -1577,7 +1575,7 @@ BoundaryHandlingCollection< FlagField_T, Handlers... >::flagsToRemove( HandlersT
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::removeFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
+std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::removeFlag( HandlersTuple & boundaryHandlers, const flag_t flag,
                                                                    const cell_idx_t x, const cell_idx_t y, const cell_idx_t z )
 {
    WALBERLA_ASSERT( outerBB_.contains(x,y,z) );
@@ -1597,7 +1595,7 @@ typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagFie
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N==-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::removeFlag( const HandlersTuple & /*boundaryHandlers*/, const flag_t flag,
+inline std::enable_if_t<(N==-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::removeFlag( const HandlersTuple & /*boundaryHandlers*/, const flag_t flag,
                                                                           const cell_idx_t x, const cell_idx_t y, const cell_idx_t z )
 {
    WALBERLA_ASSERT( outerBB_.contains(x,y,z) );
@@ -1609,7 +1607,7 @@ inline typename std::enable_if<(N==-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), typename BoundaryHandlingCollection< FlagField_T, Handlers... >::flag_t>::type
+inline std::enable_if_t<(N!=-1), typename BoundaryHandlingCollection< FlagField_T, Handlers... >::flag_t>
 BoundaryHandlingCollection< FlagField_T, Handlers... >::clear( HandlersTuple & boundaryHandlers,
                                                          const cell_idx_t x, const cell_idx_t y, const cell_idx_t z )
 {
@@ -1627,7 +1625,7 @@ BoundaryHandlingCollection< FlagField_T, Handlers... >::clear( HandlersTuple & b
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::execute( HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::execute( HandlersTuple & boundaryHandlers,
                                                                        const uint_t numberOfGhostLayersToInclude )
 {
    std::get<N>( boundaryHandlers )( numberOfGhostLayersToInclude );
@@ -1638,7 +1636,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::execute( HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::execute( HandlersTuple & boundaryHandlers,
                                                                        const cell_idx_t x, const cell_idx_t y, const cell_idx_t z )
 {
    std::get<N>( boundaryHandlers )(x,y,z);
@@ -1649,7 +1647,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::execute( HandlersTuple & boundaryHandlers, const CellInterval & cells )
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::execute( HandlersTuple & boundaryHandlers, const CellInterval & cells )
 {
    std::get<N>( boundaryHandlers )( cells );
    execute< HandlersTuple, N-1 >( boundaryHandlers, cells );
@@ -1659,7 +1657,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename CellIterator, typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::execute( HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::execute( HandlersTuple & boundaryHandlers,
                                                                        const CellIterator & begin, const CellIterator & end )
 {
    std::get<N>( boundaryHandlers )( begin, end );
@@ -1670,7 +1668,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::beforeBoundaryTreatment( HandlersTuple & boundaryHandlers )
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::beforeBoundaryTreatment( HandlersTuple & boundaryHandlers )
 {
    std::get<N>( boundaryHandlers ).beforeBoundaryTreatment();
    beforeBoundaryTreatment< HandlersTuple, N-1 >( boundaryHandlers );
@@ -1680,7 +1678,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::afterBoundaryTreatment( HandlersTuple & boundaryHandlers )
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::afterBoundaryTreatment( HandlersTuple & boundaryHandlers )
 {
    std::get<N>( boundaryHandlers ).afterBoundaryTreatment();
    afterBoundaryTreatment< HandlersTuple, N-1 >( boundaryHandlers );
@@ -1716,7 +1714,7 @@ inline CellInterval BoundaryHandlingCollection< FlagField_T, Handlers... >::getU
 
 template< typename FlagField_T, typename... Handlers >
 template< typename Buffer_T, typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::pack( const HandlersTuple & boundaryHandlers, Buffer_T & buffer,
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::pack( const HandlersTuple & boundaryHandlers, Buffer_T & buffer,
                                                                     const flag_t mask, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z ) const
 {
    std::get<0>( boundaryHandlers_ ).pack( buffer, mask, x, y, z );
@@ -1727,7 +1725,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename Buffer_T, typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::unpack( HandlersTuple & boundaryHandlers, Buffer_T & buffer,
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::unpack( HandlersTuple & boundaryHandlers, Buffer_T & buffer,
                                                                       const flag_t mask, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z )
 {
    WALBERLA_ASSERT( outerBB_.contains(x,y,z) );
@@ -1748,7 +1746,7 @@ inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection<
 
 template< typename FlagField_T, typename... Handlers >
 template< typename HandlersTuple, int N >
-inline typename std::enable_if<(N!=-1), void>::type BoundaryHandlingCollection< FlagField_T, Handlers... >::toStream( const HandlersTuple & boundaryHandlers,
+inline std::enable_if_t<(N!=-1), void>BoundaryHandlingCollection< FlagField_T, Handlers... >::toStream( const HandlersTuple & boundaryHandlers,
                                                                         std::ostream & os ) const
 {
    os << std::get<N>( boundaryHandlers );
@@ -1772,4 +1770,4 @@ inline std::ostream & operator<<( std::ostream & os, const BoundaryHandlingColle
 
 
 
-} // namespace walberla
+} // namespace walberla
\ No newline at end of file
diff --git a/src/core/DataTypes.h b/src/core/DataTypes.h
index d6147c12be61a072f112e49de6e68001a6013abc..2428b19fa540dd4d34107116e5e920739b99a146 100644
--- a/src/core/DataTypes.h
+++ b/src/core/DataTypes.h
@@ -55,7 +55,7 @@ using std::dynamic_pointer_cast;
 template< typename S, typename T >
 inline S numeric_cast( T t ) {
 #ifndef NDEBUG
-   if( std::is_integral<S>::value && std::is_integral<T>::value && !std::is_same<S,T>::value )
+   if( std::is_integral_v<S> && std::is_integral_v<T> && !std::is_same_v<S,T> )
         // integer to different integer: check that forward and back conversion does not change value
    {
       if( !isIdentical( static_cast<T>( static_cast<S>(t) ), t ) )
@@ -63,19 +63,19 @@ inline S numeric_cast( T t ) {
          throw std::range_error("out of range");
       }
    }
-   else if( !std::is_integral<S>::value && !std::is_integral<T>::value && sizeof(S) < sizeof(T) )
+   else if( !std::is_integral_v<S> && !std::is_integral_v<T> && sizeof(S) < sizeof(T) )
        // float to shorter float: check that value within limits of shorter type
    {
-      using H = typename std::conditional< !std::is_integral<S>::value && !std::is_integral<T>::value && (sizeof(S) < sizeof(T)), T, long double >::type; // always true, but makes Intel's overflow check happy
+      using H = typename std::conditional_t< !std::is_integral_v<S> && !std::is_integral_v<T> && (sizeof(S) < sizeof(T)), T, long double >; // always true, but makes Intel's overflow check happy
       H h = static_cast<H>(t);
       if( h < static_cast<H>(std::numeric_limits<S>::lowest()) || h > static_cast<H>(std::numeric_limits<S>::max()) ) {
          throw std::range_error("out of range");
       }
    }
-   else if( std::is_integral<S>::value && !std::is_integral<T>::value )
+   else if( std::is_integral_v<S> && !std::is_integral_v<T> )
        // float to integer: check that value within limits of integer
    {
-      using H = typename std::conditional< std::is_integral<S>::value && !std::is_integral<T>::value, T, long double >::type; // always true, but makes Intel's overflow check happy
+      using H = typename std::conditional_t< std::is_integral_v<S> && !std::is_integral_v<T>, T, long double >; // always true, but makes Intel's overflow check happy
       H h = static_cast<H>(t);
       if( h < static_cast<H>(std::numeric_limits<S>::lowest()) || h > static_cast<H>(std::numeric_limits<S>::max()) ) {
          throw std::range_error("out of range");
diff --git a/src/core/EndianIndependentSerialization.h b/src/core/EndianIndependentSerialization.h
index b45b19c8ed73a29b6c0a5fb22b74e88d5f117459..96278b4b4cfe883c91078d9c5b7ffbb88cb1400b 100644
--- a/src/core/EndianIndependentSerialization.h
+++ b/src/core/EndianIndependentSerialization.h
@@ -147,7 +147,7 @@ REAL_T byteArrayToReal( const std::vector< uint8_t >& array, const uint_t offset
 
 inline void boolVectorToByteArray( const std::vector< bool >& boolVec, std::vector< uint8_t >& array, const uint_t offset )
 {
-   static const uint_t bit[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+   static const std::array< uint_t, 8 > bit = { 1, 2, 4, 8, 16, 32, 64, 128 };
 
    WALBERLA_ASSERT_EQUAL( boolVec.size() % 8, uint_t(0) );
    const uint_t bytes =  uint_c(boolVec.size() / 8);
@@ -163,7 +163,7 @@ inline void boolVectorToByteArray( const std::vector< bool >& boolVec, std::vect
 
 inline std::vector< bool > byteArrayToBoolVector( const std::vector< uint8_t >& array, const uint_t offset, const uint_t bytes )
 {
-   static const uint8_t bit[] = { 1, 2, 4, 8, 16, 32, 64, 128 };
+   static const std::array< uint8_t, 8 > bit = { 1, 2, 4, 8, 16, 32, 64, 128 };
 
    WALBERLA_ASSERT_LESS_EQUAL( offset + bytes, array.size() );
 
diff --git a/src/core/Environment.cpp b/src/core/Environment.cpp
index 684f6f8e22dcdb50106591111fc1b0ce2591345d..9a7521b544a9256c27a8ca732b63276e298ac333 100644
--- a/src/core/Environment.cpp
+++ b/src/core/Environment.cpp
@@ -85,8 +85,8 @@ void configureGlobalState( const shared_ptr<Config> & config ) {
       states.erase( std::remove_if( states.begin(), states.end(), [](auto &s){ return s.empty(); } ), states.end() );
 
       Set<SUID> state;
-      for( auto it = states.begin(); it != states.end(); ++it )
-         state += SUID( *it );
+      for(auto & it : states)
+         state += SUID( it );
 
       uid::GlobalState::instance()->configure( state );
    }
diff --git a/src/core/Format.hpp b/src/core/Format.hpp
index c535b43348e0b870f24ca17d825e6645213c80ea..87977c5a0ec91600f2b1fdcc790955e3cee58b5e 100644
--- a/src/core/Format.hpp
+++ b/src/core/Format.hpp
@@ -37,10 +37,10 @@ std::string format(const std::string& formatString, Args&&... args)
 {
    /// this size is arbitrary
    const size_t maxBufferSize = 4096;
-   char buffer[maxBufferSize];
+   std::array< char, maxBufferSize > buffer;
    int check = snprintf(buffer, maxBufferSize, formatString.c_str(), args...);
    if (check <= 0 || check > int(maxBufferSize)) { WALBERLA_ABORT("snprintf failed"); }
-   return std::string(buffer);
+   return { buffer.data() };
 }
 
 } // namespace walberla
\ No newline at end of file
diff --git a/src/core/FunctionTraits.h b/src/core/FunctionTraits.h
index cc8b1e35f0f7d1aca1436507e4b971bd01170050..bc73ad1e7f45ec8aa776c07c6122353b4596cf93 100644
--- a/src/core/FunctionTraits.h
+++ b/src/core/FunctionTraits.h
@@ -53,7 +53,7 @@ struct FunctionTraits< R( Args... ) >
    struct argument
    {
       static_assert(N < arity, "Error: Parameter index is not valid!");
-      using type = typename std::tuple_element< N, std::tuple<Args...> >::type;
+      using type = typename std::tuple_element_t< N, std::tuple<Args...> >;
    };
 };
 
diff --git a/src/core/Hostname.cpp b/src/core/Hostname.cpp
index 04b20dbb08c17dcde26d81f82fb2cda05755e9b7..c977590b0304a1cc24af53ea366566a6e660d7c4 100644
--- a/src/core/Hostname.cpp
+++ b/src/core/Hostname.cpp
@@ -21,6 +21,8 @@
 
 #include "Hostname.h"
 
+#include <array>
+
 #include "waLBerlaDefinitions.h"
 
 #ifdef WALBERLA_CXX_COMPILER_IS_MSVC
@@ -36,9 +38,9 @@ namespace walberla {
 
 std::string getHostName()
 {
-   char hostname[255];
-   gethostname( hostname, 255 );
-   return std::string( hostname );
+   std::array< char, 255 > hostname;
+   gethostname(hostname.data(), 255);
+   return { hostname.data() };
 }
 
 } // namespace walberla
diff --git a/src/core/NonCopyable.h b/src/core/NonCopyable.h
index 59b7773d23cd77c8daed1e76928d85567af0595d..226cdd5fe8ba66e70b15d2d13283afc1ecc8da1b 100644
--- a/src/core/NonCopyable.h
+++ b/src/core/NonCopyable.h
@@ -39,10 +39,10 @@ protected:
     NonCopyable()= default; // no object of type 'NonCopyable' can be created!
    ~NonCopyable()= default;
 
-private:
+public:
 
-   NonCopyable( const NonCopyable& );
-   NonCopyable& operator=( const NonCopyable& );
+   NonCopyable( const NonCopyable& ) = delete;
+   NonCopyable& operator=( const NonCopyable& ) = delete;
 
 };
 
diff --git a/src/core/OpenMP.h b/src/core/OpenMP.h
index 5e454f37fdf463a117c17d0711ecd2901c5e4fb1..d5b51cee8db14c0c6487abcb67d38adc3633e340 100644
--- a/src/core/OpenMP.h
+++ b/src/core/OpenMP.h
@@ -63,22 +63,22 @@ inline void    omp_set_max_active_levels (int) { WALBERLA_OPENMP_FUNCTION_ERROR
 inline void    omp_set_schedule          (omp_sched_t, int) { WALBERLA_OPENMP_FUNCTION_ERROR }
 
 /* query API functions */
-inline int     omp_get_num_threads  (void) { return 1; }
-inline int     omp_get_dynamic      (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int     omp_get_nested       (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int     omp_get_max_threads  (void) { return 1; }
-inline int     omp_get_thread_num   (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int     omp_get_num_procs    (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int     omp_in_parallel      (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int     omp_in_final         (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int     omp_get_active_level        (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int     omp_get_level               (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_get_num_threads  () { return 1; }
+inline int     omp_get_dynamic      () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_get_nested       () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_get_max_threads  () { return 1; }
+inline int     omp_get_thread_num   () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_get_num_procs    () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_in_parallel      () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_in_final         () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_get_active_level        () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_get_level               () { WALBERLA_OPENMP_FUNCTION_ERROR }
 inline int     omp_get_ancestor_thread_num (int) { WALBERLA_OPENMP_FUNCTION_ERROR }
 inline int     omp_get_team_size           (int) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int     omp_get_thread_limit        (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int     omp_get_max_active_levels   (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_get_thread_limit        () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_get_max_active_levels   () { WALBERLA_OPENMP_FUNCTION_ERROR }
 inline void    omp_get_schedule            (omp_sched_t *, int *) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int     omp_get_max_task_priority   (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int     omp_get_max_task_priority   () { WALBERLA_OPENMP_FUNCTION_ERROR }
 
 /* lock API functions */
 using omp_lock_t = struct omp_lock_t {
@@ -119,21 +119,21 @@ inline void omp_init_lock_with_hint(omp_lock_t *, omp_lock_hint_t) { WALBERLA_OP
 inline void omp_init_nest_lock_with_hint(omp_nest_lock_t *, omp_lock_hint_t) { WALBERLA_OPENMP_FUNCTION_ERROR }
 
 /* time API functions */
-inline double  omp_get_wtime (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline double  omp_get_wtick (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline double  omp_get_wtime () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline double  omp_get_wtick () { WALBERLA_OPENMP_FUNCTION_ERROR }
 
 /* OpenMP 4.0 */
-inline int   omp_get_default_device (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int   omp_get_default_device () { WALBERLA_OPENMP_FUNCTION_ERROR }
 inline void  omp_set_default_device (int) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int   omp_is_initial_device (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int   omp_get_num_devices (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int   omp_get_num_teams (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int   omp_get_team_num (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int   omp_get_cancellation (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int   omp_is_initial_device () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int   omp_get_num_devices () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int   omp_get_num_teams () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int   omp_get_team_num () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int   omp_get_cancellation () { WALBERLA_OPENMP_FUNCTION_ERROR }
 
 #   include <stdlib.h> // NOLINT(modernize-deprecated-headers)
 /* OpenMP 4.5 */
-inline int    omp_get_initial_device (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int    omp_get_initial_device () { WALBERLA_OPENMP_FUNCTION_ERROR }
 inline void*  omp_target_alloc(size_t, int) { WALBERLA_OPENMP_FUNCTION_ERROR }
 inline void   omp_target_free(void *, int) { WALBERLA_OPENMP_FUNCTION_ERROR }
 inline int    omp_target_is_present(void *, int) { WALBERLA_OPENMP_FUNCTION_ERROR }
@@ -152,14 +152,14 @@ using omp_proc_bind_t = enum omp_proc_bind_t {
     omp_proc_bind_spread = 4
 };
 
-inline omp_proc_bind_t omp_get_proc_bind (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline omp_proc_bind_t omp_get_proc_bind () { WALBERLA_OPENMP_FUNCTION_ERROR }
 
 /* OpenMP 4.5 affinity API */
-inline int  omp_get_num_places (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int  omp_get_num_places () { WALBERLA_OPENMP_FUNCTION_ERROR }
 inline int  omp_get_place_num_procs (int) { WALBERLA_OPENMP_FUNCTION_ERROR }
 inline void omp_get_place_proc_ids (int, int *) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int  omp_get_place_num (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
-inline int  omp_get_partition_num_places (void) { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int  omp_get_place_num () { WALBERLA_OPENMP_FUNCTION_ERROR }
+inline int  omp_get_partition_num_places () { WALBERLA_OPENMP_FUNCTION_ERROR }
 inline void omp_get_partition_place_nums (int *) { WALBERLA_OPENMP_FUNCTION_ERROR }
 
 } //namespace walberla
diff --git a/src/core/STLIO.h b/src/core/STLIO.h
index db122e1eda260e90044c608523ac60e809a4803b..b9c80e1051a70686493b3a68476a040991bbde73 100644
--- a/src/core/STLIO.h
+++ b/src/core/STLIO.h
@@ -66,7 +66,7 @@ template< typename Container >
 class ContainerStreamReader
 {
 public:
-   ContainerStreamReader( std::istream& is ) : is_( is ), success_(false)
+   ContainerStreamReader( std::istream& is ) : is_( is )
    {
    }
    
@@ -132,7 +132,7 @@ private:
    std::istream& is_;
    std::istream::pos_type oldPos_;
    std::istream::fmtflags oldFlags_;
-   bool success_;   
+   bool success_{false};
 };
 
 //**********************************************************************************************************************
diff --git a/src/core/VectorTrait.h b/src/core/VectorTrait.h
index 82d60ef0bdd1ddf51193c9b7840d097d8fcfd99f..c99eb3ef8ea1b6790f75534e07df0bc80efd3b95 100644
--- a/src/core/VectorTrait.h
+++ b/src/core/VectorTrait.h
@@ -44,7 +44,7 @@ struct VectorTrait
 };
 
 template< typename T >
-struct VectorTrait<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
+struct VectorTrait<T, std::enable_if_t<std::is_arithmetic_v<T>>>
 {
    using OutputType = T;
 
diff --git a/src/core/cell/Cell.h b/src/core/cell/Cell.h
index f531430ea1733cca2ccf650a944bd92301d623cd..701b10e9c85434a6238e264881823d7117f0316e 100644
--- a/src/core/cell/Cell.h
+++ b/src/core/cell/Cell.h
@@ -91,8 +91,7 @@ public:
    bool positiveIndicesOnly() const { return x() >= cell_idx_c(0) && y() >= cell_idx_c(0) && z() >= cell_idx_c(0); }
 
 private:
-
-   cell_idx_t cell[3]; ///< Array of the cells coordinates. cell == {x, y, z}.
+   std::array< cell_idx_t, 3 > cell; ///< Array of the cells coordinates. cell == {x, y, z}.
 };
 
 
@@ -129,8 +128,8 @@ inline Cell::Cell( const Vector3<uint_t> _vec )
  **********************************************************************************************************************/
 inline bool Cell::operator<( const Cell & rhs ) const
 {
-   return std::lexicographical_compare( std::reverse_iterator<const cell_idx_t*>( this->cell + 3 ), std::reverse_iterator<const cell_idx_t*>( this->cell ),
-                                        std::reverse_iterator<const cell_idx_t*>( rhs.cell + 3 ),   std::reverse_iterator<const cell_idx_t*>( rhs.cell ) );
+   return std::lexicographical_compare( std::reverse_iterator<const cell_idx_t*>( this->cell.data() + 3 ), std::reverse_iterator<const cell_idx_t*>( this->cell.data() ),
+                                        std::reverse_iterator<const cell_idx_t*>( rhs.cell.data() + 3 ),   std::reverse_iterator<const cell_idx_t*>( rhs.cell.data() ) );
 }
 
 
@@ -245,7 +244,7 @@ inline Cell Cell::operator+() const
  **********************************************************************************************************************/
 inline Cell Cell::operator-() const
 {
-   return Cell( -x(), -y(), -z() );
+   return { -x(), -y(), -z() };
 }
 
 
diff --git a/src/core/cell/CellInterval.cpp b/src/core/cell/CellInterval.cpp
index 786644d9902c92ab7f703802d64659dcb73842ff..7cd7c07031475de4ef29b8c3cedc9f6ef8b208b1 100644
--- a/src/core/cell/CellInterval.cpp
+++ b/src/core/cell/CellInterval.cpp
@@ -34,9 +34,9 @@ bool CellInterval::overlaps( const CellSet& cellSet ) const {
    if( empty() )
       return false;
 
-   for( CellSet::const_iterator cell = cellSet.begin(); cell != cellSet.end(); ++cell ) {
-      if( this->contains( *cell ) )
-         return true;
+   if (std::any_of(cellSet.begin(), cellSet.end(), [this](const auto& cell) { return this->contains(cell); }))
+   {
+      return true;
    }
 
    return false;
diff --git a/src/core/cell/CellInterval.h b/src/core/cell/CellInterval.h
index 6019ac71ce9a188998e7c13e463796f18df0336c..84af0b54aaa3349aa52bbb6616f61eaae0372ce8 100644
--- a/src/core/cell/CellInterval.h
+++ b/src/core/cell/CellInterval.h
@@ -191,7 +191,7 @@ CellInterval::const_iterator CellInterval::begin() const
    if( empty() )
       return end();
    else
-      return CellIntervalIterator(*this, min());
+      return { *this, min() };
 }
 
 CellInterval::const_iterator CellInterval::end()   const { return ++CellIntervalIterator(*this, max()); }
diff --git a/src/core/cell/CellSet.h b/src/core/cell/CellSet.h
index 09696492c422a4ed8d521031caea2f76064af44e..d8d18ee3af520355d400da0a249ced6be2958332 100644
--- a/src/core/cell/CellSet.h
+++ b/src/core/cell/CellSet.h
@@ -46,8 +46,8 @@ public:
    CellSet( const Cell& element ) : Set<Cell>( element ) {}
 
    CellSet( const CellVector& cells ) {
-      for( CellVector::const_iterator cell = cells.begin(); cell != cells.end(); ++cell )
-         Set<Cell>::insert( *cell );
+      for(auto cell : cells)
+         Set<Cell>::insert( cell );
    }
 
    using Set<Cell>::insert;
@@ -62,7 +62,7 @@ public:
 
    CellInterval boundingBox() const;
 
-   void pushToCellVector( CellVector& cellVector ) const { for( auto cell = begin(); cell != end(); ++cell ) cellVector.push_back( *cell ); }
+   void pushToCellVector( CellVector& cellVector ) const { for(auto cell : *this) cellVector.push_back( cell ); }
 
 }; // class CellSet
 
diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp
index 75a9cf41127ce25f633796fbbe3e37a0c2b6182c..5b844cd44a8e34580b877d5467202e4f6e41b9a9 100644
--- a/src/core/config/Config.cpp
+++ b/src/core/config/Config.cpp
@@ -44,9 +44,8 @@ namespace config {
 // \brief Default constructor for the Config class.
  */
 Config::Config()
-     : stateFlag_(true) // Internal status flag
-     , error_()         // Container for all error messages
-     , block_()         // Global parameter block
+   : error_(), // Container for all error messages
+     block_()  // Global parameter block
 {}
 //**********************************************************************************************************************
 
@@ -516,8 +515,8 @@ Config::Block::~Block()
 Config::size_type Config::Block::getNumBlocks( const std::string& key ) const
 {
    size_type c = 0;
-   for( List::const_iterator it=blocks_.begin(); it!=blocks_.end(); ++it ) {
-      if( string_icompare( key, it->getKey() ) == 0 ) {
+   for(const auto & block : blocks_) {
+      if( string_icompare( key, block.getKey() ) == 0 ) {
          ++c;
       }
    }
@@ -538,7 +537,7 @@ Config::BlockHandle Config::Block::getBlock( const std::string& key ) const {
    Blocks blocks;
    getBlocks( key, blocks, 0, 1 );
    if( blocks.empty() )
-      return BlockHandle();
+      return {};
    return blocks[0];
 }
 
@@ -570,9 +569,9 @@ Config::BlockHandle Config::Block::getOneBlock( const std::string& key ) const
 void Config::Block::getBlocks( const std::string& key, Blocks& blocks, size_t min, size_t max ) const
 {
    size_t c = 0;
-   for( List::const_iterator it=blocks_.begin(); it!=blocks_.end(); ++it ) {
-      if( string_icompare( key, it->getKey() ) == 0 ) {
-         blocks.emplace_back( &*it );
+   for(const auto & block : blocks_) {
+      if( string_icompare( key, block.getKey() ) == 0 ) {
+         blocks.emplace_back( &block );
          ++c;
       }
    }
@@ -594,8 +593,8 @@ void Config::Block::getBlocks( const std::string& key, Blocks& blocks, size_t mi
  */
 void Config::Block::getBlocks( Blocks& blocks ) const
 {
-   for( List::const_iterator it=blocks_.begin(); it!=blocks_.end(); ++it ) {
-      blocks.emplace_back( &*it );
+   for(const auto & block : blocks_) {
+      blocks.emplace_back( &block );
    }
 }
 //**********************************************************************************************************************
@@ -609,8 +608,8 @@ void Config::Block::getBlocks( Blocks& blocks ) const
  */
 void Config::Block::getWritableBlocks( std::vector<Block*> & blocks )
 {
-   for( List::iterator it=blocks_.begin(); it!=blocks_.end(); ++it ) {
-      blocks.emplace_back( &*it );
+   for(auto & block : blocks_) {
+      blocks.emplace_back( &block );
    }
 }
 //**********************************************************************************************************************
@@ -628,9 +627,9 @@ void Config::Block::getWritableBlocks( std::vector<Block*> & blocks )
 void Config::Block::getWritableBlocks( const std::string & key, std::vector<Block*> & blocks, size_t min, size_t max )
 {
    size_t c = 0;
-   for( List::iterator it=blocks_.begin(); it!=blocks_.end(); ++it ) {
-      if( string_icompare( key, it->getKey() ) == 0 ) {
-         blocks.emplace_back( &*it );
+   for(auto & block : blocks_) {
+      if( string_icompare( key, block.getKey() ) == 0 ) {
+         blocks.emplace_back( &block );
          ++c;
       }
    }
@@ -690,8 +689,8 @@ Config::Block& Config::Block::createBlock( const std::string& key )
  */
 void Config::Block::listParameters() const
 {
-   for( Map::const_iterator it=params_.begin(); it!=params_.end(); ++it ) {
-      std::cout << " Key = '" << it->first << "' , Value = '" << it->second << "'\n";
+   for(const auto & param : params_) {
+      std::cout << " Key = '" << param.first << "' , Value = '" << param.second << "'\n";
    }
 }
 //**********************************************************************************************************************
@@ -705,11 +704,11 @@ void Config::Block::listParameters() const
 std::string Config::Block::getString() const
 {
    std::string ret="";
-   for( Map::const_iterator it=params_.begin(); it!=params_.end(); ++it ) {
-      ret += it->first + " " + it->second + ";";
+   for(const auto & param : params_) {
+      ret += param.first + " " + param.second + ";";
    }
-   for( List::const_iterator it=blocks_.begin(); it!=blocks_.end(); ++it ) {
-      ret += it->key_ + "{" + it->getString() + "}";
+   for(const auto & block : blocks_) {
+      ret += block.key_ + "{" + block.getString() + "}";
    }
    return ret;
 }
@@ -742,12 +741,12 @@ static void printConfig( std::ostream & os, const Config::BlockHandle & block, i
       os << prefix.str() << "{\n";
    }
 
-   for( auto subBlock = subBlocks.begin(); subBlock != subBlocks.end(); ++subBlock )
-      printConfig( os, *subBlock, depth+1);
+   for(auto & subBlock : subBlocks)
+      printConfig( os, subBlock, depth+1);
 
-   for( auto paramIt = block.begin(); paramIt != block.end(); ++paramIt ) {
-      std::string key = paramIt->first;
-      std::string value = paramIt->second;
+   for(const auto & paramIt : block) {
+      std::string key = paramIt.first;
+      std::string value = paramIt.second;
       string_trim( key );
       string_trim( value );
       os << prefix.str() << "   " << key << " " << value << ";\n";
diff --git a/src/core/config/Config.h b/src/core/config/Config.h
index 00e56397d306f4f41860aafdbde65e1c97203fdb..99bf453955244e47afb86109aa496986c06b9a8d 100644
--- a/src/core/config/Config.h
+++ b/src/core/config/Config.h
@@ -395,7 +395,7 @@ private:
    //**Member variables*************************************************************************************************
    /*! \name Member variables */
    //@{
-   bool stateFlag_;             //!< Internal status of the config object.
+   bool stateFlag_ = true;      //!< Internal status of the config object.
                                 /*!< An error is indicated by \p false. */
    std::ostringstream error_;   //!< Container for all error messages.
    Block block_;                //!< The global parameter block.
@@ -623,7 +623,7 @@ inline void Config::getBlocks( Blocks& blocks ) const
  */
 inline Config::BlockHandle Config::getGlobalBlock() const
 {
-   return BlockHandle( &block_ );
+   return { &block_ };
 }
 //*******************************************************
 
@@ -667,8 +667,8 @@ void Config::listParameters() const
  */
 inline void Config::convertToLowerCase( std::string& s )
 {
-   for( std::string::size_type i=0; i<s.size(); ++i ) {
-      s[i] = (char)std::tolower( s[i] );
+   for(char & i : s) {
+      i = (char)std::tolower( i );
    }
 }
 //**********************************************************************************************************************
diff --git a/src/core/config/Create.cpp b/src/core/config/Create.cpp
index 1d3c7296540931f88508712b6dc58abded97bea1..793be4e157c6d9a82332059990f87e2a615a7aff 100644
--- a/src/core/config/Create.cpp
+++ b/src/core/config/Create.cpp
@@ -106,9 +106,9 @@ namespace config {
       using std::vector;
       using std::string;
 
-      for( auto param = params.begin(); param != params.end(); ++param )
+      for(const auto & param : params)
       {
-         vector< string > equalitySignSplitResult = string_split( *param, "=" );
+         vector< string > equalitySignSplitResult = string_split( param, "=" );
 
          std::string value;
          if ( equalitySignSplitResult.empty() )
@@ -124,7 +124,7 @@ namespace config {
          }
          else
          {
-            WALBERLA_LOG_WARNING( "Ignoring illegally formed command line parameter: '" << *param << "'  (Multiple '='s )");
+            WALBERLA_LOG_WARNING( "Ignoring illegally formed command line parameter: '" << param << "'  (Multiple '='s )");
             continue;
          }
 
@@ -133,7 +133,7 @@ namespace config {
          vector< string > blocks = string_split( blockDescriptor, "." );
 
          if ( blocks.empty() ) {
-            WALBERLA_LOG_WARNING( "Ignoring Parameter: Missing block descriptor on left hand side: '" << *param <<"'" );
+            WALBERLA_LOG_WARNING( "Ignoring Parameter: Missing block descriptor on left hand side: '" << param <<"'" );
             continue;
          }
 
@@ -146,7 +146,7 @@ namespace config {
             if ( blockName.empty() )
             {
                currentBlock = nullptr;
-               WALBERLA_LOG_WARNING("Ignoring Parameter '" << *param << "' empty block name");
+               WALBERLA_LOG_WARNING("Ignoring Parameter '" << param << "' empty block name");
                break;
             }
             vector< Config::Block * > possibleBlocks;
@@ -154,7 +154,7 @@ namespace config {
             if ( possibleBlocks.size() > 1 )
             {
                currentBlock = nullptr;
-               WALBERLA_LOG_WARNING("Ignoring Parameter '" << *param << "' since block is ambiguous: " << blockName );
+               WALBERLA_LOG_WARNING("Ignoring Parameter '" << param << "' since block is ambiguous: " << blockName );
                break;
             }
             else if ( possibleBlocks.empty() ) {
@@ -171,7 +171,7 @@ namespace config {
          string_trim( blocks.back() );
          if ( blocks.back().empty() )
          {
-            WALBERLA_LOG_WARNING( "Ignoring Parameter '" << *param << "' since key is empty");
+            WALBERLA_LOG_WARNING( "Ignoring Parameter '" << param << "' since key is empty");
             continue;
          }
          else
@@ -212,7 +212,7 @@ namespace config {
    {
    public:
       MultipleConfigGenerator( const std::string & baseName, const std::string & extension, int numberOfDigits )
-         : baseName_( baseName ), extension_( extension ), numberOfDigits_( numberOfDigits), counter_(-1) {}
+         : baseName_( baseName ), extension_( extension ), numberOfDigits_( numberOfDigits) {}
 
       shared_ptr<Config> next() override
       {
@@ -231,7 +231,7 @@ namespace config {
       std::string baseName_;
       std::string extension_;
       int numberOfDigits_;
-      int counter_;
+      int counter_{-1};
    };
 
 
@@ -275,7 +275,7 @@ namespace config {
          auto config = make_shared<Config>();
          createFromTextFile( *config, filename );
          substituteCommandLineArgs( *config, argc, argv );
-         return config::Iterator( make_shared<SingleConfigGenerator> ( config ) );
+         return { make_shared< SingleConfigGenerator >(config) };
       }
    }
 
@@ -283,7 +283,7 @@ namespace config {
    {
       // Intel compiler complains when casting shared_ptr<MultipleConfigGenerator> to shared_ptr<ConfigGenerator>
       ConfigGenerator * cg = new MultipleConfigGenerator( basename, extension, nrOfDigits );
-      return Iterator( shared_ptr<config::ConfigGenerator>(cg) );
+      return { shared_ptr< config::ConfigGenerator >(cg) };
    }
 
 
diff --git a/src/core/config/Create.h b/src/core/config/Create.h
index 3c92f3f685c13c29bf13f8ed9eeab8fac50cbe4b..b1e5bb141c3c83981f2b0e9f900b3358f83c8ccb 100644
--- a/src/core/config/Create.h
+++ b/src/core/config/Create.h
@@ -68,7 +68,7 @@ namespace config {
    */
    //*******************************************************************************************************************
           Iterator begin( int argc, char ** argv);
-   inline Iterator end()                           { return config::Iterator(); }
+   inline Iterator end()                           { return {}; }
 
 
 
diff --git a/src/core/debug/CheckFunctions.impl.h b/src/core/debug/CheckFunctions.impl.h
index e4615bc0e1aaeca998385b5b8352bd00d05efa3a..85b1ecb6ced4a3619831d20e2510fba313f577d5 100644
--- a/src/core/debug/CheckFunctions.impl.h
+++ b/src/core/debug/CheckFunctions.impl.h
@@ -61,7 +61,7 @@ inline bool check_not_nullptr( const shared_ptr<T> & p )
 template< typename T, typename U >
 inline bool check_equal( const T & lhs, const U & rhs )
 {
-   using truth_type = std::integral_constant<bool, std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>;
+   using truth_type = std::integral_constant<bool, std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>;
    return check_equal( lhs, rhs, truth_type() );
 }
 
@@ -81,7 +81,7 @@ inline bool check_equal( const T & lhs, const U & rhs, const std::false_type & )
 template< typename T, typename U >
 inline bool check_unequal( const T & lhs, const U & rhs )
 {
-   using truth_type = std::integral_constant<bool, std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>;
+   using truth_type = std::integral_constant<bool, std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>;
    return check_unequal( lhs, rhs, truth_type() );
 }
 
@@ -101,8 +101,8 @@ inline bool check_unequal( const T & lhs, const U & rhs, const std::false_type &
 template< typename T, typename U >
 inline bool check_float_equal( const T & lhs, const U & rhs )
 {
-   static_assert( std::is_floating_point<T>::value,  "First operand type T is not a floating point type!");
-   static_assert( std::is_floating_point<U>::value, "Second operand type U is not a floating point type!");
+   static_assert( std::is_floating_point_v<T>,  "First operand type T is not a floating point type!");
+   static_assert( std::is_floating_point_v<U>, "Second operand type U is not a floating point type!");
 
    using LowType = typename math::MathTrait<T, U>::Low;
 
@@ -115,8 +115,8 @@ inline bool check_float_equal( const T & lhs, const U & rhs )
 template< typename T, typename U >
 inline bool check_float_unequal( const T & lhs, const U & rhs )
 {
-   static_assert( std::is_floating_point<T>::value,  "First operand type T is not a floating point type!");
-   static_assert( std::is_floating_point<U>::value, "Second operand type U is not a floating point type!");
+   static_assert( std::is_floating_point_v<T>,  "First operand type T is not a floating point type!");
+   static_assert( std::is_floating_point_v<U>, "Second operand type U is not a floating point type!");
 
    using LowType = typename math::MathTrait<T, U>::Low;
 
@@ -130,8 +130,8 @@ template< typename T, typename U >
 inline bool check_float_equal_eps( const T & lhs, const U & rhs,
                                    const typename VectorTrait<typename math::MathTrait<T,U>::LowType>::OutputType epsilon )
 {
-   static_assert( std::is_floating_point<T>::value,  "First operand type T is not a floating point type!");
-   static_assert( std::is_floating_point<U>::value, "Second operand type U is not a floating point type!");
+   static_assert( std::is_floating_point_v<T>,  "First operand type T is not a floating point type!");
+   static_assert( std::is_floating_point_v<U>, "Second operand type U is not a floating point type!");
 
    using LowType = typename math::MathTrait<T, U>::Low;
 
@@ -145,8 +145,8 @@ template< typename T, typename U >
 inline bool check_float_unequal_eps( const T & lhs, const U & rhs,
                                      const typename VectorTrait<typename math::MathTrait<T,U>::LowType>::OutputType epsilon )
 {
-   static_assert( std::is_floating_point<T>::value,  "First operand type T is not a floating point type!");
-   static_assert( std::is_floating_point<U>::value, "Second operand type U is not a floating point type!");
+   static_assert( std::is_floating_point_v<T>,  "First operand type T is not a floating point type!");
+   static_assert( std::is_floating_point_v<U>, "Second operand type U is not a floating point type!");
 
    using LowType = typename math::MathTrait<T, U>::Low;
 
@@ -159,7 +159,7 @@ inline bool check_float_unequal_eps( const T & lhs, const U & rhs,
 template< typename T, typename U >
 inline bool check_identical( const T & lhs, const U & rhs )
 {
-   using truth_type = std::integral_constant<bool, std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>;
+   using truth_type = std::integral_constant<bool, std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>;
    return check_identical( lhs, rhs, truth_type() );
 }
 
@@ -179,7 +179,7 @@ inline bool check_identical( const T & lhs, const U & rhs, const std::false_type
 template< typename T, typename U >
 inline bool check_not_identical( const T & lhs, const U & rhs )
 {
-   using truth_type = std::integral_constant<bool, std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>;
+   using truth_type = std::integral_constant<bool, std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>;
    return check_not_identical( lhs, rhs, truth_type() );
 }
 
@@ -199,7 +199,7 @@ inline bool check_not_identical( const T & lhs, const U & rhs, const std::false_
 template< typename T, typename U >
 inline bool check_less( const T & lhs, const U & rhs )
 {
-   using truth_type = std::integral_constant<bool, std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>;
+   using truth_type = std::integral_constant<bool, std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>;
    return check_less( lhs, rhs, truth_type() );
 }
 
@@ -219,7 +219,7 @@ inline bool check_less( const T & lhs, const U & rhs, const std::false_type & )
 template< typename T, typename U >
 inline bool check_greater( const T & lhs, const U & rhs )
 {
-   using truth_type = std::integral_constant<bool, std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>;
+   using truth_type = std::integral_constant<bool, std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>;
    return check_greater( lhs, rhs, truth_type() );
 }
 
@@ -239,7 +239,7 @@ inline bool check_greater( const T & lhs, const U & rhs, const std::false_type &
 template< typename T, typename U >
 inline bool check_less_equal( const T & lhs, const U & rhs )
 {
-   using truth_type = std::integral_constant<bool, std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>;
+   using truth_type = std::integral_constant<bool, std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>;
    return check_less_equal( lhs, rhs, truth_type() );
 }
 
@@ -259,7 +259,7 @@ inline bool check_less_equal( const T & lhs, const U & rhs, const std::false_typ
 template< typename T, typename U >
 inline bool check_greater_equal( const T & lhs, const U & rhs )
 {
-   using truth_type = std::integral_constant<bool, std::is_arithmetic<T>::value && std::is_arithmetic<U>::value>;
+   using truth_type = std::integral_constant<bool, std::is_arithmetic_v<T> && std::is_arithmetic_v<U>>;
    return check_greater_equal( lhs, rhs, truth_type() );
 }
 
diff --git a/src/core/debug/Debug.h b/src/core/debug/Debug.h
index f5cf0368656ecd4efa7c4b4e3e5bccda39170fc8..c08e2ed9c75d26a2f563a719a126d3b90d4e8abc 100644
--- a/src/core/debug/Debug.h
+++ b/src/core/debug/Debug.h
@@ -265,7 +265,8 @@ private:
 /// \endcond
 
 #define WALBERLA_ASSERT_SECTION(condition) if(true)\
-   if(const walberla::debug::ConditionalExec COND_EXEC = walberla::debug::ConditionalExec(!(condition),std::bind(walberla::debug::myAssert,__FILE__,__LINE__)))
+   if(const walberla::debug::ConditionalExec COND_EXEC = walberla::debug::ConditionalExec(!(condition),\
+   [=]() { walberla::debug::myAssert(__FILE__, __LINE__); }))
 
 #else
 
diff --git a/src/core/debug/PrintStacktrace.cpp b/src/core/debug/PrintStacktrace.cpp
index 6e0a4fef0a4a80a217d20f5818e604e36868e014..5882e8e5c56fff166c45079910aedfafd5aeede0 100644
--- a/src/core/debug/PrintStacktrace.cpp
+++ b/src/core/debug/PrintStacktrace.cpp
@@ -23,6 +23,7 @@
 #include "demangle.h"
 #include "core/DataTypes.h"
 
+#include <array>
 #include <iostream>
 
 
@@ -54,12 +55,12 @@ namespace debug {
       using std::endl;
 
       const int BACKTRACE_LENGTH = 20;
-      void * array[BACKTRACE_LENGTH];
+      std::array< void*, BACKTRACE_LENGTH > array;
       size_t size;
       char **strings;
 
-      size = numeric_cast< size_t >( backtrace (array, BACKTRACE_LENGTH) );
-      strings = backtrace_symbols (array, int_c(size) );
+      size = numeric_cast< size_t >( backtrace (array.data(), BACKTRACE_LENGTH) );
+      strings = backtrace_symbols (array.data(), int_c(size) );
 
       os << "Backtrace: " << std::endl;
 
diff --git a/src/core/grid_generator/HCPIterator.h b/src/core/grid_generator/HCPIterator.h
index dfc806d116a860e15c00a3c04a37ba30b607bc8a..f2bb389b2a96c2a0fdde7eb39b5e9866ffb5bd00 100644
--- a/src/core/grid_generator/HCPIterator.h
+++ b/src/core/grid_generator/HCPIterator.h
@@ -102,13 +102,13 @@ public:
       , spacing_(spacing)
    {}
 
-   HCPIterator begin() {return HCPIterator(domain_, pointOfReference_, spacing_);}
-   HCPIterator begin()  const {return HCPIterator(domain_, pointOfReference_, spacing_);}
-   HCPIterator cbegin() const {return HCPIterator(domain_, pointOfReference_, spacing_);}
+   HCPIterator begin() { return { domain_, pointOfReference_, spacing_ }; }
+   HCPIterator begin() const { return { domain_, pointOfReference_, spacing_ }; }
+   HCPIterator cbegin() const { return { domain_, pointOfReference_, spacing_ }; }
 
-   HCPIterator end() {return HCPIterator();}
-   HCPIterator end()  const {return HCPIterator();}
-   HCPIterator cend() const {return HCPIterator();}
+   HCPIterator end() {return {};}
+   HCPIterator end()  const {return {};}
+   HCPIterator cend() const {return {};}
 
 private:
    AABB domain_;
diff --git a/src/core/grid_generator/SCIterator.h b/src/core/grid_generator/SCIterator.h
index 19edc06dbdce96fc527df66950af847ab8dc46a7..175413c3c43265ee8d99cb57e05fbad148912edb 100644
--- a/src/core/grid_generator/SCIterator.h
+++ b/src/core/grid_generator/SCIterator.h
@@ -136,13 +136,13 @@ public:
    , spacing_(spacing)
    {}
 
-   SCIterator begin() {return SCIterator(domain_, pointOfReference_, spacing_);}
-   SCIterator begin()  const {return SCIterator(domain_, pointOfReference_, spacing_);}
-   SCIterator cbegin() const {return SCIterator(domain_, pointOfReference_, spacing_);}
+   SCIterator begin() { return { domain_, pointOfReference_, spacing_ }; }
+   SCIterator begin() const { return { domain_, pointOfReference_, spacing_ }; }
+   SCIterator cbegin() const { return { domain_, pointOfReference_, spacing_ }; }
 
-   SCIterator end() {return SCIterator();}
-   SCIterator end()  const {return SCIterator();}
-   SCIterator cend() const {return SCIterator();}
+   SCIterator end() {return {};}
+   SCIterator end()  const {return {};}
+   SCIterator cend() const {return {};}
 private:
    AABB            domain_;
    Vector3<real_t> pointOfReference_;
diff --git a/src/core/load_balancing/MetisWrapper.cpp b/src/core/load_balancing/MetisWrapper.cpp
index 6ea1bded21e7691456976c0c9b341dacfef82f7e..a78d23cf74b1c3fdb926d304ba8e29d3eef45274 100644
--- a/src/core/load_balancing/MetisWrapper.cpp
+++ b/src/core/load_balancing/MetisWrapper.cpp
@@ -76,8 +76,8 @@ int METIS_PartGraphKway( ::walberla::int64_t *nvtxs, ::walberla::int64_t *ncon,
                          ::walberla::int64_t *vwgt, ::walberla::int64_t *vsize, ::walberla::int64_t *adjwgt, ::walberla::int64_t *nparts,
                          double *tpwgts, double *ubvec, ::walberla::int64_t *options, ::walberla::int64_t *edgecut, ::walberla::int64_t *part)
 {
-   static_assert(std::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!");
-   static_assert(std::is_same< double, ::real_t >::value, "You have to compile the metis library with 64-bit wide floating-point type support!");
+   static_assert(std::is_same_v< ::walberla::int64_t, ::idx_t >, "You have to compile the metis library with 64-bit wide integer type support!");
+   static_assert(std::is_same_v< double, ::real_t >, "You have to compile the metis library with 64-bit wide floating-point type support!");
 
    return ::METIS_PartGraphKway( nvtxs, ncon, xadj, adjncy, vwgt, vsize, adjwgt, nparts, tpwgts, ubvec, options, edgecut, part );
 }
@@ -87,15 +87,15 @@ int METIS_PartGraphRecursive( ::walberla::int64_t *nvtxs, ::walberla::int64_t *n
                               ::walberla::int64_t *vwgt, ::walberla::int64_t *vsize, ::walberla::int64_t *adjwgt, ::walberla::int64_t *nparts,
                               double *tpwgts, double *ubvec, ::walberla::int64_t *options, ::walberla::int64_t *edgecut, ::walberla::int64_t *part)
 {
-   static_assert(std::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!");
-   static_assert(std::is_same< double, ::real_t >::value, "You have to compile the metis library with 64-bit wide floating-point type support!");
+   static_assert(std::is_same_v< ::walberla::int64_t, ::idx_t >, "You have to compile the metis library with 64-bit wide integer type support!");
+   static_assert(std::is_same_v< double, ::real_t >, "You have to compile the metis library with 64-bit wide floating-point type support!");
 
    return ::METIS_PartGraphRecursive( nvtxs, ncon, xadj, adjncy, vwgt, vsize, adjwgt, nparts, tpwgts, ubvec, options, edgecut, part );
 }
 
 int METIS_SetDefaultOptions( ::walberla::int64_t *options )
 {
-   static_assert(std::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!");
+   static_assert(std::is_same_v< ::walberla::int64_t, ::idx_t >, "You have to compile the metis library with 64-bit wide integer type support!");
    
    return ::METIS_SetDefaultOptions( options );
 }
diff --git a/src/core/load_balancing/ParMetisWrapper.cpp b/src/core/load_balancing/ParMetisWrapper.cpp
index 40a7c58e8e404dc2dce5c383344e7215b2485289..d5bd67c7785d234d253857103c7a0a4b9bf1ccce 100644
--- a/src/core/load_balancing/ParMetisWrapper.cpp
+++ b/src/core/load_balancing/ParMetisWrapper.cpp
@@ -79,8 +79,8 @@ int ParMETIS_V3_AdaptiveRepart(
    ::walberla::int64_t *options, ::walberla::int64_t *edgecut, ::walberla::int64_t *part, MPI_Comm *comm )
 {
 
-   static_assert( std::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!"        );
-   static_assert( std::is_same< double, ::real_t >::value,             "You have to compile the metis library with 64-bit wide floating-point type support!" );
+   static_assert( std::is_same_v< ::walberla::int64_t, ::idx_t >, "You have to compile the metis library with 64-bit wide integer type support!"        );
+   static_assert( std::is_same_v< double, ::real_t >,             "You have to compile the metis library with 64-bit wide floating-point type support!" );
 
    return ::ParMETIS_V3_AdaptiveRepart( vtxdist, xadj, adjncy, vwgt,
                                         vsize, adjwgt, wgtflag, numflag, ncon,
@@ -94,8 +94,8 @@ int ParMETIS_V3_PartKway(
    double *tpwgts, double *ubvec, ::walberla::int64_t *options, ::walberla::int64_t *edgecut, ::walberla::int64_t *part,
    MPI_Comm *comm )
 {
-   static_assert( std::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!" );
-   static_assert( std::is_same< double, ::real_t >::value, "You have to compile the metis library with 64-bit wide floating-point type support!" );
+   static_assert( std::is_same_v< ::walberla::int64_t, ::idx_t >, "You have to compile the metis library with 64-bit wide integer type support!" );
+   static_assert( std::is_same_v< double, ::real_t >, "You have to compile the metis library with 64-bit wide floating-point type support!" );
 
    return ::ParMETIS_V3_PartKway( vtxdist, xadj, adjncy, vwgt,
                                   adjwgt, wgtflag, numflag, ncon, nparts,
@@ -109,8 +109,8 @@ int ParMETIS_V3_PartGeomKway(
    ::walberla::int64_t *ncon, ::walberla::int64_t *nparts, double *tpwgts, double *ubvec, ::walberla::int64_t *options,
    ::walberla::int64_t *edgecut, ::walberla::int64_t *part, MPI_Comm *comm )
 {
-   static_assert( std::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!" );
-   static_assert( std::is_same< double, ::real_t >::value, "You have to compile the metis library with 64-bit wide floating-point type support!" );
+   static_assert( std::is_same_v< ::walberla::int64_t, ::idx_t >, "You have to compile the metis library with 64-bit wide integer type support!" );
+   static_assert( std::is_same_v< double, ::real_t >, "You have to compile the metis library with 64-bit wide floating-point type support!" );
 
    return ::ParMETIS_V3_PartGeomKway( vtxdist, xadj, adjncy, vwgt,
                                       adjwgt, wgtflag, numflag, ndims, xyz,
@@ -121,8 +121,8 @@ int ParMETIS_V3_PartGeomKway(
 int ParMETIS_V3_PartGeom(
    ::walberla::int64_t *vtxdist, ::walberla::int64_t *ndims, double *xyz, ::walberla::int64_t *part, MPI_Comm *comm )
 {
-   static_assert( std::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!" );
-   static_assert( std::is_same< double, ::real_t >::value, "You have to compile the metis library with 64-bit wide floating-point type support!" );
+   static_assert( std::is_same_v< ::walberla::int64_t, ::idx_t >, "You have to compile the metis library with 64-bit wide integer type support!" );
+   static_assert( std::is_same_v< double, ::real_t >, "You have to compile the metis library with 64-bit wide floating-point type support!" );
 
    return ::ParMETIS_V3_PartGeom( vtxdist, ndims, xyz, part, comm );
 }
@@ -133,8 +133,8 @@ int ParMETIS_V3_RefineKway(
    double *tpwgts, double *ubvec, ::walberla::int64_t *options, ::walberla::int64_t *edgecut,
    ::walberla::int64_t *part, MPI_Comm *comm )
 {
-   static_assert( std::is_same< ::walberla::int64_t, ::idx_t >::value, "You have to compile the metis library with 64-bit wide integer type support!" );
-   static_assert( std::is_same< double, ::real_t >::value, "You have to compile the metis library with 64-bit wide floating-point type support!" );
+   static_assert( std::is_same_v< ::walberla::int64_t, ::idx_t >, "You have to compile the metis library with 64-bit wide integer type support!" );
+   static_assert( std::is_same_v< double, ::real_t >, "You have to compile the metis library with 64-bit wide floating-point type support!" );
 
    return ::ParMETIS_V3_RefineKway( vtxdist, xadj, adjncy, vwgt,
                                     adjwgt, wgtflag, numflag, ncon, nparts,
diff --git a/src/core/logging/Initialization.cpp b/src/core/logging/Initialization.cpp
index d1dfe609934f920b39a90c32fbecb053d5439206..68fc0f0bce7b749a6d511c5f6d0236a80fedefee 100644
--- a/src/core/logging/Initialization.cpp
+++ b/src/core/logging/Initialization.cpp
@@ -35,11 +35,11 @@ namespace logging {
 
 static void parseIgnoreBlocks( const Config::Blocks & ignoreBlocks, std::vector< walberla::regex > & regexes )
 {
-   for( auto ignoreBlock = ignoreBlocks.begin(); ignoreBlock != ignoreBlocks.end(); ++ignoreBlock )
+   for(auto ignoreBlock : ignoreBlocks)
    {
-      if( ignoreBlock->isDefined( "callerPathPattern" ) )
+      if( ignoreBlock.isDefined( "callerPathPattern" ) )
       {
-         std::string regexString = ignoreBlock->getParameter<std::string>( "callerPathPattern" );
+         std::string regexString = ignoreBlock.getParameter<std::string>( "callerPathPattern" );
          // Replace slashes with a regex to allow for windows/linux compatibility
          string_replace_all( regexString, "/", "(\\\\|/)" );
          try
@@ -217,14 +217,14 @@ void configureLogging( const Config::BlockHandle & loggingBlock )
    loggingBlock.getBlocks( "ignore", ignoreBlocks );
    std::vector< walberla::regex > regexes;
    parseIgnoreBlocks( ignoreBlocks, regexes );
-   for( auto regex = regexes.begin(); regex != regexes.end(); ++regex )
-      logging::Logging::instance()->addIgnoreRegex( *regex );
+   for(auto & regexe : regexes)
+      logging::Logging::instance()->addIgnoreRegex( regexe );
 
    regexes.clear();
    loggingBlock.getBlocks( "ignoreWarning", ignoreWarningBlocks );
    parseIgnoreBlocks( ignoreWarningBlocks, regexes );
-   for( auto regex = regexes.begin(); regex != regexes.end(); ++regex )
-      logging::Logging::instance()->addIgnoreWarningRegex( *regex );
+   for(auto & regexe : regexes)
+      logging::Logging::instance()->addIgnoreWarningRegex( regexe );
 }
 
 
diff --git a/src/core/logging/Logging.cpp b/src/core/logging/Logging.cpp
index bd2dfa403b03b16f7aa619cf3ee6cc12ab5972bc..2aad5963be66901dc10ec1307e6030c6f49759ad 100644
--- a/src/core/logging/Logging.cpp
+++ b/src/core/logging/Logging.cpp
@@ -173,9 +173,9 @@ std::string Logging::getHeaderFooter( bool header )
    std::time_t t;
    std::time( &t );
 
-   char cTimeString[64];
-   std::strftime( cTimeString, 64, "%A, %d.%B %Y, %H:%M:%S", std::localtime( &t ) );
-   std::string timeString( cTimeString );
+   std::array< char, 64 > cTimeString;
+   std::strftime(cTimeString.data(), 64, "%A, %d.%B %Y, %H:%M:%S", std::localtime(&t));
+   std::string timeString(cTimeString.data());
 
    std::string beginEnd( header ? "BEGIN LOGGING" : "  END LOGGING" );
 
@@ -226,8 +226,8 @@ bool Logging::isInIgnoreCallerPaths( const std::vector< walberla::regex > & rege
       std::stringstream callerPathAndLine;
       callerPathAndLine << callerPath << ":" << line;
 
-      for( auto regex = regexes.begin(); regex != regexes.end(); ++regex )
-         if( walberla::regex_search( callerPathAndLine.str(), *regex ) )
+      for(const auto & regexe : regexes)
+         if( walberla::regex_search( callerPathAndLine.str(), regexe ) )
             return true;
    }
 
diff --git a/src/core/logging/Logging.h b/src/core/logging/Logging.h
index e891ecf5dff1ecf452d1b01b7f59be2d160a5c70..b135c86003155d009bb82d7a8498cfa31838c6a3 100644
--- a/src/core/logging/Logging.h
+++ b/src/core/logging/Logging.h
@@ -165,8 +165,8 @@ private:
 
 
 
-   LogLevel streamLogLevel_;
-   LogLevel   fileLogLevel_;
+   LogLevel streamLogLevel_{ WALBERLA_LOGLEVEL };
+   LogLevel   fileLogLevel_{ WALBERLA_LOGLEVEL };
 
    std::ofstream file_;
 
@@ -174,10 +174,10 @@ private:
    uint_t numberOfProcesses_;
 
    double startTime_;
-   bool showTimeStamp_;
+   bool showTimeStamp_{ true };
    shared_ptr< CustomStamp > additionalStamp_;
 
-   bool logCallerPath_;
+   bool logCallerPath_{ false };
 
    std::vector< walberla::regex > ignoreRegexes_;
    std::vector< walberla::regex > ignoreWarningRegexes_;
@@ -186,10 +186,9 @@ private:
 
 
 inline Logging::Logging() : singleton::Singleton<Logging>(),
-   streamLogLevel_( WALBERLA_LOGLEVEL ), fileLogLevel_( WALBERLA_LOGLEVEL ),
    processId_( uint_c( mpi::MPIManager::instance()->worldRank() ) ),
    numberOfProcesses_( uint_c( mpi::MPIManager::instance()->numProcesses() ) ),
-   startTime_( timing::WcPolicy::getTimestamp() ), showTimeStamp_( true ), logCallerPath_( false )
+   startTime_( timing::WcPolicy::getTimestamp() )
 {
 }
 
diff --git a/src/core/math/DistributedSample.cpp b/src/core/math/DistributedSample.cpp
index 965ab81692dbdc74d6a58814d0c8ff7329c89490..e6b84e6d8707fe2a96798280fb9317a677d8877c 100644
--- a/src/core/math/DistributedSample.cpp
+++ b/src/core/math/DistributedSample.cpp
@@ -45,11 +45,11 @@ void DistributedSample::mpiAllGather()
    max_ = -std::numeric_limits< real_t >::max();
    size_ = uint_c( data_.size() );
 
-   for( auto it = data_.begin(); it != data_.end(); ++it )
+   for(const real_t it : data_)
    {
-      sum_ += *it;
-      min_ = std::min( min_, *it );
-      max_ = std::max( max_, *it );
+      sum_ += it;
+      min_ = std::min( min_, it );
+      max_ = std::max( max_, it );
    }
 
    WALBERLA_MPI_SECTION()
@@ -63,9 +63,9 @@ void DistributedSample::mpiAllGather()
    mean_ = sum_ / real_c(size_);
    variance_ = real_t(0);
 
-   for( auto it = data_.begin(); it != data_.end(); ++it )
+   for(real_t & it : data_)
    {
-      real_t val = *it - mean_;
+      real_t val = it - mean_;
       variance_ += val*val;
    }
 
@@ -104,11 +104,11 @@ void DistributedSample::mpiGather( int rank )
    max_ = -std::numeric_limits< real_t >::max();
    size_ = uint_c( data_.size() );
 
-   for( auto it = data_.begin(); it != data_.end(); ++it )
+   for(real_t & it : data_)
    {
-      sum_ += *it;
-      min_ = std::min( min_, *it );
-      max_ = std::max( max_, *it );
+      sum_ += it;
+      min_ = std::min( min_, it );
+      max_ = std::max( max_, it );
    }
 
    WALBERLA_MPI_SECTION()
@@ -122,9 +122,9 @@ void DistributedSample::mpiGather( int rank )
    mean_ = sum_ / real_c(size_);
    variance_ = real_t(0);
 
-   for( auto it = data_.begin(); it != data_.end(); ++it )
+   for(real_t & it : data_)
    {
-      real_t val = *it - mean_;
+      real_t val = it - mean_;
       variance_ += val*val;
    }
 
diff --git a/src/core/math/DistributedSample.h b/src/core/math/DistributedSample.h
index e8c817d9506bee09b24b73ce6adc0bcc9b17a49f..2a52d627ad5113acddb25816fbad5afa2bf97b7d 100644
--- a/src/core/math/DistributedSample.h
+++ b/src/core/math/DistributedSample.h
@@ -99,7 +99,7 @@ private:
 template< typename T >
 void DistributedSample::castToRealAndInsert( const T & val )
 {
-   static_assert( std::is_arithmetic<T>::value, "You can only use DistributedSample::castToRealAndInsert with " \
+   static_assert( std::is_arithmetic_v<T>, "You can only use DistributedSample::castToRealAndInsert with " \
                   "arithmetic types!" );
 
    insert( numeric_cast< real_t >( val ) );
@@ -108,7 +108,7 @@ void DistributedSample::castToRealAndInsert( const T & val )
 template <class InputIterator>
 void DistributedSample::castToRealAndInsert( InputIterator first, InputIterator last )
 {
-   static_assert( std::is_arithmetic< typename std::iterator_traits<InputIterator>::value_type >::value,
+   static_assert( std::is_arithmetic_v< typename std::iterator_traits<InputIterator>::value_type >,
                   "You can only use DistributedSample::castToRealAndInsert with sequences of arithmetic types!" );
 
    while( first != last )
diff --git a/src/core/math/GenericAABB.h b/src/core/math/GenericAABB.h
index 6ca2ce1764841485d97efe714eb6456d1b4119d4..a16eae2cc21bf6baad174f575606f6c58966e7d4 100644
--- a/src/core/math/GenericAABB.h
+++ b/src/core/math/GenericAABB.h
@@ -44,7 +44,7 @@ namespace math {
 template< typename T >
 class GenericAABB
 {
-   static_assert( std::is_floating_point< T >::value, "GenericAABB only works with floating point types for T!" );
+   static_assert( std::is_floating_point_v< T >, "GenericAABB only works with floating point types for T!" );
 
 public:
    // Typedefs
@@ -196,7 +196,7 @@ public:
    inline friend mpi::GenericRecvBuffer< ET > & operator>>( mpi::GenericRecvBuffer< ET > & buf, GenericAABB< T > & aabb )
    {
       buf.readDebugMarker( "bb" );
-      static_assert ( std::is_trivially_copyable< GenericAABB< T > >::value,
+      static_assert ( std::is_trivially_copyable_v< GenericAABB< T > >,
                       "type has to be trivially copyable for the memcpy to work correctly" );
       auto pos = buf.skip(sizeof(GenericAABB< T >));
       std::memcpy(&aabb, pos, sizeof(GenericAABB< T >));
@@ -217,7 +217,7 @@ private:
    vector_type minCorner_; /// minimal values
    vector_type maxCorner_; /// maximal values
 };
-static_assert( std::is_trivially_copyable<GenericAABB<real_t>>::value, "GenericAABB<real_t> has to be trivially copyable!");
+static_assert( std::is_trivially_copyable_v<GenericAABB<real_t>>, "GenericAABB<real_t> has to be trivially copyable!");
 
 
 
diff --git a/src/core/math/GenericAABB.impl.h b/src/core/math/GenericAABB.impl.h
index e62757bfa1add43d24632ca56366f212f3b50166..35c4ed45bf8336262928a9ea1387d327f499f0dc 100644
--- a/src/core/math/GenericAABB.impl.h
+++ b/src/core/math/GenericAABB.impl.h
@@ -1069,8 +1069,8 @@ typename GenericAABB< T >::value_type GenericAABB< T >::sqSignedDistance( const
    if( !inside )
       return sqDistance( point );
 
-   value_type sqAxisDist[3];
-   
+   std::array< value_type, 3 > sqAxisDist;
+
    for( uint_t i = 0; i < 3; ++i )
    {
       WALBERLA_ASSERT_GREATER_EQUAL( d[i], 0 );
@@ -1159,7 +1159,7 @@ typename GenericAABB< T >::value_type GenericAABB< T >::signedDistance( const ve
    if( !inside )
       return distance( point );
 
-   value_type axisDist[3];
+   std::array< value_type, 3 > axisDist;
 
    for( uint_t i = 0; i < 3; ++i )
    {
@@ -1883,7 +1883,7 @@ template< typename T,    // Element type of SendBuffer
 mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, const GenericAABB< VT > & aabb )
 {
    buf.addDebugMarker( "bb" );
-   static_assert ( std::is_trivially_copyable< GenericAABB< VT > >::value,
+   static_assert ( std::is_trivially_copyable_v< GenericAABB< VT > >,
                    "type has to be trivially copyable for the memcpy to work correctly" );
    auto pos = buf.forward(sizeof(GenericAABB< VT >));
    std::memcpy(pos, &aabb, sizeof(GenericAABB< VT >));
diff --git a/src/core/math/Matrix2.h b/src/core/math/Matrix2.h
index 3827333a4aef26fe1c2db7599724181b6df78a84..60d554158f9d6e5b1a1576099ac26aea64f11821 100644
--- a/src/core/math/Matrix2.h
+++ b/src/core/math/Matrix2.h
@@ -151,7 +151,7 @@ public:
    inline const Matrix2       getInverse()                               const;
    inline bool                isSingular()                               const;
    inline bool                isSymmetric()                              const;
-   inline Type*               data()                                     {return v_;}
+   inline Type*               data()                                     {return v_.data();}
    //@}
    //*******************************************************************************************************************
 
@@ -160,7 +160,7 @@ private:
    //**Member variables****************************************************************************
    /*!\name Member variables */
    //@{
-   Type v_[4];  //!< The nine statically allocated matrix elements.
+   std::array< Type, 4 > v_; //!< The nine statically allocated matrix elements.
                 /*!< Access to the matrix elements is gained via the subscript or function call
                      operator. The order of the elements is
                      \f[\left(\begin{array}{*{2}{c}}
@@ -831,7 +831,7 @@ inline const Matrix2<Type> fabs( const Matrix2<Type>& m );
 // \return The scaled result matrix.
 */
 template< typename Type, typename Other >
-inline typename std::enable_if< std::is_fundamental< Other >::value, Matrix2< HIGH > >::type
+inline std::enable_if_t< std::is_fundamental_v< Other >, Matrix2< HIGH > >
 operator*(Other scalar, const Matrix2< Type >& matrix)
 {
    return matrix * scalar;
@@ -947,7 +947,7 @@ template< typename T,    // Element type of SendBuffer
 mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, const Matrix2<MT> & m )
 {
    buf.addDebugMarker( "m2" );
-   static_assert ( std::is_trivially_copyable< Matrix2<MT> >::value,
+   static_assert ( std::is_trivially_copyable_v< Matrix2<MT> >,
                    "type has to be trivially copyable for the memcpy to work correctly" );
    auto pos = buf.forward(sizeof(Matrix2<MT>));
    std::memcpy(pos, &m, sizeof(Matrix2<MT>));
@@ -959,7 +959,7 @@ template< typename T,    // Element type  of RecvBuffer
 mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, Matrix2<MT> & m )
 {
    buf.readDebugMarker( "m2" );
-   static_assert ( std::is_trivially_copyable< Matrix2<MT> >::value,
+   static_assert ( std::is_trivially_copyable_v< Matrix2<MT> >,
                    "type has to be trivially copyable for the memcpy to work correctly" );
    auto pos = buf.skip(sizeof(Matrix2<MT>));
    //suppress https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-Wclass-memaccess
diff --git a/src/core/math/Matrix3.h b/src/core/math/Matrix3.h
index 8c4259b05c48fd01d6e452a9dc9a219490aef150..bde2d22e5916ef1cc66441a77031b0eaa99896b3 100644
--- a/src/core/math/Matrix3.h
+++ b/src/core/math/Matrix3.h
@@ -148,8 +148,8 @@ public:
    template< typename Other > inline const Vector3<HIGH> operator* ( const Vector3<Other>& rhs ) const;
    template< typename Other > inline const Matrix3<HIGH> operator* ( const Matrix3<Other>& rhs ) const;
 
-   template< typename Other > inline typename std::enable_if< std::is_arithmetic<Other>::value, Matrix3&            >::type operator*=( Other rhs );
-   template< typename Other > inline typename std::enable_if< std::is_arithmetic<Other>::value, const Matrix3<HIGH> >::type operator* ( Other rhs ) const;
+   template< typename Other > inline std::enable_if_t< std::is_arithmetic_v<Other>, Matrix3&            >operator*=( Other rhs );
+   template< typename Other > inline std::enable_if_t< std::is_arithmetic_v<Other>, const Matrix3<HIGH> >operator* ( Other rhs ) const;
    //@}
    //*******************************************************************************************************************
 
@@ -254,7 +254,7 @@ private:
    //@}
    //*******************************************************************************************************************
 };
-static_assert( std::is_trivially_copyable<Matrix3<real_t>>::value, "Matrix3<real_t> has to be trivially copyable!");
+static_assert( std::is_trivially_copyable_v<Matrix3<real_t>>, "Matrix3<real_t> has to be trivially copyable!");
 //**********************************************************************************************************************
 
 
@@ -690,7 +690,7 @@ inline Matrix3<Type>& Matrix3<Type>::operator-=( const Matrix3<Other>& rhs )
 */
 template< typename Type >
 template< typename Other >
-inline typename std::enable_if< std::is_arithmetic<Other>::value, Matrix3<Type>& >::type Matrix3<Type>::operator*=( Other rhs )
+inline std::enable_if_t< std::is_arithmetic_v<Other>, Matrix3<Type>& >Matrix3<Type>::operator*=( Other rhs )
 {
    v_[0] *= rhs;
    v_[1] *= rhs;
@@ -814,7 +814,7 @@ inline const Matrix3<Type> operator-( const Matrix3<Type>& rhs )
 */
 template< typename Type >
 template< typename Other >
-inline typename std::enable_if< std::is_arithmetic<Other>::value ,const Matrix3<HIGH> >::type Matrix3<Type>::operator*( Other rhs ) const
+inline std::enable_if_t< std::is_arithmetic_v<Other> ,const Matrix3<HIGH> >Matrix3<Type>::operator*( Other rhs ) const
 {
    return Matrix3<HIGH>( v_[0]*rhs, v_[1]*rhs, v_[2]*rhs,
                          v_[3]*rhs, v_[4]*rhs, v_[5]*rhs,
@@ -1304,8 +1304,8 @@ const Vector3<Type> Matrix3<Type>::getEulerAngles( EulerRotation order ) const
 {
    WALBERLA_STATIC_ASSERT( !std::numeric_limits<Type>::is_integer );
 
-   static const uint_t eulSafe[4] = { 0, 1, 2, 0 };
-   static const uint_t eulNext[4] = { 1, 2, 0, 1 };
+   static const std::array< uint_t, 4 > eulSafe = { 0, 1, 2, 0 };
+   static const std::array< uint_t, 4 > eulNext = { 1, 2, 0, 1 };
 
    Vector3<Type> ea;
 
@@ -1405,7 +1405,7 @@ inline const Matrix3<Type> fabs( const Matrix3<Type>& m );
 // \return The scaled result matrix.
 */
 template< typename Type, typename Other >
-inline typename std::enable_if< std::is_arithmetic< Other >::value, const Matrix3< HIGH > >::type
+inline std::enable_if_t< std::is_arithmetic_v< Other >, const Matrix3< HIGH > >
 operator*(Other scalar, const Matrix3< Type >& matrix)
 {
    return matrix * scalar;
@@ -1750,7 +1750,7 @@ namespace mpi {
       mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, const Matrix3<MT> & m )
       {
          buf.addDebugMarker( "m3" );
-         static_assert ( std::is_trivially_copyable< Matrix3<MT> >::value,
+         static_assert ( std::is_trivially_copyable_v< Matrix3<MT> >,
                          "type has to be trivially copyable for the memcpy to work correctly" );
          auto pos = buf.forward(sizeof(Matrix3<MT>));
          std::memcpy(pos, &m, sizeof(Matrix3<MT>));
@@ -1762,7 +1762,7 @@ namespace mpi {
       mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, Matrix3<MT> & m )
       {
          buf.readDebugMarker( "m3" );
-         static_assert ( std::is_trivially_copyable< Matrix3<MT> >::value,
+         static_assert ( std::is_trivially_copyable_v< Matrix3<MT> >,
                          "type has to be trivially copyable for the memcpy to work correctly" );
          auto pos = buf.skip(sizeof(Matrix3<MT>));
          //suppress https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-Wclass-memaccess
diff --git a/src/core/math/MatrixMxN.h b/src/core/math/MatrixMxN.h
index f523fde9422e06a04c37f7918120f04d6dda1e0c..a76ea955d83951708cb4aa60ad534563bb2624e1 100644
--- a/src/core/math/MatrixMxN.h
+++ b/src/core/math/MatrixMxN.h
@@ -89,8 +89,8 @@ class MatrixMxN
 {
    //**Compile time checks*************************************************************************
    /*! \cond internal */
-   static_assert(!std::is_const<Type>::value, "only non const Types are allowed!");
-   static_assert(!std::is_volatile<Type>::value, "only non volatile types are allowed!");
+   static_assert(!std::is_const_v<Type>, "only non const Types are allowed!");
+   static_assert(!std::is_volatile_v<Type>, "only non volatile types are allowed!");
    /*! \endcond */
    //**********************************************************************************************
 
@@ -111,7 +111,7 @@ public:
                                     inline constexpr MatrixMxN( const MatrixMxN& m );
 
    template< typename Other, size_t M, size_t N >
-   inline constexpr MatrixMxN( const Other (&rhs)[M][N] );
+   inline constexpr MatrixMxN( const std::array<std::array<Other, N>, M>& rhs );
    //@}
    //**********************************************************************************************
 
@@ -126,7 +126,7 @@ public:
    /*!\name Operators */
    //@{
    template< typename Other, size_t M, size_t N >
-   inline MatrixMxN& operator=( const Other (&rhs)[M][N] );
+   inline MatrixMxN& operator=( const std::array<std::array<Other, N>, M>& rhs );
 
                            inline MatrixMxN&  operator= ( Type set );
                            inline MatrixMxN&  operator= ( const MatrixMxN& set );
@@ -292,7 +292,7 @@ template< typename Type >  // Data type of the matrix
 template< typename Other   // Data type of the initialization array
         , size_t M         // Number of rows of the initialization array
         , size_t N >       // Number of columns of the initialization array
-inline constexpr MatrixMxN<Type>::MatrixMxN( const Other (&rhs)[M][N] )
+inline constexpr MatrixMxN<Type>::MatrixMxN( const std::array<std::array<Other, N>, M>& rhs )
    : m_       ( M )              // The current number of rows of the matrix
    , n_       ( N )              // The current number of columns of the matrix
    , capacity_( M*N )            // The maximum capacity of the matrix
@@ -355,7 +355,7 @@ template< typename Type >  // Data type of the matrix
 template< typename Other   // Data type of the initialization array
         , size_t M         // Number of rows of the initialization array
         , size_t N >       // Number of columns of the initialization array
-inline MatrixMxN<Type>& MatrixMxN<Type>::operator=( const Other (&rhs)[M][N] )
+inline MatrixMxN<Type>& MatrixMxN<Type>::operator=( const std::array<std::array<Other, N>, M>& rhs )
 {
    resize( M, N, false );
 
diff --git a/src/core/math/Parser.cpp b/src/core/math/Parser.cpp
index 7b12bc35203f7b68d8cd5e193fea4e85bcee2ae3..ea68dfe1d2f6b1500e09c7f2325218db0275fcb3 100644
--- a/src/core/math/Parser.cpp
+++ b/src/core/math/Parser.cpp
@@ -61,16 +61,7 @@
 namespace walberla {
 namespace math {
 
-
-
-FunctionParser::FunctionParser() 
-   : expression_ ( nullptr ),
-     symbolTable_( nullptr ),
-     isConstant_(false),
-     isZero_(false)
-{
-
-}
+FunctionParser::FunctionParser() = default;
 
 FunctionParser::~FunctionParser() 
 {
@@ -132,14 +123,14 @@ double FunctionParser::evaluate( const std::map<std::string,double> & symbolTabl
    std::vector< std::string > variables;
    symbolTable_->get_variable_list( variables );
 
-   for( auto vIt = variables.begin(); vIt != variables.end(); ++vIt )
+   for(auto & variable : variables)
    {
-      auto symbolEntryIt = symbolTable.find( *vIt );
+      auto symbolEntryIt = symbolTable.find( variable );
 
       if( symbolEntryIt == symbolTable.end() )
-         WALBERLA_ABORT( "Error evaluating expression. Variable \"" << *vIt << "\" not specified in symbol table!" );
+         WALBERLA_ABORT( "Error evaluating expression. Variable \"" << variable << "\" not specified in symbol table!" );
 
-      symbolTable_->variable_ref( *vIt ) = symbolEntryIt->second;
+      symbolTable_->variable_ref( variable ) = symbolEntryIt->second;
    }
 
    return expression_->value();
diff --git a/src/core/math/Parser.h b/src/core/math/Parser.h
index 692051c2c5539295f1d8f10071e5dce35487ffca..303a4057a837951ee2c52c4bf9a8a60a0c3fe6a3 100644
--- a/src/core/math/Parser.h
+++ b/src/core/math/Parser.h
@@ -73,10 +73,10 @@ protected:
    FunctionParser( const FunctionParser & other );
    FunctionParser & operator=( const FunctionParser & other );
 
-   exprtk::expression<double>   * expression_;
-   exprtk::symbol_table<double> * symbolTable_;
-   bool isConstant_;
-   bool isZero_;
+   exprtk::expression<double>   * expression_{ nullptr };
+   exprtk::symbol_table<double> * symbolTable_{ nullptr };
+   bool isConstant_{false};
+   bool isZero_{false};
 };
 
 #else // WALBERLA_DEACTIVATE_MATH_PARSER
diff --git a/src/core/math/ParserOMP.h b/src/core/math/ParserOMP.h
index 7a3939e18f74245a9fcef2459adedf9274c7d678..43fc54cecfb10838feda051d0eec50813a048f69 100644
--- a/src/core/math/ParserOMP.h
+++ b/src/core/math/ParserOMP.h
@@ -39,7 +39,7 @@ public:
    inline bool symbolExists(const std::string & symbol) const { return parser_[0].symbolExists(symbol); }
 
 private:
-   std::unique_ptr< FunctionParser[] > parser_;
+   std::unique_ptr< FunctionParser[] > parser_; // NOLINT
 #ifndef NDEBUG
    int num_parsers_;
 #endif
diff --git a/src/core/math/Primes.cpp b/src/core/math/Primes.cpp
index 81cad6dffaf1de0b03a4e6b17f5b657449b7c369..50c9ce669e8315586c498748827267eff572898d 100644
--- a/src/core/math/Primes.cpp
+++ b/src/core/math/Primes.cpp
@@ -72,7 +72,7 @@ bool isPrime( const uint_t n )
 std::vector<uint_t> getPrimes( const uint_t n )
 {
    if( n < 2 )
-      return std::vector<uint_t>();
+      return {};
 
    std::vector<bool> markers( n+1, false );
    std::vector<uint_t> primes;
@@ -115,14 +115,14 @@ std::vector<uint_t> getPrimeFactors( const uint_t n )
    std::vector<uint_t> primeFactors;
 
    uint_t n_rest = n;
-   for(auto primeIt = primes.begin(); primeIt != primes.end(); ++primeIt)
+   for(const uint_t prime : primes)
    {
-      if( *primeIt * *primeIt > n )
+      if( prime * prime > n )
          break;
-      while( n_rest % *primeIt == 0)
+      while( n_rest % prime == 0)
       {
-         n_rest /= *primeIt;
-         primeFactors.push_back(*primeIt);
+         n_rest /= prime;
+         primeFactors.push_back(prime);
       }
    }
 
@@ -147,7 +147,7 @@ std::vector<uint_t> getPrimeFactors( const uint_t n )
 std::set<uint_t> getDevisors( const uint_t n )
 {
    if( n == uint_t(0) )
-      return std::set<uint_t>();
+      return {};
 
    std::vector<uint_t> factors = getPrimeFactors( n );
 
@@ -157,12 +157,12 @@ std::set<uint_t> getDevisors( const uint_t n )
    devisors.insert( uint_t(1) );
    tmpDevisors.reserve( ( size_t(1) << factors.size() ) - size_t(1) );
 
-   for( auto fIt = factors.begin(); fIt != factors.end(); ++fIt )
+   for(const uint_t factor : factors)
    {
       tmpDevisors.clear();
-      for(auto pIt = devisors.begin(); pIt != devisors.end(); ++pIt)
+      for(uint_t devisor : devisors)
       {
-         tmpDevisors.push_back( *pIt * *fIt );
+         tmpDevisors.push_back( devisor * factor );
       }
       devisors.insert( tmpDevisors.begin(), tmpDevisors.end() );
    }
diff --git a/src/core/math/Quaternion.h b/src/core/math/Quaternion.h
index 3ee4273ae173a0a1057784db65c531fa6f8256fe..59111ab8100044c02b3ef3449361e3d66edee4cf 100644
--- a/src/core/math/Quaternion.h
+++ b/src/core/math/Quaternion.h
@@ -100,9 +100,9 @@ class Quaternion
 {
    //**Compile time checks*************************************************************************
    /*! \cond internal */
-   static_assert(std::is_floating_point<Type>::value, "T has to be floating point!");
-   static_assert(!std::is_const<Type>::value, "T has to be non const!");
-   static_assert(!std::is_volatile<Type>::value, "T has to be non volatile!");
+   static_assert(std::is_floating_point_v<Type>, "T has to be floating point!");
+   static_assert(!std::is_const_v<Type>, "T has to be non const!");
+   static_assert(!std::is_volatile_v<Type>, "T has to be non volatile!");
    /*! \endcond */
    //**********************************************************************************************
 
@@ -161,8 +161,8 @@ public:
                               inline void                       rotateZ( Type angle );
                               inline void                       swap( Quaternion& q ) /* throw() */;
                               inline const Vector3<Type>        getEulerAnglesXYZ() const;
-                              inline Type*                      data()                         {return v_;}
-                              inline Type const *               data()                         const {return v_;}
+                              inline Type*                      data()                         {return v_.data();}
+                              inline Type const *               data()                         const {return v_.data();}
    //@}
    //**********************************************************************************************
 
@@ -205,11 +205,11 @@ private:
     * 0 & 1 & 2 & 3 \\
     * \end{array}\right)\f]
    **/
-   Type v_[4] = {Type(1), Type(0), Type(0), Type(0)};
-   //@}
+  std::array< Type, 4 > v_ = { Type(1), Type(0), Type(0), Type(0) };
+  //@}
    //**********************************************************************************************
 };
-static_assert( std::is_trivially_copyable<Quaternion<real_t>>::value, "Quaternion<real_t> has to be trivially copyable!");
+static_assert( std::is_trivially_copyable_v<Quaternion<real_t>>, "Quaternion<real_t> has to be trivially copyable!");
 //*************************************************************************************************
 
 
@@ -264,7 +264,7 @@ template< typename Type >  // Data type of the quaternion
 template< typename Axis >  // Data type of the rotation axis
 inline Quaternion<Type>::Quaternion( Vector3<Axis> axis, Type angle )
 {
-   static_assert(std::is_floating_point<Axis>::value, "Axis has to be floating point!" );
+   static_assert(std::is_floating_point_v<Axis>, "Axis has to be floating point!" );
 
    auto axisLength = axis.length();
    if( (floatIsEqual(axisLength, 0)) || (math::equal(std::fabs(angle), real_t(0)))  ) {
@@ -1095,7 +1095,7 @@ namespace mpi {
    mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, const math::Quaternion<VT> & quat )
    {
       buf.addDebugMarker( "q4" );
-      static_assert ( std::is_trivially_copyable< math::Quaternion<VT> >::value,
+      static_assert ( std::is_trivially_copyable_v< math::Quaternion<VT> >,
                       "type has to be trivially copyable for the memcpy to work correctly" );
       auto pos = buf.forward(sizeof(math::Quaternion<VT>));
       std::memcpy(pos, &quat, sizeof(math::Quaternion<VT>));
@@ -1107,7 +1107,7 @@ namespace mpi {
    mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, math::Quaternion<VT> & quat )
    {
       buf.readDebugMarker( "q4" );
-      static_assert ( std::is_trivially_copyable< math::Quaternion<VT> >::value,
+      static_assert ( std::is_trivially_copyable_v< math::Quaternion<VT> >,
                       "type has to be trivially copyable for the memcpy to work correctly" );
       auto pos = buf.skip(sizeof(math::Quaternion<VT>));
       //suppress https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-Wclass-memaccess
diff --git a/src/core/math/Rot3.h b/src/core/math/Rot3.h
index b0ab7ecdbfd2c0a53a660b0009c59d70a92441e3..6177400fd871fc0bf8340a48be8f77c33c1f3b2b 100644
--- a/src/core/math/Rot3.h
+++ b/src/core/math/Rot3.h
@@ -41,9 +41,9 @@ class Rot3
 {
    //**Compile time checks*************************************************************************
    /*! \cond internal */
-   static_assert(std::is_floating_point<Type>::value, "T has to be floating point!");
-   static_assert(!std::is_const<Type>::value, "T has to be non const!");
-   static_assert(!std::is_volatile<Type>::value, "T has to be non volatile!");
+   static_assert(std::is_floating_point_v<Type>, "T has to be floating point!");
+   static_assert(!std::is_const_v<Type>, "T has to be non const!");
+   static_assert(!std::is_volatile_v<Type>, "T has to be non volatile!");
    /*! \endcond */
    //**********************************************************************************************
 public:
diff --git a/src/core/math/Sample.cpp b/src/core/math/Sample.cpp
index 303656736e90548418641993606f8838661d23af..fa5acd595101bbbee415d773a8af42ddd4584fb6 100644
--- a/src/core/math/Sample.cpp
+++ b/src/core/math/Sample.cpp
@@ -124,9 +124,9 @@ real_t Sample::variance( real_t theMean ) const
    WALBERLA_ASSERT(!empty());
 
    KahanAccumulator< real_t > acc;
-   for(auto it = begin(); it != end(); ++it)
+   for(real_t it : *this)
    {
-      real_t val = *it - theMean;
+      real_t val = it - theMean;
       acc += val*val;
    }
       
@@ -208,10 +208,10 @@ real_t Sample::giniCoefficient() const
    real_t sum1 = 0;
    uint_t i    = 1;
 
-   for( auto it = begin(); it != end(); ++it )
+   for(real_t it : *this)
    {
-      sum0 += *it * real_t( i++ );
-      sum1 += *it;
+      sum0 += it * real_t( i++ );
+      sum1 += it;
    }
 
    const real_t theSize = real_c( size() );
diff --git a/src/core/math/Sample.h b/src/core/math/Sample.h
index 66328ea420df718321b05e408e17407e958787bd..c7623e186391ae66c0837ebc8622783aa8ce2c81 100644
--- a/src/core/math/Sample.h
+++ b/src/core/math/Sample.h
@@ -92,7 +92,7 @@ std::ostream & operator<<( std::ostream & os, const Sample & statReal );
 template< typename T >
 Sample::iterator Sample::castToRealAndInsert(const T& val)
 {
-   static_assert( std::is_arithmetic<T>::value, "You can only use Sample::castToRealAndInsert with " \
+   static_assert( std::is_arithmetic_v<T>, "You can only use Sample::castToRealAndInsert with " \
                   "arithmetic types!" );
 
    return insert( numeric_cast<value_type>( val ) );
@@ -101,7 +101,7 @@ Sample::iterator Sample::castToRealAndInsert(const T& val)
 template< typename T >
 Sample::iterator Sample::castToRealAndInsert(const_iterator position, const T& val)
 {
-   static_assert( std::is_arithmetic<T>::value, "You can only use Sample::castToRealAndInsert with " \
+   static_assert( std::is_arithmetic_v<T>, "You can only use Sample::castToRealAndInsert with " \
                   "arithmetic types!" );
 
    return insert( position, numeric_cast<value_type>( val ) );
@@ -110,7 +110,7 @@ Sample::iterator Sample::castToRealAndInsert(const_iterator position, const T& v
 template <class InputIterator>
 void Sample::castToRealAndInsert(InputIterator first, InputIterator last)
 {
-   static_assert( std::is_arithmetic< typename std::iterator_traits<InputIterator>::value_type >::value,
+   static_assert( std::is_arithmetic_v< typename std::iterator_traits<InputIterator>::value_type >,
                   "You can only use Sample::castToRealAndInsert with sequences of arithmetic types!" );
 
    while( first != last )
diff --git a/src/core/math/Uint.h b/src/core/math/Uint.h
index d15bc2f3db83cb9b9845d2791420edeaa94f3ba0..406a19f925a6f887d0e9177aa3a14b8723f8822a 100644
--- a/src/core/math/Uint.h
+++ b/src/core/math/Uint.h
@@ -132,7 +132,7 @@ inline UINT uintPow16( UINT exp ) {
 
 // http://graphics.stanford.edu/~seander/bithacks.html
 
-static const uint8_t msbLookupTable[256] =
+static const std::array< uint8_t, 256 > msbLookupTable =
 {
 #define msbLT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
       0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
@@ -150,7 +150,7 @@ static const uint8_t msbLookupTable[256] =
 //**********************************************************************************************************************
 template< typename UINT > uint_t uintMSBPosition( UINT value )
 {
-   static_assert( std::is_unsigned< UINT >::value, "uintMSBPosition can only be used with unsigned integer types!" );
+   static_assert( std::is_unsigned_v< UINT >, "uintMSBPosition can only be used with unsigned integer types!" );
 
    switch( std::numeric_limits<UINT>::digits )
    {
diff --git a/src/core/math/Utility.h b/src/core/math/Utility.h
index 87300282bca8c9f7b5949796407c95fea5bdabe6..1ce1da8882acc0b2f6f3eb6522de5bfcb0cb05ca 100644
--- a/src/core/math/Utility.h
+++ b/src/core/math/Utility.h
@@ -47,9 +47,9 @@ template< typename T >
 inline const T sign( T a );
 
 template< typename T >
-inline const typename std::enable_if<  std::is_unsigned<T>::value, T >::type abs( T a );
+inline const typename std::enable_if_t<  std::is_unsigned_v<T>, T > abs( T a );
 template< typename T >
-inline const typename std::enable_if< ! std::is_unsigned<T>::value, T >::type abs( T a );
+inline const typename std::enable_if_t< ! std::is_unsigned_v<T>, T > abs( T a );
 
 
 template< typename T1, typename T2 >
@@ -104,13 +104,13 @@ inline const T sign( T a )
 // \return The value if it is greater than or equal to zero, -1 times the value if the value is smaller than zero.
  */
 template< typename T >
-inline const typename std::enable_if<  std::is_unsigned<T>::value, T >::type abs( T a )
+inline const typename std::enable_if_t<  std::is_unsigned_v<T>, T > abs( T a )
 {
    return a;
 }
 
 template< typename T >
-inline const typename std::enable_if< !std::is_unsigned<T>::value, T >::type abs( T a )
+inline const typename std::enable_if_t< !std::is_unsigned_v<T>, T > abs( T a )
 {
    return std::abs( a );
 }
diff --git a/src/core/math/Vector2.h b/src/core/math/Vector2.h
index 0434cd57a16c3905e7aa7e3fb2fbff229cba950c..65da26a585ed9f873ed0b271800d0d998109119d 100644
--- a/src/core/math/Vector2.h
+++ b/src/core/math/Vector2.h
@@ -84,7 +84,7 @@ namespace math {
 template< typename Type >
 class Vector2
 {
-   static_assert( std::is_arithmetic<Type>::value, "Vector2 only accepts arithmetic data types" );
+   static_assert( std::is_arithmetic_v<Type>, "Vector2 only accepts arithmetic data types" );
 
 private:
    //**Friend declarations*************************************************************************
@@ -160,8 +160,8 @@ public:
    inline Length          length()                       const;
    inline Type            sqrLength()                    const;
    inline Vector2<Length> getNormalized()                const;
-   inline Type*           data()                         {return v_;}
-   inline Type const *    data()                         const {return v_;}
+   inline Type*           data()                         {return v_.data();}
+   inline Type const *    data()                         const {return v_.data();}
    //@}
    //*******************************************************************************************************************
 
@@ -178,11 +178,11 @@ public:
     * 0 & 1 \\
     * \end{array}\right)\f]
    **/
-   Type v_[2] = {Type(), Type()};
+   std::array< Type, 2 > v_ = { Type(), Type() };
    //@}
    //*******************************************************************************************************************
 };
-static_assert( std::is_trivially_copyable<Vector2<real_t>>::value, "Vector2<real_t> has to be trivially copyable!");
+static_assert( std::is_trivially_copyable_v<Vector2<real_t>>, "Vector2<real_t> has to be trivially copyable!");
 //**********************************************************************************************************************
 
 template<typename T>
@@ -220,7 +220,7 @@ template< typename Type >
 template< typename Other >
 inline Vector2<Type>::Vector2( Other init )
 {
-   static_assert( std::is_arithmetic<Other>::value, "Vector2 only accepts arithmetic data types in Vector2( Other init )");
+   static_assert( std::is_arithmetic_v<Other>, "Vector2 only accepts arithmetic data types in Vector2( Other init )");
 
    v_[0] = v_[1] = init;
 }
@@ -1315,7 +1315,7 @@ inline bool operator!=( long double scalar, const Vector2<Type>& vec )
 // \return The scaled result vector.
 */
 template< typename Type, typename Other >
-inline typename std::enable_if< std::is_fundamental<Other>::value, Vector2<HIGH> >::type
+inline std::enable_if_t< std::is_fundamental_v<Other>, Vector2<HIGH> >
    operator*( Other scalar, const Vector2<Type>& vec )
 {
    return vec * scalar;
@@ -1510,9 +1510,9 @@ inline const Vector2<Type> fabs( const Vector2<Type>& v )
 template<typename T>
 Vector2<T> & normalize( Vector2<T> & v )
 {
-   static_assert( std::is_floating_point<T>::value,
+   static_assert( std::is_floating_point_v<T>,
       "You can only normalize floating point vectors in-place!");
-   static_assert( (std::is_same<T, typename Vector2<T>::Length>::value),
+   static_assert( (std::is_same_v<T, typename Vector2<T>::Length>),
       "The type of your Vector2's length does not match its element type!" );
 
    const T len( v.length() );
@@ -1561,7 +1561,7 @@ struct Vector2LexicographicalyLess
 // \param   v The vector the hash is computed for.
 // \returns   A hash for the entire Vector2.
 */
-template< typename T, typename Enable = std::enable_if_t<std::is_integral<T>::value> >
+template< typename T, typename Enable = std::enable_if_t<std::is_integral_v<T>> >
 std::size_t hash_value( const Vector2<T> & v )
 {
    std::size_t seed;
@@ -1606,7 +1606,7 @@ namespace mpi {
    mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, const Vector2<VT> & vec )
    {
       buf.addDebugMarker( "v2" );
-      static_assert ( std::is_trivially_copyable< Vector2<VT> >::value,
+      static_assert ( std::is_trivially_copyable_v< Vector2<VT> >,
                       "type has to be trivially copyable for the memcpy to work correctly" );
       auto pos = buf.forward(sizeof(Vector2<VT>));
       std::memcpy(pos, &vec, sizeof(Vector2<VT>));
@@ -1618,7 +1618,7 @@ namespace mpi {
    mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, Vector2<VT> & vec )
    {
       buf.readDebugMarker( "v2" );
-      static_assert ( std::is_trivially_copyable< Vector2<VT> >::value,
+      static_assert ( std::is_trivially_copyable_v< Vector2<VT> >,
                       "type has to be trivially copyable for the memcpy to work correctly" );
       auto pos = buf.skip(sizeof(Vector2<VT>));
       //suppress https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-Wclass-memaccess
diff --git a/src/core/math/Vector3.h b/src/core/math/Vector3.h
index 81745b3bd552cbde1baf9b4b475b01981bd4f888..0e50a16384936c4ad0eff10abfec19b66108c9da 100644
--- a/src/core/math/Vector3.h
+++ b/src/core/math/Vector3.h
@@ -84,7 +84,7 @@ namespace math {
 template< typename Type >
 class Vector3
 {
-   static_assert( std::is_arithmetic<Type>::value, "Vector3 only accepts arithmetic data types" );
+   static_assert( std::is_arithmetic_v<Type>, "Vector3 only accepts arithmetic data types" );
 
 private:
    //**Friend declarations*************************************************************************
@@ -167,8 +167,8 @@ public:
    inline Vector3<Length> getNormalizedOrZero()          const;
    inline Vector3<Length> getNormalizedIfNotZero()       const;
    inline void            reset();
-   inline Type*           data()                         {return v_;}
-   inline Type const *    data()                         const {return v_;}
+   inline Type*           data()                         {return v_.data();}
+   inline Type const *    data()                         const {return v_.data();}
    //@}
    //*******************************************************************************************************************
 
@@ -185,11 +185,11 @@ public:
     * 0 & 1 & 2 \\
     * \end{array}\right)\f]
    **/
-   Type v_[3] = {Type(), Type(), Type()};
+   std::array< Type, 3 > v_ = { Type(), Type(), Type() };
    //@}
    //*******************************************************************************************************************
 };
-static_assert( std::is_trivially_copyable<Vector3<real_t>>::value, "Vector3<real_t> has to be trivially copyable!");
+static_assert( std::is_trivially_copyable_v<Vector3<real_t>>, "Vector3<real_t> has to be trivially copyable!");
 //**********************************************************************************************************************
 
 template<typename T>
@@ -227,7 +227,7 @@ template< typename Type >
 template< typename Other >
 inline constexpr Vector3<Type>::Vector3( Other init )
 {
-   static_assert( std::is_arithmetic<Other>::value, "Vector3 only accepts arithmetic data types in Vector3( Other init )");
+   static_assert( std::is_arithmetic_v<Other>, "Vector3 only accepts arithmetic data types in Vector3( Other init )");
 
    v_[0] = v_[1] = v_[2] = numeric_cast<Type>(init);
 }
@@ -1492,7 +1492,7 @@ inline bool operator!=( long double scalar, const Vector3<Type>& vec )
 // \return The scaled result vector.
 */
 template< typename Type, typename Other >
-inline typename std::enable_if< std::is_fundamental<Other>::value, Vector3<HIGH> >::type
+inline std::enable_if_t< std::is_fundamental_v<Other>, Vector3<HIGH> >
    operator*( Other scalar, const Vector3<Type>& vec )
 {
    return vec * scalar;
@@ -1759,9 +1759,9 @@ inline void normals(const Vector3<Type>& v, Vector3<Type>& defNor, Vector3<Type>
 template<typename T>
 Vector3<T> & normalize( Vector3<T> & v )
 {
-   static_assert( std::is_floating_point<T>::value,
+   static_assert( std::is_floating_point_v<T>,
       "You can only normalize floating point vectors in-place!");
-   static_assert( (std::is_same<T, typename Vector3<T>::Length>::value),
+   static_assert( (std::is_same_v<T, typename Vector3<T>::Length>),
       "The type of your Vector3's length does not match its element type!" );
 
    const T len( v.length() );
@@ -1847,7 +1847,7 @@ struct Vector3LexicographicalyLess
 // \param   v The vector the hash is computed for.
 // \returns   A hash for the entire Vector3.
 */
-template< typename T, typename Enable = std::enable_if_t<std::is_integral<T>::value> >
+template< typename T, typename Enable = std::enable_if_t<std::is_integral_v<T>> >
 std::size_t hash_value( const Vector3<T> & v )
 {
    std::size_t seed;
@@ -1891,7 +1891,7 @@ namespace mpi {
    mpi::GenericSendBuffer<T,G>& operator<<( mpi::GenericSendBuffer<T,G> & buf, const Vector3<VT> & vec )
    {
       buf.addDebugMarker( "v3" );
-      static_assert ( std::is_trivially_copyable< Vector3<VT> >::value,
+      static_assert ( std::is_trivially_copyable_v< Vector3<VT> >,
                       "type has to be trivially copyable for the memcpy to work correctly" );
       auto pos = buf.forward(sizeof(Vector3<VT>));
       std::memcpy(pos, &vec, sizeof(Vector3<VT>));
@@ -1903,7 +1903,7 @@ namespace mpi {
    mpi::GenericRecvBuffer<T>& operator>>( mpi::GenericRecvBuffer<T> & buf, Vector3<VT> & vec )
    {
       buf.readDebugMarker( "v3" );
-      static_assert ( std::is_trivially_copyable< Vector3<VT> >::value,
+      static_assert ( std::is_trivially_copyable_v< Vector3<VT> >,
                       "type has to be trivially copyable for the memcpy to work correctly" );
       auto pos = buf.skip(sizeof(Vector3<VT>));
       //suppress https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#index-Wclass-memaccess
diff --git a/src/core/mpi/BufferSizeTrait.h b/src/core/mpi/BufferSizeTrait.h
index 365c911544336370004a5e7da057964c3e234550..ab8f4c1c2cc50ef6b1b3740035aad65929ed8aa3 100644
--- a/src/core/mpi/BufferSizeTrait.h
+++ b/src/core/mpi/BufferSizeTrait.h
@@ -67,7 +67,7 @@ namespace mpi {
 
    // Specialization for all enums
    template< typename T>
-   struct BufferSizeTrait< T, typename std::enable_if< std::is_enum< T >::value >::type >
+   struct BufferSizeTrait< T, std::enable_if_t< std::is_enum_v< T > > >
    {
       static const bool constantSize = true;
       static const size_t size = sizeof( T ) + BUFFER_DEBUG_OVERHEAD;
diff --git a/src/core/mpi/BufferSystem.h b/src/core/mpi/BufferSystem.h
index 02bdd60bb38452899d84abeb78d19c68b03f1b69..fdd7d093ab0d072c3efaeecff1617d83627fb4f5 100644
--- a/src/core/mpi/BufferSystem.h
+++ b/src/core/mpi/BufferSystem.h
@@ -176,7 +176,7 @@ public:
       GenericBufferSystem & bufferSystem_;
 
       RecvBuffer_T * currentRecvBuffer_;
-      MPIRank        currentSenderRank_;
+      MPIRank        currentSenderRank_{ -1 };
 
       friend class GenericBufferSystem;
    };
@@ -235,8 +235,8 @@ protected:
    internal::NoMPICommunication<RecvBuffer_T, SendBuffer_T>             noMPIComm_;
    internal::AbstractCommunication<RecvBuffer_T, SendBuffer_T> *        currentComm_;  //< after receiver setup, this points to unknown- or knownSizeComm_
 
-   bool sizeChangesEverytime_; //< if set to true, the receiveSizeUnknown_ is set to true before communicating
-   bool communicationRunning_; //< indicates if a communication step is currently running
+   bool sizeChangesEverytime_{ true }; //< if set to true, the receiveSizeUnknown_ is set to true before communicating
+   bool communicationRunning_{ false }; //< indicates if a communication step is currently running
 
 
    /// Info about the message to be received from a certain rank:
diff --git a/src/core/mpi/BufferSystem.impl.h b/src/core/mpi/BufferSystem.impl.h
index b927d242daa869ec294916f0991c6a94e5bce88d..58fa6e48724b3306b4925bfe33d4a81869a9f8c3 100644
--- a/src/core/mpi/BufferSystem.impl.h
+++ b/src/core/mpi/BufferSystem.impl.h
@@ -1,15 +1,15 @@
 //======================================================================================================================
 //
-//  This file is part of waLBerla. waLBerla is free software: you can 
+//  This file is part of waLBerla. waLBerla 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.
-//  
-//  waLBerla 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 
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
@@ -41,7 +41,7 @@ std::set<int> GenericBufferSystem<Rb, Sb>::activeTags_;
 
 template< typename Rb, typename Sb>
 GenericBufferSystem<Rb, Sb>::iterator::iterator( GenericBufferSystem<Rb, Sb> & bufferSystem, bool begin )
-    : bufferSystem_( bufferSystem), currentRecvBuffer_( nullptr ), currentSenderRank_( -1 )
+    : bufferSystem_( bufferSystem), currentRecvBuffer_( nullptr )
 {
    if ( begin ) // init iterator
       ++(*this);
@@ -129,9 +129,7 @@ GenericBufferSystem<Rb, Sb>::GenericBufferSystem( const MPI_Comm & communicator,
      unknownSizeComm_( communicator, tag ),
      unknownSizeCommIProbe_( communicator, tag ),
      noMPIComm_( communicator, tag ),
-     currentComm_    ( nullptr ),
-     sizeChangesEverytime_( true ),
-     communicationRunning_( false )
+     currentComm_    ( nullptr )
 {
 }
 
diff --git a/src/core/mpi/Gatherv.cpp b/src/core/mpi/Gatherv.cpp
index af9aea36cf657f8c17dc977d6484c3b4a2d1eb4f..2a4f28a854d444af521dce63d76c38bae6436bb0 100644
--- a/src/core/mpi/Gatherv.cpp
+++ b/src/core/mpi/Gatherv.cpp
@@ -41,7 +41,7 @@ std::vector< std::string > gatherv( const std::vector< std::string > & values, i
 {
    WALBERLA_NON_MPI_SECTION()
    {
-      return std::vector< std::string >( values );
+      return { values };
    }
 
    mpi::SendBuffer sb;
@@ -64,14 +64,14 @@ std::vector< std::string > gatherv( const std::vector< std::string > & values, i
       {
          std::vector< std::string > tmp;
          rb >> tmp;
-         for( auto it = tmp.begin(); it != tmp.end(); ++it )
-            result.push_back( *it );
+         for(auto & it : tmp)
+            result.push_back( it );
       }
 
       return result;
    }
 
-   return std::vector< std::string >();
+   return {};
 }
 
 template<>
diff --git a/src/core/mpi/MPIIO.cpp b/src/core/mpi/MPIIO.cpp
index 13b90c7a20139ce4eb5dd8e3b02ea1b0ab2e1fdc..ee1b66184f7aa598494fe45a93364ab0d0fd124b 100644
--- a/src/core/mpi/MPIIO.cpp
+++ b/src/core/mpi/MPIIO.cpp
@@ -62,7 +62,7 @@ void writeMPIIO(const std::string& file, SendBuffer& buffer)
       const uint_t offset = uint_c(mpi::MPIManager::instance()->numProcesses() * 2 * uintSize) + exscanResult;
 
       // header of the file contains each process' offset and buffer size
-      uint_t offsetData[2];
+      std::array< uint_t, 2 > offsetData;
       offsetData[0] = offset; // position at which a process writes its data
       offsetData[1] = uint_c(buffer.size());
 
@@ -84,7 +84,7 @@ void writeMPIIO(const std::string& file, SendBuffer& buffer)
                }
                if (ofile.fail()) { WALBERLA_ABORT("Error while opening file \"" << file << "\" for writing."); }
 
-               ofile.write(reinterpret_cast< const char* >(offsetData), numeric_cast< std::streamsize >(2 * uintSize));
+               ofile.write(reinterpret_cast< const char* >(offsetData.data()), numeric_cast< std::streamsize >(2 * uintSize));
                if (ofile.fail()) { WALBERLA_ABORT("Error while writing to file \"" << file << "\"."); }
 
                ofile.close();
@@ -138,7 +138,7 @@ void writeMPIIO(const std::string& file, SendBuffer& buffer)
             WALBERLA_ABORT("Internal MPI-IO error! MPI Error is \"" << MPIManager::instance()->getMPIErrorString(result)
                                                                     << "\"");
 
-         result = MPI_File_write_all(mpiFile, reinterpret_cast< char* >(offsetData), 2, MPITrait< uint_t >::type(),
+         result = MPI_File_write_all(mpiFile, reinterpret_cast< char* >(offsetData.data()), 2, MPITrait< uint_t >::type(),
                                      MPI_STATUS_IGNORE);
 
          if (result != MPI_SUCCESS)
@@ -202,7 +202,7 @@ void readMPIIO(const std::string& file, RecvBuffer& buffer)
       MPI_Type_size(MPITrait< uint_t >::type(), &uintSize);
 
       // header of the file contains each process' offset and buffer size
-      uint_t offsetData[2];
+      std::array< uint_t, 2 > offsetData;
 
       // use serial I/O for versions of OpenMPI that produce segmentation faults when using MPI-IO with a 3D
       // Cartesian MPI communicator (see waLBerla issue #73)
@@ -219,7 +219,7 @@ void readMPIIO(const std::string& file, RecvBuffer& buffer)
                if (ifile.fail()) { WALBERLA_ABORT("Error while opening file \"" << file << "\" for reading."); }
 
                ifile.seekg(numeric_cast< std::streamoff >(mpi::MPIManager::instance()->rank() * 2 * uintSize));
-               ifile.read(reinterpret_cast< char* >(offsetData), numeric_cast< std::streamsize >(2 * uintSize));
+               ifile.read(reinterpret_cast< char* >(offsetData.data()), numeric_cast< std::streamsize >(2 * uintSize));
                if (ifile.fail()) { WALBERLA_ABORT("Error while reading from file \"" << file << "\"."); }
 
                ifile.close();
@@ -272,7 +272,7 @@ void readMPIIO(const std::string& file, RecvBuffer& buffer)
             WALBERLA_ABORT("Internal MPI-IO error! MPI Error is \"" << MPIManager::instance()->getMPIErrorString(result)
                                                                     << "\"");
 
-         result = MPI_File_read_all(mpiFile, reinterpret_cast< char* >(offsetData), 2, MPITrait< uint_t >::type(),
+         result = MPI_File_read_all(mpiFile, reinterpret_cast< char* >(offsetData.data()), 2, MPITrait< uint_t >::type(),
                                     MPI_STATUS_IGNORE);
 
          if (result != MPI_SUCCESS)
diff --git a/src/core/mpi/MPIManager.cpp b/src/core/mpi/MPIManager.cpp
index c25ca1082277d89c8be486ae7a9c61350d6bfea0..d8f3a653dd87c08efb907c2069bd465160a5a153 100644
--- a/src/core/mpi/MPIManager.cpp
+++ b/src/core/mpi/MPIManager.cpp
@@ -150,7 +150,7 @@ void MPIManager::resetMPI()
    }
 }
 
-void MPIManager::createCartesianComm(int dims[3], int periodicity[3])
+void MPIManager::createCartesianComm(const std::array< int, 3 >& dims, const std::array< int, 3 >& periodicity)
 {
    WALBERLA_ASSERT(isMPIInitialized_);
    WALBERLA_ASSERT_EQUAL(rank_, -1);
@@ -159,7 +159,7 @@ void MPIManager::createCartesianComm(int dims[3], int periodicity[3])
    WALBERLA_ASSERT_GREATER(dims[1], 0);
    WALBERLA_ASSERT_GREATER(dims[2], 0);
 
-   MPI_Cart_create(MPI_COMM_WORLD, 3, dims, periodicity, true, &comm_);
+   MPI_Cart_create(MPI_COMM_WORLD, 3, dims.data(), periodicity.data(), true, &comm_);
    MPI_Comm_rank(comm_, &rank_);
    cartesianSetup_ = true;
 
@@ -169,12 +169,12 @@ void MPIManager::createCartesianComm(int dims[3], int periodicity[3])
 void MPIManager::createCartesianComm(const uint_t xProcesses, const uint_t yProcesses, const uint_t zProcesses,
                                      const bool xPeriodic, const bool yPeriodic, const bool zPeriodic)
 {
-   int dims[3];
+   std::array< int, 3 > dims;
    dims[0] = numeric_cast< int >(xProcesses);
    dims[1] = numeric_cast< int >(yProcesses);
    dims[2] = numeric_cast< int >(zProcesses);
 
-   int periodicity[3];
+   std::array< int, 3 > periodicity;
    periodicity[0] = xPeriodic ? 1 : 0;
    periodicity[1] = yPeriodic ? 1 : 0;
    periodicity[2] = zPeriodic ? 1 : 0;
@@ -182,31 +182,31 @@ void MPIManager::createCartesianComm(const uint_t xProcesses, const uint_t yProc
    createCartesianComm(dims, periodicity);
 }
 
-void MPIManager::cartesianCoord(int coordOut[3]) const { cartesianCoord(rank_, coordOut); }
+void MPIManager::cartesianCoord(std::array< int, 3 >& coordOut) const { cartesianCoord(rank_, coordOut); }
 
-void MPIManager::cartesianCoord(int rankIn, int coordOut[3]) const
+void MPIManager::cartesianCoord(int rankIn, std::array< int, 3 >& coordOut) const
 {
    WALBERLA_ASSERT(isMPIInitialized_);
    WALBERLA_ASSERT(cartesianSetup_);
    WALBERLA_ASSERT_UNEQUAL(comm_, MPI_COMM_NULL);
 
-   MPI_Cart_coords(comm_, rankIn, 3, coordOut);
+   MPI_Cart_coords(comm_, rankIn, 3, coordOut.data());
 }
 
-int MPIManager::cartesianRank(int coords[3]) const
+int MPIManager::cartesianRank(std::array< int, 3 >& coords) const
 {
    WALBERLA_ASSERT(isMPIInitialized_);
    WALBERLA_ASSERT(cartesianSetup_);
    WALBERLA_ASSERT_UNEQUAL(comm_, MPI_COMM_NULL);
 
    int r;
-   MPI_Cart_rank(comm_, coords, &r);
+   MPI_Cart_rank(comm_, coords.data(), &r);
    return r;
 }
 
 int MPIManager::cartesianRank(const uint_t x, const uint_t y, const uint_t z) const
 {
-   int coords[3];
+   std::array< int, 3 > coords;
    coords[0] = numeric_cast< int >(x);
    coords[1] = numeric_cast< int >(y);
    coords[2] = numeric_cast< int >(z);
@@ -273,7 +273,7 @@ std::string MPIManager::getMPIErrorString(int errorCode)
 
    WALBERLA_ASSERT_GREATER_EQUAL(resultLen, 0);
    WALBERLA_ASSERT_LESS_EQUAL(resultLen, numeric_cast< int >(errorString.size()));
-   return std::string(errorString.begin(), errorString.begin() + resultLen);
+   return { errorString.begin(), errorString.begin() + resultLen };
 }
 
 std::string MPIManager::getMPICommName(MPI_Comm comm)
@@ -291,7 +291,7 @@ std::string MPIManager::getMPICommName(MPI_Comm comm)
 
    WALBERLA_ASSERT_GREATER_EQUAL(resultLen, 0);
    WALBERLA_ASSERT_LESS_EQUAL(resultLen, numeric_cast< int >(commName.size()));
-   return std::string(commName.begin(), commName.begin() + resultLen);
+   return { commName.begin(), commName.begin() + resultLen };
 }
 
 } // namespace mpi
diff --git a/src/core/mpi/MPIManager.h b/src/core/mpi/MPIManager.h
index 60ce4d8514e57bb2465a14dfa304cab73b3b8be6..f27f9901a67d986bf5b4039fc51931ae934a3365 100644
--- a/src/core/mpi/MPIManager.h
+++ b/src/core/mpi/MPIManager.h
@@ -81,17 +81,17 @@ public:
    /*! \name Cartesian Communicator */
    //@{
 
-   void createCartesianComm( int numberOfProcessors[3], int periodicity[3] );
+   void createCartesianComm(const std::array< int, 3 >&, const std::array< int, 3 >&);
    void createCartesianComm( const uint_t xProcesses,        const uint_t  yProcesses,        const uint_t zProcesses,
                              const bool   xPeriodic = false, const bool    yPeriodic = false, const bool   zPeriodic = false );
 
    /// Cartesian coordinates of own rank
-   void cartesianCoord( int coordOut[3] ) const;
+   void cartesianCoord(std::array< int, 3 >& coordOut) const;
    /// Cartesian coordinates of given rank
-   void cartesianCoord( int rank, int coordOut[3] ) const;
+   void cartesianCoord(int rank, std::array< int, 3 >& coordOut) const;
 
    /// translates Cartesian coordinates to rank
-   int cartesianRank( int coords[3] ) const;
+   int cartesianRank(std::array< int, 3 >& coords) const;
    /// translates Cartesian coordinates to rank
    int cartesianRank( const uint_t x, const uint_t y, const uint_t z ) const;
 
diff --git a/src/core/mpi/OpenMPBufferSystem.h b/src/core/mpi/OpenMPBufferSystem.h
index 660a5ccebe415e129f5965c3ef5a418731ef71df..2a282abd6826971f50447145b1981858215d6a21 100644
--- a/src/core/mpi/OpenMPBufferSystem.h
+++ b/src/core/mpi/OpenMPBufferSystem.h
@@ -78,14 +78,14 @@ public:
 private:
    GenericBufferSystem<RecvBuffer_T, SendBuffer_T> bs_;
 
-   bool dirty_;
+   bool dirty_{ true };
 
    void setupBufferSystem();
 
    bool serialSends_;
    bool serialRecvs_;
 
-   bool sizeChangesEverytime_;
+   bool sizeChangesEverytime_{ true };
 
    std::map<MPIRank, std::function<void ( RecvBuffer_T & )> > recvFunctions_;
 
diff --git a/src/core/mpi/OpenMPBufferSystem.impl.h b/src/core/mpi/OpenMPBufferSystem.impl.h
index f87895d7a3467ae4f7984e91e95c1c75472e13b3..ec59f5ad14e34e1768d41bbdce893b697a531604 100644
--- a/src/core/mpi/OpenMPBufferSystem.impl.h
+++ b/src/core/mpi/OpenMPBufferSystem.impl.h
@@ -35,10 +35,8 @@ template<typename Rb, typename Sb>
 GenericOpenMPBufferSystem<Rb, Sb>::GenericOpenMPBufferSystem( const MPI_Comm & communicator, int tag,
                                                               bool _serialSends, bool _serialRecvs  )
    : bs_( communicator, tag),
-     dirty_( true ),
      serialSends_( _serialSends ),
-     serialRecvs_( _serialRecvs ),
-     sizeChangesEverytime_( true )
+     serialRecvs_( _serialRecvs )
 {
 }
 
diff --git a/src/core/mpi/RecvBuffer.h b/src/core/mpi/RecvBuffer.h
index 69c0a26d213176f42b5eba8bf604b0d24915c530..04dccbfcb29258298efbd15ff1abd051a395af3c 100644
--- a/src/core/mpi/RecvBuffer.h
+++ b/src/core/mpi/RecvBuffer.h
@@ -124,8 +124,8 @@ public:
    /*!\name Operators */
    //@{
    template< typename V >
-   typename std::enable_if< std::is_arithmetic<V>::value || std::is_enum<V>::value,
-                              GenericRecvBuffer& >::type
+   std::enable_if_t< std::is_arithmetic_v<V> || std::is_enum_v<V>,
+                              GenericRecvBuffer& >
    operator>>( V& value );
    //@}
    //*******************************************************************************************************************
@@ -159,8 +159,8 @@ private:
    /*!\name Utility functions */
    //@{
    template< typename V >
-   typename std::enable_if< std::is_arithmetic<V>::value || std::is_enum<V>::value,
-                              GenericRecvBuffer& >::type
+   std::enable_if_t< std::is_arithmetic_v<V> || std::is_enum_v<V>,
+                              GenericRecvBuffer& >
    get( V& value );
    //@}
    //*******************************************************************************************************************
@@ -168,7 +168,7 @@ private:
 
 
    //**Compile time checks**********************************************************************************************
-   static_assert( std::is_arithmetic<T>::value, "SendBuffer<T>: T has to be native datatype" ) ;
+   static_assert( std::is_arithmetic_v<T>, "SendBuffer<T>: T has to be native datatype" ) ;
    //*******************************************************************************************************************
 };
 //**********************************************************************************************************************
@@ -227,7 +227,7 @@ inline GenericRecvBuffer<T>::GenericRecvBuffer( GenericSendBuffer<T,G> & sb )
    , cur_( sb.begin_ )
    , end_( sb.end_ )
 {
-   sb.begin_ = new T[0];
+   sb.begin_ = nullptr;
    sb.cur_   = sb.begin_;
    sb.end_   = sb.begin_;
 }
@@ -385,12 +385,12 @@ inline bool GenericRecvBuffer<T>::isEmpty() const
 */
 template< typename T >  // Element type
 template< typename V >  // Type of the built-in data value
-typename std::enable_if< std::is_arithmetic<V>::value || std::is_enum<V>::value,
-                           GenericRecvBuffer<T> & >::type
+std::enable_if_t< std::is_arithmetic_v<V> || std::is_enum_v<V>,
+                           GenericRecvBuffer<T> & >
 GenericRecvBuffer<T>::get( V& value )
 {
    // Compile time check that V is built-in data type
-   static_assert( std::is_arithmetic<V>::value || std::is_enum<V>::value,
+   static_assert( std::is_arithmetic_v<V> || std::is_enum_v<V>,
                             "RecvBuffer accepts only built-in data types");
 
 
@@ -427,8 +427,8 @@ GenericRecvBuffer<T>::get( V& value )
 */
 template< typename T >  // Element type
 template< typename V >  // Type of the built-in data value
-typename std::enable_if< std::is_arithmetic<V>::value || std::is_enum<V>::value,
-                           GenericRecvBuffer<T> & >::type
+std::enable_if_t< std::is_arithmetic_v<V> || std::is_enum_v<V>,
+                           GenericRecvBuffer<T> & >
 GenericRecvBuffer<T>::operator>>( V& value )
 {
    readDebugMarker( typeid(V).name() );
@@ -550,7 +550,7 @@ template< typename T >  // Element type
 template< typename V >  // Type of the built-in data value
 inline void GenericRecvBuffer<T>::peek( V& value ) const
 {
-   WALBERLA_STATIC_ASSERT( std::is_arithmetic<V>::value );
+   WALBERLA_STATIC_ASSERT( std::is_arithmetic_v<V> );
 
    WALBERLA_STATIC_ASSERT( sizeof(V) > sizeof(T) );
    WALBERLA_STATIC_ASSERT( sizeof(V) % sizeof(T) == 0);
diff --git a/src/core/mpi/Reduce.h b/src/core/mpi/Reduce.h
index a0b6edb39cad16fdfa5c527f83f9fe007ba9fa2c..20deeb5ca85ee24d07687f60b16fd8d6eda09c69 100644
--- a/src/core/mpi/Reduce.h
+++ b/src/core/mpi/Reduce.h
@@ -56,7 +56,7 @@ namespace mpi
 template< typename T >
 void reduceInplace( T & value, Operation operation, int recvRank = 0, MPI_Comm comm = MPI_COMM_WORLD )
 {
-   static_assert( std::is_arithmetic<T>::value, "reduceInplace(...) may only by called with integer or floating point types!" );
+   static_assert( std::is_arithmetic_v<T>, "reduceInplace(...) may only by called with integer or floating point types!" );
 
    WALBERLA_NON_MPI_SECTION()
    {
@@ -135,7 +135,7 @@ inline void reduceInplace( bool & value, Operation operation, int recvRank = 0,
 template< typename T >
 T reduce( const T value, Operation operation, int recvRank = 0, MPI_Comm comm = MPI_COMM_WORLD )
 {
-   static_assert( std::is_arithmetic<T>::value, "reduce(...) may only by called with integer or floating point types!" );
+   static_assert( std::is_arithmetic_v<T>, "reduce(...) may only by called with integer or floating point types!" );
 
    WALBERLA_NON_MPI_SECTION()
    {
@@ -217,7 +217,7 @@ inline bool reduce( const bool value, Operation operation, int recvRank = 0, MPI
 template< typename T >
 void reduceInplace( std::vector<T> & values, Operation operation, int recvRank = 0, MPI_Comm comm = MPI_COMM_WORLD )
 {
-   static_assert( std::is_arithmetic<T>::value, "reduceInplace(...) may only by called with integer or floating point types!" );
+   static_assert( std::is_arithmetic_v<T>, "reduceInplace(...) may only by called with integer or floating point types!" );
 
    WALBERLA_NON_MPI_SECTION()
    {
@@ -296,7 +296,7 @@ inline void reduceInplace( std::vector<bool> & values, Operation operation, int
 template< typename T >
 void reduceInplace( math::Vector3<T> & values, Operation operation, int recvRank = 0, MPI_Comm comm = MPI_COMM_WORLD )
 {
-   static_assert( std::is_arithmetic<T>::value, "reduceInplace(...) may only by called with integer or floating point types!" );
+   static_assert( std::is_arithmetic_v<T>, "reduceInplace(...) may only by called with integer or floating point types!" );
 
    WALBERLA_NON_MPI_SECTION()
    {
@@ -374,7 +374,7 @@ inline void reduceInplace( math::Vector3<bool> & values, Operation operation, in
 template< typename T >
 math::Vector3<T> reduce( const math::Vector3<T> & values, Operation operation, int recvRank = 0, MPI_Comm comm = MPI_COMM_WORLD )
 {
-   static_assert( std::is_arithmetic<T>::value, "reduce(...) may only by called with integer or floating point types!" );
+   static_assert( std::is_arithmetic_v<T>, "reduce(...) may only by called with integer or floating point types!" );
 
    WALBERLA_NON_MPI_SECTION()
    {
@@ -460,7 +460,7 @@ inline math::Vector3<bool> reduce( const math::Vector3<bool> & values, Operation
 template< typename T >
 T allReduce( const T & value, Operation operation, MPI_Comm comm = MPI_COMM_WORLD )
 {
-   static_assert( std::is_arithmetic<T>::value, "allReduce(...) may only by called with integer or floating point types!" );
+   static_assert( std::is_arithmetic_v<T>, "allReduce(...) may only by called with integer or floating point types!" );
 
    WALBERLA_NON_MPI_SECTION() { return value; }
 
@@ -513,7 +513,7 @@ inline bool allReduce( const bool value, Operation operation, MPI_Comm comm = MP
 template< typename T >
 void allReduceInplace( T & value, Operation operation, MPI_Comm comm = MPI_COMM_WORLD )
 {
-   static_assert( std::is_arithmetic<T>::value, "allReduceInplace(...) may only by called with integer or floating point types!" );
+   static_assert( std::is_arithmetic_v<T>, "allReduceInplace(...) may only by called with integer or floating point types!" );
 
    WALBERLA_NON_MPI_SECTION() { return; }
 
@@ -561,7 +561,7 @@ inline void allReduceInplace( bool & value, Operation operation, MPI_Comm comm =
 template< typename T >
 void allReduceInplace( std::vector<T> & values, Operation operation, MPI_Comm comm = MPI_COMM_WORLD )
 {
-   static_assert( std::is_arithmetic<T>::value, "allReduceInplace(...) may only by called with integer or floating point types!" );
+   static_assert( std::is_arithmetic_v<T>, "allReduceInplace(...) may only by called with integer or floating point types!" );
 
    WALBERLA_NON_MPI_SECTION() { return; }
 
@@ -611,7 +611,7 @@ inline void allReduceInplace( std::vector<bool> & bools, Operation operation, MP
 template< typename T >
 void allReduceInplace( math::Vector3<T> & values, Operation operation, MPI_Comm comm = MPI_COMM_WORLD )
 {
-   static_assert( std::is_arithmetic<T>::value, "allReduceInplace(...) may only by called with integer or floating point types!" );
+   static_assert( std::is_arithmetic_v<T>, "allReduceInplace(...) may only by called with integer or floating point types!" );
 
    WALBERLA_NON_MPI_SECTION() { return; }
 
diff --git a/src/core/mpi/SendBuffer.h b/src/core/mpi/SendBuffer.h
index f167a4459f5aadb411b30f891bc5bff6b010a41f..d0663d2b8a900056d158560309b2b30b007f1256 100644
--- a/src/core/mpi/SendBuffer.h
+++ b/src/core/mpi/SendBuffer.h
@@ -86,7 +86,7 @@ public:
    class Ptr
    {
    public:
-      static_assert( std::is_fundamental<VT>::value, "only fundamental data types are allowed");
+      static_assert( std::is_fundamental_v<VT>, "only fundamental data types are allowed");
       using value_type = VT;
 
       Ptr(GenericSendBuffer<T, G>& buffer, const std::ptrdiff_t offset, const size_t length)
@@ -141,8 +141,8 @@ public:
    /*!\name Operators */
    //@{
    template< typename V >
-   typename std::enable_if< std::is_arithmetic<V>::value || std::is_enum<V>::value,
-   GenericSendBuffer&  >::type
+   std::enable_if_t< std::is_arithmetic_v<V> || std::is_enum_v<V>,
+   GenericSendBuffer&  >
    operator<<( V value );
 
    //@}
@@ -189,8 +189,8 @@ private:
    void extendMemory( size_t newCapacity );
 
    template< typename V >
-   typename std::enable_if< std::is_arithmetic<V>::value || std::is_enum<V>::value,
-   GenericSendBuffer&  >::type
+   std::enable_if_t< std::is_arithmetic_v<V> || std::is_enum_v<V>,
+   GenericSendBuffer&  >
    put( V value );
 
    inline std::ptrdiff_t getOffset() const;
@@ -208,7 +208,7 @@ private:
    //*******************************************************************************************************************
 
    //**Compile time checks**********************************************************************************************
-   static_assert( std::is_arithmetic<T>::value, "SendBuffer<T>: T has to be native datatype" ) ;
+   static_assert( std::is_arithmetic_v<T>, "SendBuffer<T>: T has to be native datatype" ) ;
    //*******************************************************************************************************************
 
    template< typename U >
@@ -438,12 +438,12 @@ inline bool GenericSendBuffer<T,G>::isEmpty() const
 template< typename T    // Element type
           , typename G >  // Growth policy
 template< typename V >  // Type of the built-in data value
-typename std::enable_if< std::is_arithmetic<V>::value || std::is_enum<V>::value,
-GenericSendBuffer<T,G>& >::type
+std::enable_if_t< std::is_arithmetic_v<V> || std::is_enum_v<V>,
+GenericSendBuffer<T,G>& >
 GenericSendBuffer<T,G>::put( V value )
 {
    // Compile time check that V is built-in data type
-   static_assert( std::is_arithmetic<V>::value || std::is_enum<V>::value,
+   static_assert( std::is_arithmetic_v<V> || std::is_enum_v<V>,
                   "SendBuffer accepts only built-in data types");
 
    static_assert( sizeof(V) >= sizeof(T), "Type that is stored has to be bigger than T" );
@@ -483,8 +483,8 @@ GenericSendBuffer<T,G>::put( V value )
 template< typename T    // Element type
           , typename G >  // Growth policy
 template< typename V >  // Type of the built-in data value
-typename std::enable_if< std::is_arithmetic<V>::value || std::is_enum<V>::value,
-GenericSendBuffer<T,G>& >::type
+std::enable_if_t< std::is_arithmetic_v<V> || std::is_enum_v<V>,
+GenericSendBuffer<T,G>& >
 GenericSendBuffer<T,G>::operator<<( V value )
 {
    addDebugMarker( typeid(V).name() );
@@ -697,7 +697,7 @@ template< typename T    // Element type
 inline void GenericSendBuffer<T,G>::reset()
 {
    delete [] begin_;
-   begin_ = new T[0];
+   begin_ = nullptr;
    cur_ = begin_;
    end_ = begin_;
 }
diff --git a/src/core/mpi/SetReduction.h b/src/core/mpi/SetReduction.h
index f9898b449c1931cff7970c209000f226e486cdf4..c7ca52b2f039e0bfc58acb9a2dd730ec764068a3 100644
--- a/src/core/mpi/SetReduction.h
+++ b/src/core/mpi/SetReduction.h
@@ -89,7 +89,7 @@ std::vector<T> allReduceSet( std::vector<T> values, SetOperation op, MPI_Comm mp
       sendBuffer << values;
 
       int sendBufferSize = int_c( sendBuffer.size() );
-      MPI_Request sendRequests[] = { MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL };
+      std::array< MPI_Request, 4 > sendRequests = { MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL };
       MPI_Isend( &sendBufferSize, 1, MPI_INT, commPartner % numberOfRanks, mpiTag, mpiCommunicator, &sendRequests[0] );
       MPI_Isend( sendBuffer.ptr(), sendBufferSize, MPI_CHAR, commPartner % numberOfRanks, mpiTag, mpiCommunicator, &sendRequests[1] );
       if( hasVirtualRank )
@@ -136,7 +136,7 @@ std::vector<T> allReduceSet( std::vector<T> values, SetOperation op, MPI_Comm mp
          swap( values, tmp1 );
       }
 
-      MPI_Waitall( hasVirtualRank ? 4 : 2, sendRequests, MPI_STATUSES_IGNORE );
+      MPI_Waitall( hasVirtualRank ? 4 : 2, sendRequests.data(), MPI_STATUSES_IGNORE );
 
       ++lvl;
       lvlRank = rank >> lvl;
diff --git a/src/core/selectable/SelectableObject.h b/src/core/selectable/SelectableObject.h
index e41af2944e82db5d85ee70b68a39cbc8d63f2d0c..07ec18e1453a2c916e75fce181648a03b81ac62a 100644
--- a/src/core/selectable/SelectableObject.h
+++ b/src/core/selectable/SelectableObject.h
@@ -264,9 +264,9 @@ void SelectableObject<T,A,S>::get( std::vector<T>& object, const S& selector ) c
 
    select( index, selector );
 
-   for( size_t i = 0; i != index.size(); ++i ) {
-      WALBERLA_ASSERT_LESS( index[i], object_.size() );
-      object.push_back( object_[ index[i] ] );
+   for(size_t s : index) {
+      WALBERLA_ASSERT_LESS( s, object_.size() );
+      object.push_back( object_[ s ] );
    }
 }
 
@@ -315,10 +315,10 @@ void SelectableObject<T,A,S>::get( std::vector<T>& object, std::vector< std::str
 
    select( index, selector );
 
-   for( size_t i = 0; i != index.size(); ++i ) {
+   for(size_t i : index) {
       WALBERLA_ASSERT_LESS( index[i], object_.size() );
-      object.push_back( object_[ index[i] ] );
-      identifier.push_back( identifier_[ index[i] ] );
+      object.push_back( object_[ i ] );
+      identifier.push_back( identifier_[ i ] );
    }
 }
 
diff --git a/src/core/timing/TimingNode.h b/src/core/timing/TimingNode.h
index 404feb7d5a2308e4f2131f111e0bc8ffd6e87998..50804915a9f721a218023fcda4486426d7d44c31 100644
--- a/src/core/timing/TimingNode.h
+++ b/src/core/timing/TimingNode.h
@@ -376,9 +376,9 @@ void synchronizeEntries( TimingNode<TP>& tn )
    
    std::set_difference( globalChildNames.begin(), globalChildNames.end(), childNames.begin(), childNames.end(), missingChildNames.begin() );
 
-   for( auto it = missingChildNames.begin(); it != missingChildNames.end(); ++it )
+   for(auto & missingChildName : missingChildNames)
    {
-      tn.tree_[*it].last_ = &tn; // insert missing child and setup correct pointer to parent node
+      tn.tree_[missingChildName].last_ = &tn; // insert missing child and setup correct pointer to parent node
    }
 
    // recurse into children
diff --git a/src/core/timing/TimingPool.cpp b/src/core/timing/TimingPool.cpp
index 28cf668f2d08741bf2ec265726969a4974ab7480..7d18a5a7535f3385ad0e6364d343f71d6ca78300 100644
--- a/src/core/timing/TimingPool.cpp
+++ b/src/core/timing/TimingPool.cpp
@@ -395,9 +395,9 @@ void TimingPool<TP>::unifyRegisteredTimersAcrossProcesses()
       names.push_back( timer->first );
 
    auto gatheredNames = mpi::allReduceSet( names, mpi::UNION );
-   for( auto name = gatheredNames.begin(); name != gatheredNames.end(); ++name )
-      if( !timerExists(*name) )
-         registerTimer( *name );
+   for(auto & gatheredName : gatheredNames)
+      if( !timerExists(gatheredName) )
+         registerTimer( gatheredName );
 }
 
 
diff --git a/src/core/typeToString.h b/src/core/typeToString.h
index ca49ecefa92ac264fea62ecc6f60c3112c479dd4..b02a49a8d3620295ca4048c3921553bbb44289d5 100644
--- a/src/core/typeToString.h
+++ b/src/core/typeToString.h
@@ -27,7 +27,7 @@ namespace walberla {
 template< typename T > inline const char* typeToString();
 
 #define TypeToString(X) template<> inline const char* typeToString< X >() { \
-   static char string[] = #X; \
+   static char string[] = #X; /* NOLINT */ \
    return string; \
 }
 
diff --git a/src/core/uid/GlobalState.h b/src/core/uid/GlobalState.h
index 140dd3b1daaa46a2a8c4a5bfd88e8b1dc918cdf1..90a5bb2a32dda21cc8f75f24efdaa33e4a26bbd6 100644
--- a/src/core/uid/GlobalState.h
+++ b/src/core/uid/GlobalState.h
@@ -59,10 +59,10 @@ public:
 
 private:
 
-   bool      configured_;
+   bool      configured_{ false };
    Set<SUID> state_;
 
-   GlobalState() : configured_( false ) {}
+   GlobalState() {}
 
 };
 
diff --git a/src/core/uid/UIDGenerators.h b/src/core/uid/UIDGenerators.h
index 3d715c9de807582197070fbc64ca87662b812cac..aca73860752c12ded8acd1ee29dc773b14bfb7d4 100644
--- a/src/core/uid/UIDGenerators.h
+++ b/src/core/uid/UIDGenerators.h
@@ -153,7 +153,7 @@ public:
 
 // http://graphics.stanford.edu/~seander/bithacks.html
 
-static const uint8_t logBase2LookupTable[256] =
+static const std::array< uint8_t, 256 > logBase2LookupTable =
 {
 #define logBase2LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
       0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
diff --git a/src/domain_decomposition/BlockCounter.h b/src/domain_decomposition/BlockCounter.h
index f191726cd6d179275ed496a510aa69c586b24a29..4b106edb21e42fe0f313489f13ac9f2fcc148301 100644
--- a/src/domain_decomposition/BlockCounter.h
+++ b/src/domain_decomposition/BlockCounter.h
@@ -85,8 +85,8 @@ public:
 
       mpi::allReduceInplace( numberOfBlocks_, mpi::SUM );
 
-      for( auto numberOfBlocksOnLevel = numberOfBlocks_.begin(); numberOfBlocksOnLevel != numberOfBlocks_.end(); ++numberOfBlocksOnLevel )
-         totalNumberOfBlocks_ += *numberOfBlocksOnLevel;
+      for(const uint_t& numberOfBlock : numberOfBlocks_)
+         totalNumberOfBlocks_ += numberOfBlock;
    }
 
 private:
diff --git a/src/domain_decomposition/BlockDataHandling.h b/src/domain_decomposition/BlockDataHandling.h
index 56b18521f0c65656b3b09b4ec5ff0a430c39c312..4807815b5a5aa43445979825b6df7b9e733de1da 100644
--- a/src/domain_decomposition/BlockDataHandling.h
+++ b/src/domain_decomposition/BlockDataHandling.h
@@ -257,9 +257,9 @@ public:
    shared_ptr< BlockDataHandlingWrapper > getDataHandling( IBlock const * const block, const Set<SUID> & state = Set<SUID>::emptySet() )
    {
       shared_ptr< BlockDataHandlingWrapper > dataHandling;
-      
-      Set<SUID> selection( uid::globalState() + block->getState() + state );
-      size_t numMatches = dataHandling_.get( dataHandling, selection );
+
+      const Set<SUID> selection( uid::globalState() + block->getState() + state );
+      const size_t  numMatches = dataHandling_.get( dataHandling, selection );
 
       if( numMatches > size_t(1) )
       {
diff --git a/src/domain_decomposition/BlockDataID.h b/src/domain_decomposition/BlockDataID.h
index d5e25b5080cd0df6f4e3ea27cf1aebd6cb8f3070..6d1e879d71a0b01d304a972589fb829db6c79d77 100644
--- a/src/domain_decomposition/BlockDataID.h
+++ b/src/domain_decomposition/BlockDataID.h
@@ -64,7 +64,7 @@ private:
    uint_t id_ = 0;
 
 }; // class BlockDataID
-static_assert( std::is_trivially_copyable<BlockDataID>::value, "BlockDataID has to be trivially copyable!");
+static_assert( std::is_trivially_copyable_v<BlockDataID>, "BlockDataID has to be trivially copyable!");
 
 
 class ConstBlockDataID
@@ -93,7 +93,7 @@ private:
    uint_t id_ = 0;
 
 }; // class ConstBlockDataID
-static_assert( std::is_trivially_copyable<ConstBlockDataID>::value, "ConstBlockDataID has to be trivially copyable!");
+static_assert( std::is_trivially_copyable_v<ConstBlockDataID>, "ConstBlockDataID has to be trivially copyable!");
 
 
 } // namespace domain_decomposition
diff --git a/src/domain_decomposition/BlockStorage.cpp b/src/domain_decomposition/BlockStorage.cpp
index bda4c82ed0ec168216da614f0b6b8f59c2c610ca..db9df1d1ed9879690cf62d4f34a8fe6e39b2459d 100644
--- a/src/domain_decomposition/BlockStorage.cpp
+++ b/src/domain_decomposition/BlockStorage.cpp
@@ -99,7 +99,7 @@ BlockDataID BlockStorage::addBlockData( const internal::SelectableBlockDataHandl
 {
    WALBERLA_LOG_PROGRESS( "Adding block data (\"" << identifier << "\")" );
 
-   BlockDataID id( blockDataItem_.size() );
+   const BlockDataID id( blockDataItem_.size() );
    internal::BlockDataItem item( id, identifier, dataHandling );
    blockDataItem_.push_back( item );
 
@@ -135,7 +135,7 @@ BlockDataID BlockStorage::loadBlockData( const std::string & file, const interna
 {
    WALBERLA_LOG_PROGRESS( "Adding block data (\"" << identifier << "\"), loading data from file \"" << file << "\" ..." );
    
-   BlockDataID id( blockDataItem_.size() );
+   const BlockDataID id( blockDataItem_.size() );
    internal::BlockDataItem item( id, identifier, dataHandling );
    blockDataItem_.push_back( item );
    
@@ -147,9 +147,8 @@ BlockDataID BlockStorage::loadBlockData( const std::string & file, const interna
       blocks.push_back( block.get() );
    std::sort( blocks.begin(), blocks.end(), internal::sortBlocksByID );
    
-   for( auto it = blocks.begin(); it != blocks.end(); ++it )
+   for(auto block : blocks)
    {
-      IBlock * block = *it;
       auto dh = item.getDataHandling( block );
       if( dh )
       {
@@ -197,9 +196,8 @@ void BlockStorage::serializeBlockData( const BlockDataID & id, mpi::SendBuffer &
 
    auto & item = blockDataItem_[ uint_t(id) ];
 
-   for( auto it = blocks.begin(); it != blocks.end(); ++it )
+   for(auto block : blocks)
    {
-      IBlock * block = *it;
       auto dh = item.getDataHandling( block );
       if( dh )
          dh->serialize( block, id, buffer );
@@ -224,9 +222,8 @@ void BlockStorage::deserializeBlockData( const BlockDataID & id, mpi::RecvBuffer
 
    auto & item = blockDataItem_[ uint_t(id) ];
 
-   for( auto it = blocks.begin(); it != blocks.end(); ++it )
+   for(auto block : blocks)
    {
-      IBlock * block = *it;
       auto dh = item.getDataHandling( block );
       if( dh )
          dh->deserialize( block, id, buffer );
@@ -252,7 +249,7 @@ MPI_Comm BlockStorage::processesWithBlocksCommunicator()
    {
       if( rebuildProcessesWithBlocksCommunicator_ )
       {
-         int8_t hasBlocks = ( getNumberOfBlocks() > uint_t(0) ) ? int8_t(1) : int8_t(0);
+         const int8_t hasBlocks = ( getNumberOfBlocks() > uint_t(0) ) ? int8_t(1) : int8_t(0);
 
          std::vector<int8_t> processHasBlocks = mpi::allGather( hasBlocks );
 
diff --git a/src/domain_decomposition/BlockStorage.h b/src/domain_decomposition/BlockStorage.h
index 551ff5f6803c0e6f740db717ccf7b2a220048ebb..34a09b7f41234f48e06162aa0734b9601ed56c46 100644
--- a/src/domain_decomposition/BlockStorage.h
+++ b/src/domain_decomposition/BlockStorage.h
@@ -90,7 +90,7 @@ public:
       iterator( const iterator & it )  = default;
 
       iterator & operator++()    { ++it_; checkStateAndAdapt(); return *this; }      // prefix ++X
-      iterator   operator++(int) { iterator it( *this ); operator++(); return it; }; // postfix X++
+      iterator   operator++(int) { const iterator it( *this ); operator++(); return it; }; // postfix X++
 
       bool operator==( const iterator & rhs ) const { return it_ == rhs.it_; }
       bool operator!=( const iterator & rhs ) const { return it_ != rhs.it_; }
@@ -135,7 +135,7 @@ public:
       const_iterator( const const_iterator & it )  = default;
 
       const_iterator & operator++()    { ++it_; checkStateAndAdapt(); return *this; }            // prefix ++X
-      const_iterator   operator++(int) { const_iterator it( *this ); operator++(); return it; }; // postfix X++
+      const_iterator   operator++(int) { const const_iterator it( *this ); operator++(); return it; }; // postfix X++
 
       bool operator==( const const_iterator & rhs ) const { return it_ == rhs.it_; }
       bool operator!=( const const_iterator & rhs ) const { return it_ != rhs.it_; }
@@ -170,7 +170,8 @@ public:
       Set<SUID> incompatibleSelectors_;
    };
 
-
+   /// Deleted default constructor
+   BlockStorage() = delete;
 
    const AABB& getDomain() const { return domain_; } ///< returns an axis-aligned bounding box that covers the entire simulation space/domain
 
@@ -192,14 +193,14 @@ public:
    /// iterator for traversing all locally allocated blocks
    iterator begin( const Set<SUID> & requiredSelectors     = Set<SUID>::emptySet(),
                    const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() )
-      { return iterator( iBlocks_.begin(), iBlocks_.end(), requiredSelectors, incompatibleSelectors ); }
-   iterator   end() { return iterator( iBlocks_.end(), iBlocks_.end() ); } ///< iterator for traversing all locally allocated blocks
+      { return { iBlocks_.begin(), iBlocks_.end(), requiredSelectors, incompatibleSelectors }; }
+   iterator   end() { return { iBlocks_.end(), iBlocks_.end() }; } ///< iterator for traversing all locally allocated blocks
 
    /// iterator for traversing all locally allocated blocks
    const_iterator begin( const Set<SUID> & requiredSelectors     = Set<SUID>::emptySet(),
                          const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() ) const
-      { return const_iterator( iBlocks_.begin(), iBlocks_.end(), requiredSelectors, incompatibleSelectors ); }
-   const_iterator   end() const { return const_iterator( iBlocks_.end(), iBlocks_.end() ); } ///< iterator for traversing all locally allocated blocks
+      { return { iBlocks_.begin(), iBlocks_.end(), requiredSelectors, incompatibleSelectors }; }
+   const_iterator   end() const { return { iBlocks_.end(), iBlocks_.end() }; } ///< iterator for traversing all locally allocated blocks
 
    uint_t getNumberOfBlocks() const { return iBlocks_.size(); } ///< number of locally allocated blocks
    uint_t size()              const { return iBlocks_.size(); } ///< number of locally allocated blocks
@@ -207,11 +208,11 @@ public:
 
    /// inserts all locally allocated blocks into vector 'blocks'
    void getBlocks( std::vector< const IBlock* >& blocks ) const
-   { for (auto blkIt = iBlocks_.begin(); blkIt != iBlocks_.end(); ++blkIt ) { blocks.push_back(blkIt->second); } }
+   { for (auto iBlock : iBlocks_) { blocks.push_back(iBlock.second); } }
 
    /// inserts all locally allocated blocks into vector 'blocks'
    void getBlocks( std::vector<       IBlock* >& blocks )
-   { for (auto blkIt = iBlocks_.begin(); blkIt != iBlocks_.end(); ++blkIt ) { blocks.push_back(blkIt->second); } }
+   { for (auto & iBlock : iBlocks_) { blocks.push_back(iBlock.second); } }
 
    //*******************************************************************************************************************
    /*!
@@ -465,7 +466,7 @@ public:
    ///
    /// Usage: BlockDataID id = blockStorage.addBlockData( "[optional block data identifier]" ) << BlockDataCreator( ... )
    ///                                                                                         << BlockDataCreator( ... ) << ... ;
-   internal::BlockDataHandlingAdder addBlockData( const std::string & identifier = std::string() ) { return internal::BlockDataHandlingAdder( *this, identifier ); }
+   internal::BlockDataHandlingAdder addBlockData( const std::string & identifier = std::string() ) { return { *this, identifier }; }
 
    template< typename T >
    inline BlockDataID addBlockData( const shared_ptr< T > & dataHandling,
@@ -520,14 +521,12 @@ protected:
 
 
    AABB domain_;      ///< axis-aligned bounding box for the entire simulation space/domain
-   bool periodic_[3]; ///< periodicity flags
+   std::array< bool, 3 > periodic_; ///< periodicity flags
    
    std::vector< internal::BlockDataItem > blockDataItem_;
 
 private:
 
-   BlockStorage(); ///< Must not be made public or protected! Derived classes must call one of the available public/protected constructors.
-
    inline void registerBlock( const std::pair<IBlockID::IDType, IBlock*>& block ); // All three functions must not be made public!
    inline void removeBlock  ( const IBlock* block );                               // All three functions are intended for internal use only.
    inline void removeBlock  ( const IBlockID::IDType& blockID );                   // All three functions are intended for internal use only.
@@ -736,9 +735,10 @@ inline void BlockStorage::clearBlockData( const BlockDataID & id )
 inline std::vector< std::string > BlockStorage::getBlockDataIdentifiers() const
 {
    std::vector< std::string > identifiers;
+   identifiers.reserve(blockDataItem_.size());
 
-   for( auto it = blockDataItem_.begin(); it != blockDataItem_.end(); ++it )
-      identifiers.push_back( it->getIdentifier() );
+   for(const auto & it : blockDataItem_)
+      identifiers.push_back( it.getIdentifier() );
 
    return identifiers;
 }
@@ -747,7 +747,7 @@ inline std::vector< std::string > BlockStorage::getBlockDataIdentifiers() const
 
 inline const std::string & BlockStorage::getBlockDataIdentifier( const ConstBlockDataID & id ) const
 {
-   static std::string noData( "[no block data]" );
+   static const std::string noData( "[no block data]" );
 
    if( !(id < blockDataItem_.size()) )
       return noData;
diff --git a/src/domain_decomposition/IBlock.h b/src/domain_decomposition/IBlock.h
index a1641d5a5ac2d2297514fc9da429fe2faee7e5b2..e84c8f697729cb7278e8cc56ffb39bbef2083895 100644
--- a/src/domain_decomposition/IBlock.h
+++ b/src/domain_decomposition/IBlock.h
@@ -208,6 +208,7 @@ class StructuredBlockStorage; // forward declaration
 class IBlock : private NonCopyable
 {
 public:
+   IBlock() = delete;
 
    using BlockData = internal::BlockData;
 
@@ -274,8 +275,6 @@ protected:
 
 private:
 
-   IBlock(); ///< Must not be made public or protected! Derived classes must call one of the available public/protected constructors.
-
    /// helper function for assigning data to this block (called by 'BlockStorage'), must not be made public or protected!
    inline void addData( const BlockDataID & index, BlockData* const data );
 
diff --git a/src/domain_decomposition/StructuredBlockStorage.h b/src/domain_decomposition/StructuredBlockStorage.h
index 146a5eadb5186fb283652c834d4579ca91482e73..62549621589664943f0906868f4ab6949dee6371 100644
--- a/src/domain_decomposition/StructuredBlockStorage.h
+++ b/src/domain_decomposition/StructuredBlockStorage.h
@@ -101,6 +101,8 @@ class StructuredBlockStorage : private NonCopyable {
 
 public:
 
+   StructuredBlockStorage() = delete;
+
    /// helper class for adding multiple block data initialization functions
    class StructuredBlockDataAdder {
    public:
@@ -412,7 +414,7 @@ public:
    /// Usage: BlockDataID id = blockStorage.addBlockData( "[optional block data identifier]" ) << StructuredBlockDataCreator( ... )
    ///                                                                                         << BlockDataCreator( ... ) << ... ;
    StructuredBlockDataAdder addStructuredBlockData( const std::string& identifier = std::string() )
-                                                                               { return StructuredBlockDataAdder( *this, identifier ); }
+                                                                               { return { *this, identifier }; }
 
    template< typename T >
    inline BlockDataID addStructuredBlockData( std::function< T* ( IBlock* const block, StructuredBlockStorage* const storage ) > function,
@@ -447,11 +449,6 @@ protected:
    virtual inline BlockDataID addCellBoundingBoxesAsBlockData( const std::string & identifier );
 
 private:
-
-   StructuredBlockStorage(); ///< Must not be made public or protected! Derived classes must call one of the available public/protected constructors.
-
-
-
    shared_ptr<BlockStorage> blockStorage_; ///< reference to an encapsulated object of type class BlockStorage (the object itself must be stored as a member in the derived class)
 
    uint_t levels_; ///< number of different grid levels managed by this block storage (every grid level has its own cell size dx/dy/dz)
diff --git a/src/domain_decomposition/StructuredBlockStorageCellMapping.h b/src/domain_decomposition/StructuredBlockStorageCellMapping.h
index e54aa32089c6669dcffddaab5828c98d2bd96eab..275892a654c9e70ec11287c7b7c76afed6e7b43c 100644
--- a/src/domain_decomposition/StructuredBlockStorageCellMapping.h
+++ b/src/domain_decomposition/StructuredBlockStorageCellMapping.h
@@ -56,8 +56,7 @@ inline void transformGlobalToBlockLocal( CellVector& local, const StructuredBloc
 
    WALBERLA_ASSERT_EQUAL( &( blockStorage.getBlockStorage() ), &( block.getBlockStorage() ) );
 
-   for( CellVector::const_iterator it = global.begin(); it != global.end(); ++it ) {
-      Cell cell = *it;
+   for(auto cell : global) {
       blockStorage.transformGlobalToBlockLocalCell( cell, block );
       local.push_back( cell );
    }
@@ -71,8 +70,8 @@ inline void transformGlobalToBlockLocal( CellVector& cells, const StructuredBloc
 
    WALBERLA_ASSERT_EQUAL( &( blockStorage.getBlockStorage() ), &( block.getBlockStorage() ) );
 
-   for( CellVector::iterator cell = cells.begin(); cell != cells.end(); ++cell )
-      blockStorage.transformGlobalToBlockLocalCell( *cell, block );
+   for(auto & cell : cells)
+      blockStorage.transformGlobalToBlockLocalCell( cell, block );
 }
 
 
@@ -83,8 +82,7 @@ inline void transformBlockLocalToGlobal( CellVector& global, const StructuredBlo
 
    WALBERLA_ASSERT_EQUAL( &( blockStorage.getBlockStorage() ), &( block.getBlockStorage() ) );
 
-   for( CellVector::const_iterator it = local.begin(); it != local.end(); ++it ) {
-      Cell cell = *it;
+   for(auto cell : local) {
       blockStorage.transformBlockLocalToGlobalCell( cell, block );
       global.push_back( cell );
    }
@@ -98,8 +96,8 @@ inline void transformBlockLocalToGlobal( CellVector& cells, const StructuredBloc
 
    WALBERLA_ASSERT_EQUAL( &( blockStorage.getBlockStorage() ), &( block.getBlockStorage() ) );
 
-   for( CellVector::iterator cell = cells.begin(); cell != cells.end(); ++cell )
-      blockStorage.transformBlockLocalToGlobalCell( *cell, block );
+   for(auto & cell : cells)
+      blockStorage.transformBlockLocalToGlobalCell( cell, block );
 }
 
 
@@ -110,8 +108,7 @@ inline void transformGlobalToBlockLocal( CellSet& local, const StructuredBlockSt
 
    WALBERLA_ASSERT_EQUAL( &( blockStorage.getBlockStorage() ), &( block.getBlockStorage() ) );
 
-   for( CellSet::const_iterator it = global.begin(); it != global.end(); ++it ) {
-      Cell cell = *it;
+   for(auto cell : global) {
       blockStorage.transformGlobalToBlockLocalCell( cell, block );
       local.insert( cell );
    }
@@ -127,8 +124,7 @@ inline void transformGlobalToBlockLocal( CellSet& cells, const StructuredBlockSt
 
    CellSet localCells;
 
-   for( CellSet::const_iterator it = cells.begin(); it != cells.end(); ++it ) {
-      Cell cell = *it;
+   for(auto cell : cells) {
       blockStorage.transformGlobalToBlockLocalCell( cell, block );
       localCells.insert( localCells.end(), cell );
    }
@@ -144,8 +140,7 @@ inline void transformBlockLocalToGlobal( CellSet& global, const StructuredBlockS
 
    WALBERLA_ASSERT_EQUAL( &( blockStorage.getBlockStorage() ), &( block.getBlockStorage() ) );
 
-   for( CellSet::const_iterator it = local.begin(); it != local.end(); ++it ) {
-      Cell cell = *it;
+   for(auto cell : local) {
       blockStorage.transformBlockLocalToGlobalCell( cell, block );
       global.insert( cell );
    }
@@ -161,8 +156,7 @@ inline void transformBlockLocalToGlobal( CellSet& cells, const StructuredBlockSt
 
    CellSet globalCells;
 
-   for( CellSet::const_iterator it = cells.begin(); it != cells.end(); ++it ) {
-      Cell cell = *it;
+   for(auto cell : cells) {
       blockStorage.transformBlockLocalToGlobalCell( cell, block );
       globalCells.insert( globalCells.end(), cell );
    }
diff --git a/src/field/AccuracyEvaluation.h b/src/field/AccuracyEvaluation.h
index 77fd10c4d3d649789ba29fc1b43fb23b332c4b13..4f61f5b1543465d6686fa4f38f53c31b8af4670e 100644
--- a/src/field/AccuracyEvaluation.h
+++ b/src/field/AccuracyEvaluation.h
@@ -161,7 +161,7 @@ public:
       L1_( real_t(0) ), L2_( real_t(0) ), Lmax_( real_t(0) ),
       requiredSelectors_(requiredSelectors), incompatibleSelectors_( incompatibleSelectors )
    {
-      static_assert( (std::is_same< Filter_T, DefaultEvaluationFilter >::value),
+      static_assert( (std::is_same_v< Filter_T, DefaultEvaluationFilter >),
                      "This constructor is only available if DefaultEvaluationFilter is set as filter type!" );
    }
 
@@ -257,8 +257,8 @@ void AccuracyEvaluation< Field_T, SolutionFunction_T, Filter_T >::operator()()
          )
       }
 
-      for( auto v = lmax.begin(); v != lmax.end(); ++v )
-         _Lmax = std::max( _Lmax, *v );
+      for(const real_t v : lmax)
+         _Lmax = std::max( _Lmax, v );
 
 #else
 
@@ -376,7 +376,7 @@ inline void accuracyEvaluationConfigParser( const Config::BlockHandle & parentBl
 {
    if( parentBlockHandle )
    {
-      Config::BlockHandle block = parentBlockHandle.getBlock( configBlockName );
+      Config::BlockHandle const block = parentBlockHandle.getBlock( configBlockName );
       if( block )
       {
          defaultPlotFrequency = block.getParameter< uint_t >( "plotFrequency", defaultPlotFrequency );
diff --git a/src/field/AccuracyEvaluationLinePlot.h b/src/field/AccuracyEvaluationLinePlot.h
index a0c2218609ee7a1d4f3be1ed969e0f01923ca95d..3889d2435afcf10bdf88f3fa9402d1cb30c6b2bf 100644
--- a/src/field/AccuracyEvaluationLinePlot.h
+++ b/src/field/AccuracyEvaluationLinePlot.h
@@ -93,19 +93,19 @@ inline void accuracyEvaluationLinePlotIO( std::ofstream & file, const std::vecto
 {
    file << "# position [1] [2] [3], simulation [4] [5] [6], exact solution [7] [8] [9], "
            "|| u - u_exact || / || u_exact || (rel. error) [10], || u - u_exact || (abs. error) [11]\n";
-   for( auto point = points.begin(); point != points.end(); ++point )
+   for(const auto & point : points)
    {
-      Vector3< real_t > diff = point->value - point->solution;
-      file << point->center[0] << " "
-           << point->center[1] << " "
-           << point->center[2] << " "
-           << point->value[0] << " "
-           << point->value[1] << " "
-           << point->value[2] << " "
-           << point->solution[0] << " "
-           << point->solution[1] << " "
-           << point->solution[2] << " "
-           << ( diff.length() / point->solution.length() ) << " "
+      Vector3< real_t > const diff = point.value - point.solution;
+      file << point.center[0] << " "
+           << point.center[1] << " "
+           << point.center[2] << " "
+           << point.value[0] << " "
+           << point.value[1] << " "
+           << point.value[2] << " "
+           << point.solution[0] << " "
+           << point.solution[1] << " "
+           << point.solution[2] << " "
+           << ( diff.length() / point.solution.length() ) << " "
            << diff.length() << "\n";
    }
 }
@@ -218,7 +218,7 @@ public:
       relLinePoint_( Vector3<real_t>( real_c(0.5) ) ), normalizationFactor_( real_t(1) ),
       requiredSelectors_(requiredSelectors), incompatibleSelectors_( incompatibleSelectors )
    {
-      static_assert( (std::is_same< Filter_T, DefaultEvaluationFilter >::value),
+      static_assert( (std::is_same_v< Filter_T, DefaultEvaluationFilter >),
                      "This constructor is only available if DefaultEvaluationFilter is set as filter type!" );
 
       auto _blocks = blocks_.lock();
@@ -444,7 +444,7 @@ inline void accuracyEvaluationLinePlotConfigParser( const Config::BlockHandle &
 {
    if( parentBlockHandle )
    {
-      Config::BlockHandle block = parentBlockHandle.getBlock( configBlockName );
+      Config::BlockHandle const block = parentBlockHandle.getBlock( configBlockName );
       if( block )
       {
          defaultYAxis = block.getParameter< bool >( "y", defaultYAxis );
@@ -657,7 +657,7 @@ inline void accuracyEvaluationLinePlotterConfigParser( const Config::BlockHandle
 {
    if( parentBlockHandle )
    {
-      Config::BlockHandle block = parentBlockHandle.getBlock( configBlockName );
+      Config::BlockHandle const block = parentBlockHandle.getBlock( configBlockName );
       if( block )
       {
          defaultEvaluationFrequency = block.getParameter< uint_t >( "frequency", defaultEvaluationFrequency );
diff --git a/src/field/AddToStorage.h b/src/field/AddToStorage.h
index 66db81a406a55649984f079b36c37e33c2a0ef7d..fbbd56a5db1a45860a78e57b59e1c3ed45f627c6 100644
--- a/src/field/AddToStorage.h
+++ b/src/field/AddToStorage.h
@@ -118,8 +118,8 @@ struct AddToStorage
 
 template< typename GhostLayerField_T, typename BlockStorage_T >
 struct AddToStorage< GhostLayerField_T, BlockStorage_T,
-                     typename std::enable_if< ( std::is_integral< typename GhostLayerField_T::value_type >::value || std::is_floating_point< typename GhostLayerField_T::value_type >::value ) &&
-	                                            ! std::is_same< GhostLayerField_T, FlagField< typename GhostLayerField_T::value_type > >::value >::type >
+                     std::enable_if_t< ( std::is_integral_v< typename GhostLayerField_T::value_type > || std::is_floating_point_v< typename GhostLayerField_T::value_type > ) &&
+	                                            ! std::is_same_v< GhostLayerField_T, FlagField< typename GhostLayerField_T::value_type > > > >
 {
    using Value_T = typename GhostLayerField_T::value_type;
    static BlockDataID add( const shared_ptr< BlockStorage_T > & blocks, const std::string & identifier,
@@ -332,9 +332,9 @@ struct Creator : public domain_decomposition::BlockDataCreator< GhostLayerField_
    Creator( const std::string & identifier = std::string(),
             const Set<SUID> & requiredSelectors = Set<SUID>::emptySet(),
             const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet(),
-            const typename GhostLayerField_T::value_type & initValue = typename GhostLayerField_T::value_type(),
-            const Layout layout = fzyx,
-            const uint_t nrOfGhostLayers = uint_t(1) ) :
+            const typename GhostLayerField_T::value_type &  /*initValue*/ = typename GhostLayerField_T::value_type(),
+            const Layout  /*layout*/ = fzyx,
+            const uint_t  /*nrOfGhostLayers*/ = uint_t(1) ) :
       domain_decomposition::BlockDataCreator< GhostLayerField_T >( shared_ptr< DefaultBlockDataHandling< GhostLayerField_T > >(),
                                                                    identifier, requiredSelectors, incompatibleSelectors )
    {
@@ -345,8 +345,8 @@ struct Creator : public domain_decomposition::BlockDataCreator< GhostLayerField_
 
 template< typename GhostLayerField_T >
 struct Creator< GhostLayerField_T,
-                typename std::enable_if< std::is_integral< typename GhostLayerField_T::value_type >::value ||
-                                         std::is_floating_point< typename GhostLayerField_T::value_type >::value  >::type >
+                std::enable_if_t< std::is_integral_v< typename GhostLayerField_T::value_type > ||
+                                         std::is_floating_point_v< typename GhostLayerField_T::value_type > > >
    : public domain_decomposition::BlockDataCreator< GhostLayerField_T >
 {
    Creator( const shared_ptr< StructuredBlockStorage > & blocks,
@@ -379,9 +379,9 @@ struct Creator< GhostLayerField_T,
    Creator( const std::string & identifier = std::string(),
             const Set<SUID> & requiredSelectors = Set<SUID>::emptySet(),
             const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet(),
-            const typename GhostLayerField_T::value_type & initValue = typename GhostLayerField_T::value_type(),
-            const Layout layout = fzyx,
-            const uint_t nrOfGhostLayers = uint_t(1) ) :
+            const typename GhostLayerField_T::value_type &  /*initValue*/ = typename GhostLayerField_T::value_type(),
+            const Layout  /*layout*/ = fzyx,
+            const uint_t  /*nrOfGhostLayers*/ = uint_t(1) ) :
       domain_decomposition::BlockDataCreator< GhostLayerField_T >( shared_ptr< DefaultBlockDataHandling< GhostLayerField_T > >(),
                                                                    identifier, requiredSelectors, incompatibleSelectors )
    {
@@ -424,7 +424,7 @@ struct Creator< FlagField<T> > : public domain_decomposition::BlockDataCreator<
    Creator( const std::string & identifier = std::string(),
             const Set<SUID> & requiredSelectors = Set<SUID>::emptySet(),
             const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet(),
-            const uint_t nrOfGhostLayers = uint_t(1) ) :
+            const uint_t  /*nrOfGhostLayers*/ = uint_t(1) ) :
       domain_decomposition::BlockDataCreator< FlagField<T> >( shared_ptr< DefaultBlockDataHandling< FlagField<T> > >(),
                                                               identifier, requiredSelectors, incompatibleSelectors )
    {
diff --git a/src/field/CellCounter.h b/src/field/CellCounter.h
index dd549ab508db9f95f0b01721a58f279c7b5b6971..8220ab47b651cdcaa79a5a0455734c3bd63d3ac1 100644
--- a/src/field/CellCounter.h
+++ b/src/field/CellCounter.h
@@ -70,7 +70,7 @@ public:
                 const Set<SUID> & requiredSelectors     = Set<SUID>::emptySet(),
                 const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() ) :
       totalNumberOfCells_( uint64_t(0) ), totalNumberOfBlocksContainingCell_( uint64_t(0) ),
-      blocks_( blocks ), allFlagsMustBeSet_( false ), cellsToCount_( cellsToCount ), flagFieldId_( flagFieldId ),
+      blocks_( blocks ), cellsToCount_( cellsToCount ), flagFieldId_( flagFieldId ),
       requiredSelectors_( requiredSelectors ), incompatibleSelectors_( incompatibleSelectors )
    {}
 
@@ -140,7 +140,7 @@ private:
 
    weak_ptr< StructuredBlockStorage > blocks_;
 
-   bool allFlagsMustBeSet_;
+   bool allFlagsMustBeSet_ = false;
    const Set< FlagUID >   cellsToCount_;
    const ConstBlockDataID flagFieldId_;
 
@@ -198,8 +198,8 @@ void CellCounter< FlagField_T >::operator()()
          else
          {
             typename FlagField_T::flag_t mask = 0;
-            for( auto flag = cellsToCount_.begin(); flag != cellsToCount_.end(); ++flag )
-               mask = static_cast< typename FlagField_T::flag_t >( mask | flagField->getFlag( *flag ) );
+            for(const auto & flag : cellsToCount_)
+               mask = static_cast< typename FlagField_T::flag_t >( mask | flagField->getFlag( flag ) );
 
             bool blockHasCell = false;
             if( allFlagsMustBeSet_ )
diff --git a/src/field/Field.h b/src/field/Field.h
index 30fe15586846f09c540f12cf309c36eb05135e05..3e76b5f2b5f1b0633806127fb46df9f14a2d82a2 100644
--- a/src/field/Field.h
+++ b/src/field/Field.h
@@ -86,7 +86,7 @@ namespace field {
       using Ptr = FieldPointer<Field<T, fSize_>, Field<T, fSize_>, T>;
       using ConstPtr = FieldPointer<Field<T, fSize_>, const Field<T, fSize_>, const T>;
 
-      using FlattenedField = typename std::conditional<VectorTrait<T>::F_SIZE != 0, Field<typename VectorTrait<T>::OutputType, VectorTrait<T>::F_SIZE * fSize_>, Field<T, fSize_>>::type;
+      using FlattenedField = std::conditional_t<VectorTrait<T>::F_SIZE != 0, Field<typename VectorTrait<T>::OutputType, VectorTrait<T>::F_SIZE * fSize_>, Field<T, fSize_>>;
 
       static const uint_t F_SIZE = fSize_;
       //@}
@@ -125,6 +125,14 @@ namespace field {
       //@}
       //****************************************************************************************************************
 
+      //**Operators************************************************************************************
+      /*! \name Operators */
+      //@{
+
+      Field & operator=( const Field & ) = delete;
+
+      //@}
+      //****************************************************************************************************************
 
       //** Element Access **********************************************************************************************
       /*! \name Element Access */
@@ -349,8 +357,6 @@ namespace field {
 
    private:
 
-      Field & operator=( const Field & );
-
       T * values_;           //!< Linearized, 1-dimensional representation of the 4D data grid.
       T * valuesWithOffset_; //!< set by setOffsets(), to allow derived classes to change the offset
 
diff --git a/src/field/Field.impl.h b/src/field/Field.impl.h
index 3eb80bd583192b5ffb5ea9e7d6f5a3c7450b720c..c77743c8a3eac7379c4e084f63a64ea8f3e8a1b9 100644
--- a/src/field/Field.impl.h
+++ b/src/field/Field.impl.h
@@ -286,7 +286,7 @@ namespace field {
    {
       WALBERLA_CHECK_EQUAL(layout_, Layout::zyxf)
       static_assert(fSize_ % fSize2 == 0, "number of field components do not match");
-      static_assert(std::is_same<typename Field<T2,fSize2>::FlattenedField, Field<T,fSize_>>::value, "field types are incompatible for flattening");
+      static_assert(std::is_same_v<typename Field<T2,fSize2>::FlattenedField, Field<T,fSize_>>, "field types are incompatible for flattening");
       allocator_->incrementReferenceCount ( values_ );
    }
 
diff --git a/src/field/FileIO.impl.h b/src/field/FileIO.impl.h
index eae64c6b39b1281c9f2d0c01b5c27e2770d18ffe..8f4b3dc3cd3f877c3a168e95f827eda578e15c03 100644
--- a/src/field/FileIO.impl.h
+++ b/src/field/FileIO.impl.h
@@ -342,9 +342,9 @@ void FieldWriter< FieldT >::writeToFileNonMPI(const std::vector< const IBlock* >
 {
    std::ofstream ofs(filename_.c_str(), std::ofstream::out | std::ofstream::binary);
 
-   for (auto block = blocks.begin(); block != blocks.end(); ++block)
+   for (auto block : blocks)
    {
-      const FieldT* field = (*block)->template getData< FieldT >(fieldID_);
+      const FieldT* field = block->template getData< FieldT >(fieldID_);
 
       for (auto fieldIt = field->begin(); fieldIt != field->end(); ++fieldIt)
       {
@@ -360,9 +360,9 @@ void FieldWriter< FieldT >::readFromFileNonMPI(const std::vector< IBlock* >& blo
 {
    std::ifstream ifs(filename_.c_str(), std::ifstream::in | std::ifstream::binary);
 
-   for (auto block = blocks.begin(); block != blocks.end(); ++block)
+   for (auto block : blocks)
    {
-      FieldT* field = (*block)->template getData< FieldT >(fieldID_);
+      FieldT* field = block->template getData< FieldT >(fieldID_);
 
       for (auto fieldIt = field->begin(); fieldIt != field->end(); ++fieldIt)
       {
@@ -379,9 +379,9 @@ std::vector< uint_t > FieldWriter< FieldT >::computeBlockOffsets(const std::vect
    std::vector< uint_t > blockOffsets;
    blockOffsets.push_back(0);
 
-   for (auto block = blocks.begin(); block != blocks.end(); ++block)
+   for (auto block : blocks)
    {
-      const FieldT* field = (*block)->template getData< FieldT >(fieldID_);
+      const FieldT* field = block->template getData< FieldT >(fieldID_);
       const uint_t offset = blockOffsets.back() + field->xSize() * field->ySize() * field->zSize() * field->fSize();
       blockOffsets.push_back(offset);
    }
@@ -395,9 +395,9 @@ std::vector< uint_t > FieldWriter< FieldT >::computeBlockOffsets(const std::vect
    std::vector< uint_t > blockOffsets;
    blockOffsets.push_back(0);
 
-   for (auto block = blocks.begin(); block != blocks.end(); ++block)
+   for (auto block : blocks)
    {
-      const FieldT* field = (*block)->template getData< FieldT >(fieldID_);
+      const FieldT* field = block->template getData< FieldT >(fieldID_);
       const uint_t offset = blockOffsets.back() + field->xSize() * field->ySize() * field->zSize() * field->fSize();
       blockOffsets.push_back(offset);
    }
diff --git a/src/field/FlagField.h b/src/field/FlagField.h
index a2333770d5b1ae3b9b901b8248f572a41cb63520..9a9e1ee9a8ae3b1da3fe6c8386a6bced658b7964 100644
--- a/src/field/FlagField.h
+++ b/src/field/FlagField.h
@@ -203,7 +203,7 @@ protected:
    // All Members are hold inside an extra struct, to enable shallow copies of the field
    struct RegistrationData
    {
-      RegistrationData() : usedMask(0), nextFreeBit(0) {}
+      RegistrationData() : usedMask(0) {}
       RegistrationData( const RegistrationData & o )
          : flagToUID  ( o.flagToUID   ),
            uidToFlag  ( o.uidToFlag   ),
@@ -224,16 +224,16 @@ protected:
       /// BitNumbers smaller than nextFreeBit are guaranteed to be
       /// occupied. Bits greater or equal may be occupied, when registerFlac(name,bitNr)
       /// was called.
-      uint_t nextFreeBit;
+      uint_t nextFreeBit = uint_c(0);
    };
    RegistrationData * data_;
 
 
 
-   static_assert( (std::is_same<T,uint8_t >::value ||
-                   std::is_same<T,uint16_t>::value ||
-                   std::is_same<T,uint32_t>::value ||
-                   std::is_same<T,uint64_t>::value),
+   static_assert( (std::is_same_v<T,uint8_t > ||
+                   std::is_same_v<T,uint16_t> ||
+                   std::is_same_v<T,uint32_t> ||
+                   std::is_same_v<T,uint64_t>),
                   "Only unsigned types of various lengths are allowed as type of FlagFields");
 
 
@@ -252,7 +252,7 @@ protected:
    friend bool isFlagInNeighborhood( const FieldPtrOrIterator & i, typename FieldPtrOrIterator::value_t mask);
 
    template <class Stencil, typename FieldPtrOrIterator>
-   friend typename std::remove_const<typename FieldPtrOrIterator::value_type>::type
+   friend std::remove_const_t<typename FieldPtrOrIterator::value_type>
       getOredNeighborhood(const FieldPtrOrIterator & i);
 
    //@}
diff --git a/src/field/FlagField.impl.h b/src/field/FlagField.impl.h
index b765323a9d89c430fc226e78e556d5dfdad68668..15ec3e5b0da25f46fd47aa6fab98d6ff3673a78e 100644
--- a/src/field/FlagField.impl.h
+++ b/src/field/FlagField.impl.h
@@ -78,7 +78,7 @@ namespace field {
    template<typename T>
    FlagField<T>::~FlagField()
    {
-      uint_t refs = Field<T,1>::referenceCount();
+      uint_t const refs = Field<T,1>::referenceCount();
       if( refs == 1 ) // last field that uses this data
          delete data_;
    }
@@ -490,12 +490,12 @@ namespace field {
     template<class Sten, typename FieldPtrOrIterator>
     inline bool isFlagInNeighborhood(const FieldPtrOrIterator & i, typename FieldPtrOrIterator::value_type mask)
     {
-       using T = typename std::remove_const<typename FieldPtrOrIterator::value_type>::type;
+       using T = std::remove_const_t<typename FieldPtrOrIterator::value_type>;
 
-       static_assert( (std::is_same< T,uint8_t >::value ||
-                       std::is_same< T,uint16_t>::value ||
-                       std::is_same< T,uint32_t>::value ||
-                       std::is_same< T,uint64_t>::value),
+       static_assert( (std::is_same_v< T,uint8_t > ||
+                       std::is_same_v< T,uint16_t> ||
+                       std::is_same_v< T,uint32_t> ||
+                       std::is_same_v< T,uint64_t>),
                       "Only unsigned types of various lengths are allowed as type of FlagFields");
 
        T flag = 0;
@@ -511,10 +511,10 @@ namespace field {
      * \param[in] i     field pointer.
      ******************************************************************************************************************/
     template<class Sten, typename FieldPtrOrIterator>
-    inline typename std::remove_const<typename FieldPtrOrIterator::value_type>::type
+    inline std::remove_const_t<typename FieldPtrOrIterator::value_type>
        getOredNeighborhood(const FieldPtrOrIterator & i)
     {
-       using RetType = typename std::remove_const<typename FieldPtrOrIterator::value_type>::type;
+       using RetType = std::remove_const_t<typename FieldPtrOrIterator::value_type>;
 
        RetType flag = 0;
        for( auto d = Sten::beginNoCenter(); d != Sten::end(); ++d ) {
diff --git a/src/field/Gather.h b/src/field/Gather.h
index 58e23ff67dbfe342b74ad9c74135ecefeabcc73c..9e69df55df14afdb95ea58acd4e54e0b23c5a6e7 100644
--- a/src/field/Gather.h
+++ b/src/field/Gather.h
@@ -63,7 +63,7 @@ namespace field {
       mpi::SendBuffer sendBuffer;
       for( auto blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt )
       {
-         IBlock & block = *blockIt;
+         IBlock const & block = *blockIt;
          auto field = blockIt->template getData<Field_T>( fieldID );
 
          // intersection between block cell bounding box and the interval to collect - in global coordinates
diff --git a/src/field/GhostLayerField.h b/src/field/GhostLayerField.h
index 345d497cdc4c04a789d46d391b909f3fb0322aa5..0c893573d1a0185be57afc2f60b0f9fb993a824b 100644
--- a/src/field/GhostLayerField.h
+++ b/src/field/GhostLayerField.h
@@ -67,7 +67,7 @@ namespace field {
       using Ptr = typename Field<T, fSize_>::Ptr;
       using ConstPtr = typename Field<T, fSize_>::ConstPtr;
 
-      using FlattenedField = typename std::conditional<VectorTrait<T>::F_SIZE != 0, GhostLayerField<typename VectorTrait<T>::OutputType, VectorTrait<T>::F_SIZE * fSize_>, GhostLayerField<T, fSize_>>::type;
+      using FlattenedField = std::conditional_t<VectorTrait<T>::F_SIZE != 0, GhostLayerField<typename VectorTrait<T>::OutputType, VectorTrait<T>::F_SIZE * fSize_>, GhostLayerField<T, fSize_>>;
       //@}
       //****************************************************************************************************************
 
diff --git a/src/field/GhostLayerField.impl.h b/src/field/GhostLayerField.impl.h
index 1a8b758ca7a9f717ed0786c4edbb7ed24195a410..bd7c2f9dc27247b365fd4bff422e1da6eca94798 100644
--- a/src/field/GhostLayerField.impl.h
+++ b/src/field/GhostLayerField.impl.h
@@ -129,7 +129,7 @@ namespace field {
     {
        gl_ = gl;
        timestepCounter_ = uint8_c(0);
-       uint_t innerGhostLayerSize = ( l == fzyx ) ? gl : uint_t(0);
+       uint_t const innerGhostLayerSize = ( l == fzyx ) ? gl : uint_t(0);
        Field<T,fSize_>::init( _xSize + 2*gl ,
                               _ySize + 2*gl,
                               _zSize + 2*gl, l, alloc,
diff --git a/src/field/GhostRegions.h b/src/field/GhostRegions.h
index 7745968acb073ebca98d8cf107212ad2692cadfb..f683cbe86bf3a605c80f0c254e2ebba290d8c510 100644
--- a/src/field/GhostRegions.h
+++ b/src/field/GhostRegions.h
@@ -46,7 +46,7 @@ template< typename GhostLayerField_T>
 CellInterval getGhostRegion( const GhostLayerField_T & f, stencil::Direction d,
                              cell_idx_t thickness, bool fullSlice )
 {
-   const cell_idx_t sizeArr [] = { cell_idx_c( f.xSize() ),
+   const std::array<cell_idx_t, 3> sizeArr = { cell_idx_c( f.xSize() ),
                                    cell_idx_c( f.ySize() ),
                                    cell_idx_c( f.zSize() )};
 
@@ -89,7 +89,7 @@ CellInterval getSliceBeforeGhostLayer(const GhostLayerField_T & f, stencil::Dire
 {
    WALBERLA_ASSERT_GREATER( thickness, 0 );
 
-   const cell_idx_t sizeArr [] = { cell_idx_c( f.xSize() ),
+   const std::array<cell_idx_t, 3> sizeArr = { cell_idx_c( f.xSize() ),
                                    cell_idx_c( f.ySize() ),
                                    cell_idx_c( f.zSize() )};
 
diff --git a/src/field/MassEvaluation.h b/src/field/MassEvaluation.h
index 0b9ec26a42962a5d34019ec850539bac9ed88eaf..70608005699937d5c47d377646ada0784d143eac 100644
--- a/src/field/MassEvaluation.h
+++ b/src/field/MassEvaluation.h
@@ -156,7 +156,7 @@ public:
       initialMass_( real_t(0) ), minMass_( real_t(0) ), maxMass_( real_t(0) ),
       requiredSelectors_(requiredSelectors), incompatibleSelectors_( incompatibleSelectors )
    {
-      static_assert( (std::is_same< Filter_T, DefaultEvaluationFilter >::value),
+      static_assert( (std::is_same_v< Filter_T, DefaultEvaluationFilter >),
                      "This constructor is only available if DefaultEvaluationFilter is set as filter type!" );
 
       auto _blocks = blocks.lock();
@@ -341,7 +341,7 @@ inline void massEvaluationConfigParser( const Config::BlockHandle & parentBlockH
 {
    if( parentBlockHandle )
    {
-      Config::BlockHandle block = parentBlockHandle.getBlock( configBlockName );
+      Config::BlockHandle const block = parentBlockHandle.getBlock( configBlockName );
       if( block )
       {
          defaultPlotFrequency = block.getParameter< uint_t >( "plotFrequency", defaultPlotFrequency );
diff --git a/src/field/Printers.impl.h b/src/field/Printers.impl.h
index dd36a8097dbc527375d4c38ab85a46f9d10c0970..7768825237bd38ab83bd8627380708f257dfad58 100644
--- a/src/field/Printers.impl.h
+++ b/src/field/Printers.impl.h
@@ -44,10 +44,10 @@ namespace field {
       CellInterval size = field.xyzSize();
 
       Cell coord = size.min();
-      const char * coordNames [3] = { "x", "y", "z" };
+      std::array<const char *, 3> coordNames = { "x", "y", "z" };
 
-      int innerCoord = (sliceCoord + 1) % 3;
-      int outerCoord = (sliceCoord + 2) % 3;
+      uint_t const innerCoord = static_cast< uint_t >((sliceCoord + 1) % 3);
+      uint_t const outerCoord = static_cast< uint_t >((sliceCoord + 2) % 3);
 
       size.min()[uint_c(sliceCoord)] = sliceValue;
       size.max()[uint_c(sliceCoord)] = sliceValue;
@@ -99,10 +99,10 @@ namespace field {
       WALBERLA_ASSERT(sliceCoord >=0 && sliceCoord <3 );
       cell_idx_t glCellIdx = cell_idx_c ( field.nrOfGhostLayers() );
 
-      const char * coordNames [3] = { "x", "y", "z" };
+      std::array<const char *, 3> coordNames = { "x", "y", "z" };
 
-      int innerCoord = (sliceCoord + 1) % 3;
-      int outerCoord = (sliceCoord + 2) % 3;
+      uint_t const innerCoord = static_cast< uint_t >((sliceCoord + 1) % 3);
+      uint_t const outerCoord = static_cast< uint_t >((sliceCoord + 2) % 3);
 
       CellInterval sliceInterval = field.xyzSize();
 
@@ -171,10 +171,10 @@ namespace field {
       WALBERLA_ASSERT(sliceCoord >=0 && sliceCoord <3 );
       cell_idx_t glCellIdx = cell_idx_c ( field.nrOfGhostLayers() );
 
-      const char * coordNames [3] = { "x", "y", "z" };
+      std::array<const char *, 3> coordNames = { "x", "y", "z" };
 
-      int innerCoord = (sliceCoord + 1) % 3;
-      int outerCoord = (sliceCoord + 2) % 3;
+      uint_t const innerCoord = static_cast< uint_t >((sliceCoord + 1) % 3);
+      uint_t const outerCoord = static_cast< uint_t >((sliceCoord + 2) % 3);
 
       CellInterval sliceInterval = field.xyzSize();
 
@@ -190,9 +190,9 @@ namespace field {
       std::vector<field::FlagUID> allFlags;
       sliced->getAllRegisteredFlags( allFlags );
       os << endl << "Registered Flags: " << endl;
-      for(auto i = allFlags.begin(); i != allFlags.end(); ++i )
+      for(const auto & allFlag : allFlags)
       {
-         os << "\t" << i->getIdentifier()[0] << " = " << *i << endl;
+         os << "\t" << allFlag.getIdentifier()[0] << " = " << allFlag << endl;
       }
       os << endl;
 
@@ -231,9 +231,9 @@ namespace field {
                os << std::setw(3) << "|";
 
             std::string out;
-            for( auto curFlag = allFlags.begin(); curFlag != allFlags.end(); ++curFlag )
-               if ( sliced->isFlagSet(coord[0],coord[1],coord[2], sliced->getFlag(*curFlag) ) )
-                  out.append( 1, curFlag->getIdentifier()[0] );
+            for(const auto & allFlag : allFlags)
+               if ( sliced->isFlagSet(coord[0],coord[1],coord[2], sliced->getFlag(allFlag) ) )
+                  out.append( 1, allFlag.getIdentifier()[0] );
 
             os << std::setw(10) << out;
          }
diff --git a/src/field/StabilityChecker.h b/src/field/StabilityChecker.h
index 37493707da7f300154aaea0382e6bc027944bf24..b979213954627504f08ccb04e710f6dc65cffb55 100644
--- a/src/field/StabilityChecker.h
+++ b/src/field/StabilityChecker.h
@@ -301,7 +301,7 @@ public:
                                   "With FASTMATH activated NaNs are not defined and thus the checkFunction will not work. "
                                   "To make it work provide a different checkFunction.")
 #endif
-     static_assert( (std::is_same< Filter_T, DefaultEvaluationFilter >::value),
+     static_assert( (std::is_same_v< Filter_T, DefaultEvaluationFilter >),
                    "This constructor is only available if DefaultEvaluationFilter is set as filter type!" );
   }
 
@@ -314,7 +314,7 @@ public:
    outputToStream_( outputToStream ), outputVTK_( outputVTK ),
    requiredSelectors_(requiredSelectors), incompatibleSelectors_( incompatibleSelectors )
   {
-     static_assert( (std::is_same< Filter_T, DefaultEvaluationFilter >::value),
+     static_assert( (std::is_same_v< Filter_T, DefaultEvaluationFilter >),
                    "This constructor is only available if DefaultEvaluationFilter is set as filter type!" );
   }
 
@@ -384,27 +384,27 @@ void StabilityChecker< Field_T, Filter_T, CheckFunction_T >::operator()()
       std::ostringstream oss;
       oss << "Check for finiteness failed on process " << MPIManager::instance()->rank();
 
-      for( auto block = failedCells_.begin(); block != failedCells_.end(); ++block )
+      for(const auto & block : failedCells_)
       {
-         oss << "\n - on block " << block->first->getId() <<
-                "\n - on level " << blocks->getLevel( *(block->first) )  <<
+         oss << "\n - on block " << block.first->getId() <<
+                "\n - on level " << blocks->getLevel( *(block.first) )  <<
                 "\n - for:";
 
-         for( auto cell = block->second.begin(); cell != block->second.end(); ++cell )
+         for(const auto & cell : block.second )
          {
-            const cell_idx_t x = cell->first[0];
-            const cell_idx_t y = cell->first[1];
-            const cell_idx_t z = cell->first[2];
+            const cell_idx_t x = cell.first[0];
+            const cell_idx_t y = cell.first[1];
+            const cell_idx_t z = cell.first[2];
 
             Vector3< real_t > center;
-            blocks->getBlockLocalCellCenter( *(block->first), cell->first, center );
+            blocks->getBlockLocalCellCenter( *(block.first), cell.first, center );
 
             Cell gCell(x,y,z);
-            blocks->transformBlockLocalToGlobalCell( gCell, *(block->first) );
+            blocks->transformBlockLocalToGlobalCell( gCell, *(block.first) );
 
-            for( auto f = cell->second.begin(); f != cell->second.end(); ++f )
+            for(int const f : cell.second)
             {
-               oss << "\n   + block local cell( " << x << ", " << y << ", " << z << " ) at index " << *f <<
+               oss << "\n   + block local cell( " << x << ", " << y << ", " << z << " ) at index " << f <<
                       "\n     = global cell ( " << gCell.x() << ", " << gCell.y() << ", " << gCell.z() << " ) with "
                       "cell center ( " << center[0] << ", " << center[1] << ", " << center[2] << " )";
             }
@@ -627,7 +627,7 @@ inline void stabilityCheckerConfigParser( const Config::BlockHandle & parentBloc
 {
    if( parentBlockHandle )
    {
-      Config::BlockHandle block = parentBlockHandle.getBlock( configBlockName );
+      Config::BlockHandle const block = parentBlockHandle.getBlock( configBlockName );
       if( block )
       {
          defaultCheckFrequency = block.getParameter< uint_t >( "checkFrequency", defaultCheckFrequency );
diff --git a/src/field/VolumetricFlowRateEvaluation.h b/src/field/VolumetricFlowRateEvaluation.h
index 8d6aee70b899d617cb10cd0492a9295224b16fa9..6aa9ead00c530c45bcd216945d0276805e9c01d8 100644
--- a/src/field/VolumetricFlowRateEvaluation.h
+++ b/src/field/VolumetricFlowRateEvaluation.h
@@ -187,7 +187,7 @@ public:
       flowRate_( real_t(0) ), velocitySolutionFlowRate_( real_t(0) ),
       requiredSelectors_(requiredSelectors), incompatibleSelectors_( incompatibleSelectors )
    {
-      static_assert( (std::is_same< Filter_T, DefaultEvaluationFilter >::value),
+      static_assert( (std::is_same_v< Filter_T, DefaultEvaluationFilter >),
                      "This constructor is only available if DefaultEvaluationFilter is set as filter type!" );
 
       auto _blocks = blocks.lock();
@@ -538,7 +538,7 @@ inline void volumetricFlowRateEvaluationConfigParser( const Config::BlockHandle
 {
    if( parentBlockHandle )
    {
-      Config::BlockHandle block = parentBlockHandle.getBlock( configBlockName );
+      Config::BlockHandle const block = parentBlockHandle.getBlock( configBlockName );
       if( block )
       {
          defaultPlotFrequency = block.getParameter< uint_t >( "plotFrequency", defaultPlotFrequency );
diff --git a/src/field/adaptors/VectorFieldAccessor.h b/src/field/adaptors/VectorFieldAccessor.h
index 2ba6ca1a28969687caab67540456b5c615d7cbab..a0a3d628cc7a5c256bd21118ab0f7d69a30ba2b1 100644
--- a/src/field/adaptors/VectorFieldAccessor.h
+++ b/src/field/adaptors/VectorFieldAccessor.h
@@ -34,7 +34,7 @@ namespace field {
    struct VectorFieldAccessor
    {
       static_assert( VectorField_T::F_SIZE == 3, "Only valid for Fields with 3 components (F_SIZE==3)" );
-      static_assert( std::is_same< typename VectorField_T::value_type, real_t >::value, "Only works for real valued fields" );
+      static_assert( std::is_same_v< typename VectorField_T::value_type, real_t >, "Only works for real valued fields" );
 
       using vector_or_constRefVector = Vector3<real_t>;
 
@@ -53,8 +53,8 @@ namespace field {
 
    template<typename VectorField_T>
    struct VectorFieldAccessor<VectorField_T,
-                              typename std::enable_if< std::is_same< typename VectorField_T::value_type,
-                                                                           Vector3<real_t> >::value >::type >
+                              std::enable_if_t< std::is_same_v< typename VectorField_T::value_type,
+                                                                           Vector3<real_t> > > >
    {
        using vector_or_constRefVector = const Vector3<real_t> &;
 
diff --git a/src/field/allocation/FieldAllocator.h b/src/field/allocation/FieldAllocator.h
index eb93be118447d799a2c1c984f3e91235d55d2067..22267404bf8aeb7e4e0f0d9ea2106bfab9ff8055 100644
--- a/src/field/allocation/FieldAllocator.h
+++ b/src/field/allocation/FieldAllocator.h
@@ -52,10 +52,10 @@ namespace field {
    */
    //*******************************************************************************************************************
    template<typename T>
-   class FieldAllocator : FieldAllocatorBase<typename std::conditional<VectorTrait<T>::F_SIZE!=0, typename VectorTrait<T>::OutputType, T>::type>
+   class FieldAllocator : FieldAllocatorBase<std::conditional_t<VectorTrait<T>::F_SIZE!=0, typename VectorTrait<T>::OutputType, T>>
    {
       public:
-         using BaseType = typename std::conditional<VectorTrait<T>::F_SIZE!=0, typename VectorTrait<T>::OutputType, T>::type;
+         using BaseType = std::conditional_t<VectorTrait<T>::F_SIZE!=0, typename VectorTrait<T>::OutputType, T>;
 
          virtual ~FieldAllocator() = default;
 
diff --git a/src/field/blockforest/BlockDataHandling.h b/src/field/blockforest/BlockDataHandling.h
index 5113b895a881e3c7ba29c4f541c4801a4d6f6dfe..e43831ffa59ca0548f3802026423ef296cc1f14b 100644
--- a/src/field/blockforest/BlockDataHandling.h
+++ b/src/field/blockforest/BlockDataHandling.h
@@ -428,7 +428,7 @@ public:
                              const shared_ptr< field::FieldAllocator<Value_T> > alloc = nullptr) :
       blocks_( blocks ), nrOfGhostLayers_( nrOfGhostLayers ), initValue_( initValue ), layout_( layout ), calculateSize_( calculateSize ), alloc_(alloc)
    {
-      static_assert( !std::is_same< GhostLayerField_T, FlagField< Value_T > >::value,
+      static_assert( !std::is_same_v< GhostLayerField_T, FlagField< Value_T > >,
                      "When using class FlagField, only constructors without the explicit specification of an initial value and the field layout are available!" );
    }
 
@@ -495,7 +495,7 @@ public:
                                       const shared_ptr< field::FieldAllocator<Value_T> > alloc = nullptr) :
       blocks_( blocks ), nrOfGhostLayers_( nrOfGhostLayers ), initValue_( initValue ), layout_( layout ), calculateSize_( calculateSize ), alloc_(alloc)
    {
-      static_assert( ! std::is_same< GhostLayerField_T, FlagField< Value_T > >::value,
+      static_assert( ! std::is_same_v< GhostLayerField_T, FlagField< Value_T > >,
                      "When using class FlagField, only constructors without the explicit specification of an initial value and the field layout are available!" );
    }
 
diff --git a/src/field/blockforest/GradientRefinement.h b/src/field/blockforest/GradientRefinement.h
index fb7f8b46634d0e7d2467ab95ca63538fb5b4ed42..ae88ba65b4b00aa9b03c5efc9b7023569d3247e3 100644
--- a/src/field/blockforest/GradientRefinement.h
+++ b/src/field/blockforest/GradientRefinement.h
@@ -76,14 +76,14 @@ template< typename VectorField_T, typename Filter_T, bool Pseudo2D >
 void GradientRefinement< VectorField_T, Filter_T, Pseudo2D >::operator()( std::vector< std::pair< const Block *, uint_t > > & minTargetLevels,
                                                                           std::vector< const Block * > &, const BlockForest & )
 {
-   for( auto it = minTargetLevels.begin(); it != minTargetLevels.end(); ++it )
+   for(auto & minTargetLevel : minTargetLevels)
    {
-      const Block * const block = it->first;
+      const Block * const block = minTargetLevel.first;
       const VectorField_T * u = block->template getData< VectorField_T >( fieldId_ );
 
       if( u == nullptr )
       {
-         it->second = uint_t(0);
+         minTargetLevel.second = uint_t(0);
          continue;
       }
 
@@ -107,7 +107,7 @@ void GradientRefinement< VectorField_T, Filter_T, Pseudo2D >::operator()( std::v
          {
             const Vector3< real_t > & v = u->get(x,y,z);
 
-            real_t gradient[gradients];
+            real_t gradient[gradients]; // NOLINT(*-avoid-c-arrays)
             for( int i = 0; i < gradients; ++i )
                gradient[i] = real_t(0);
 
@@ -200,12 +200,12 @@ void GradientRefinement< VectorField_T, Filter_T, Pseudo2D >::operator()( std::v
       if( refine && block->getLevel() < maxLevel_ )
       {
          WALBERLA_ASSERT( !coarsen );
-         it->second = block->getLevel() + uint_t(1);
+         minTargetLevel.second = block->getLevel() + uint_t(1);
       }
       if( coarsen && block->getLevel() > uint_t(0) )
       {
          WALBERLA_ASSERT( !refine );
-         it->second = block->getLevel() - uint_t(1);
+         minTargetLevel.second = block->getLevel() - uint_t(1);
       }
    }
 }
diff --git a/src/field/communication/MPIDatatypes.impl.h b/src/field/communication/MPIDatatypes.impl.h
index a21ac75bd6a150fb14bae781bd3cdb5d9a66f22d..3a9a86376db5669a69253f0eb520d45b0ee83971 100644
--- a/src/field/communication/MPIDatatypes.impl.h
+++ b/src/field/communication/MPIDatatypes.impl.h
@@ -34,9 +34,9 @@ MPI_Datatype mpiDatatypeSlice( const Field_T & field,
                                const cell_idx_t xEnd, const cell_idx_t yEnd, const cell_idx_t zEnd, const cell_idx_t fEnd )
 {
    using T = typename Field_T::value_type;
-   int sizes[4];
-   int subsizes[4];
-   int starts[4];
+   std::array<int, 4> sizes;
+   std::array<int, 4> subsizes;
+   std::array<int, 4> starts;
 
    if( field.layout() == field::fzyx )
    {
@@ -85,7 +85,7 @@ MPI_Datatype mpiDatatypeSlice( const Field_T & field,
 
    WALBERLA_DEBUG_SECTION()
    {
-      for( int i = 0; i < 4; ++i )
+      for( uint_t i = 0; i < 4; ++i )
       {
          WALBERLA_ASSERT_GREATER_EQUAL( subsizes[i], 1 );
          WALBERLA_ASSERT_LESS_EQUAL( subsizes[i], sizes[i] );
@@ -95,7 +95,7 @@ MPI_Datatype mpiDatatypeSlice( const Field_T & field,
    }
 
    MPI_Datatype newType;
-   MPI_Type_create_subarray( 4, sizes, subsizes, starts, MPI_ORDER_C, MPITrait<T>::type(), &newType );
+   MPI_Type_create_subarray( 4, sizes.data(), subsizes.data(), starts.data(), MPI_ORDER_C, MPITrait<T>::type(), &newType );
 
    return newType;
 }
@@ -137,9 +137,9 @@ MPI_Datatype mpiDatatypeSliceXYZ( const Field_T & field, const CellInterval & in
 
    MPI_Datatype newType = MPI_DATATYPE_NULL;
 
-   int sizes[3];
-   int subsizes[3];
-   int starts[3];
+   std::array<int, 3> sizes;
+   std::array<int, 3> subsizes;
+   std::array<int, 3> starts;
 
    sizes[0] = int_c( field.zAllocSize() );
    sizes[1] = int_c( field.yAllocSize() );
@@ -163,7 +163,7 @@ MPI_Datatype mpiDatatypeSliceXYZ( const Field_T & field, const CellInterval & in
 
    WALBERLA_DEBUG_SECTION()
    {
-      for( int i = 0; i < 3; ++i )
+      for( uint_t i = 0; i < 3; ++i )
       {
          WALBERLA_ASSERT_GREATER_EQUAL( starts[i], 0 );
          WALBERLA_ASSERT_LESS_EQUAL( starts[i], sizes[i] - subsizes[i] );
@@ -175,9 +175,9 @@ MPI_Datatype mpiDatatypeSliceXYZ( const Field_T & field, const CellInterval & in
    if( field.layout() == field::fzyx )
    {
       MPI_Datatype tmpType = MPI_DATATYPE_NULL;
-      MPI_Type_create_subarray( 3, sizes, subsizes, starts, MPI_ORDER_C, MPITrait<T>::type(), &tmpType );
+      MPI_Type_create_subarray( 3, sizes.data(), subsizes.data(), starts.data(), MPI_ORDER_C, MPITrait<T>::type(), &tmpType );
 
-      int count = int_c( fs.size() );
+      int const count = int_c( fs.size() );
       std::vector<int> displacements( std::max( fs.size(), size_t( 1 ) ) ); // if "fs" is empty create a dummy vector from so that we can take an address to the first element
       std::transform( fs.begin(), fs.end(), displacements.begin(), int_c<cell_idx_t> );
       
@@ -199,7 +199,7 @@ MPI_Datatype mpiDatatypeSliceXYZ( const Field_T & field, const CellInterval & in
       MPI_Datatype resizedTmpType = MPI_DATATYPE_NULL;
       MPI_Type_create_resized( tmpType, 0, int_c( field.fAllocSize() * sizeof(T) ), &resizedTmpType );
 
-      MPI_Type_create_subarray( 3, sizes, subsizes, starts, MPI_ORDER_C, resizedTmpType, &newType );
+      MPI_Type_create_subarray( 3, sizes.data(), subsizes.data(), starts.data(), MPI_ORDER_C, resizedTmpType, &newType );
 
       MPI_Type_free( &tmpType );
       MPI_Type_free( &resizedTmpType );
diff --git a/src/field/distributors/KernelDistributor.h b/src/field/distributors/KernelDistributor.h
index bc0abb8fa5882e51960d936132cd3613d55f5172..851c999f636acddbf4734a6f504cfe0df6ae2d5e 100644
--- a/src/field/distributors/KernelDistributor.h
+++ b/src/field/distributors/KernelDistributor.h
@@ -88,7 +88,7 @@ public:
       
       const uint_t neighborhoodSize = cell_idx_t(1);
 
-      CellInterval cellNeighborhood( centerCell[0] - cell_idx_c(neighborhoodSize), centerCell[1] - cell_idx_c(neighborhoodSize), centerCell[2] - cell_idx_c(neighborhoodSize),
+      CellInterval const cellNeighborhood( centerCell[0] - cell_idx_c(neighborhoodSize), centerCell[1] - cell_idx_c(neighborhoodSize), centerCell[2] - cell_idx_c(neighborhoodSize),
                                      centerCell[0] + cell_idx_c(neighborhoodSize), centerCell[1] + cell_idx_c(neighborhoodSize), centerCell[2] + cell_idx_c(neighborhoodSize) );
 
       const uint_t kernelSizeOneDirection = uint_t(2) * neighborhoodSize + uint_t(1);
@@ -99,10 +99,10 @@ public:
       real_t sumOfWeightsUnavailable = real_t(0);
 
       // get distribution weights and count available cells in surrounding cells
-      for( auto cellIt = cellNeighborhood.begin(); cellIt != cellNeighborhood.end(); ++cellIt )
+      for(const auto & cellIt : cellNeighborhood)
       {
-         Vector3<real_t> curCellCenter = blockStorage->getBlockLocalCellCenter( block_, *cellIt );
-         if( flagField_.isPartOfMaskSet( *cellIt, evaluationMask_ ) )
+         Vector3<real_t> curCellCenter = blockStorage->getBlockLocalCellCenter( block_, cellIt );
+         if( flagField_.isPartOfMaskSet( cellIt, evaluationMask_ ) )
          {
             weights[counter] = kernelweights::kernelWeightFunction( x, y, z, curCellCenter[0], curCellCenter[1], curCellCenter[2], dx, dy, dz );
             sumOfWeights += weights[counter];
@@ -124,11 +124,11 @@ public:
 
       // distribute the values to the neighboring domain cells with the corresponding (scaled) weighting
       counter = uint_t(0);
-      for( auto cellIt = cellNeighborhood.begin(); cellIt != cellNeighborhood.end(); ++cellIt )
+      for(const auto & cellIt : cellNeighborhood)
       {
          if ( weights[counter] > real_t(0) )
          {
-            addWeightedCellValue( distributeValueBegin, *cellIt, scalingFactor * weights[counter] );
+            addWeightedCellValue( distributeValueBegin, cellIt, scalingFactor * weights[counter] );
          }
          ++counter;
       }
diff --git a/src/field/interpolators/KernelFieldInterpolator.h b/src/field/interpolators/KernelFieldInterpolator.h
index 0f5987e76e844df9505869fbaab3feadacbc88fa..cc18ff5d5e29952a9043e172e3740097ef1f5f77 100644
--- a/src/field/interpolators/KernelFieldInterpolator.h
+++ b/src/field/interpolators/KernelFieldInterpolator.h
@@ -42,7 +42,7 @@ namespace kernelweights
 // f(r) != 0 for abs(r) < 1.5 -> requires three neighborhood cells
 inline real_t smoothedDeltaFunction( const real_t & r )
 {
-   real_t rAbs = std::fabs(r);
+   real_t const rAbs = std::fabs(r);
    if( rAbs <= real_t(0.5) )
    {
       return (real_t(1) + std::sqrt( - real_t(3) * r * r + real_t(1) ) ) * (real_t(1) / real_t(3));
@@ -142,11 +142,11 @@ public:
       // store the calculated weighting factors of the UNavailable cells, i.e. cells not included in the evaluation mask
       std::vector<real_t> weightsUnavailable( kernelSizeOneDirection * kernelSizeOneDirection * kernelSizeOneDirection, real_t(0) );
 
-      cell_idx_t cellIdx0x = cellNeighborhood.xMin();
-      cell_idx_t cellIdx0y = cellNeighborhood.yMin();
-      cell_idx_t cellIdx0z = cellNeighborhood.zMin();
-      uint_t nx = kernelSizeOneDirection;
-      uint_t nxy = kernelSizeOneDirection * kernelSizeOneDirection;
+      cell_idx_t const cellIdx0x = cellNeighborhood.xMin();
+      cell_idx_t const cellIdx0y = cellNeighborhood.yMin();
+      cell_idx_t const cellIdx0z = cellNeighborhood.zMin();
+      uint_t const nx = kernelSizeOneDirection;
+      uint_t const nxy = kernelSizeOneDirection * kernelSizeOneDirection;
       Vector3<real_t> cellCenter0 = blockStorage->getBlockLocalCellCenter( block_, Cell(cellIdx0x, cellIdx0y, cellIdx0z) ); // = cell in neighborhood with smallest x-, y-, and z-indices
 
       // calculate kernel weights of all cells in neighborhood
@@ -224,9 +224,9 @@ public:
 
       const real_t scalingFactor = real_t(1) + sumOfWeightsUnavailable / sumOfWeights;
 
-      for( auto weightIt = weights.begin(); weightIt != weights.end(); ++weightIt )
+      for(auto & weight : weights)
       {
-         *weightIt *= scalingFactor;
+         weight *= scalingFactor;
       }
 
       // interpolate value to interpolation position using the previously calculated weights
diff --git a/src/field/iterators/FieldIterator.h b/src/field/iterators/FieldIterator.h
index 7557fea2af83b9c6b880dab2abc73a9eb9ec07f7..5022109fdeb9785fb525897ba391bbc321c49ae4 100644
--- a/src/field/iterators/FieldIterator.h
+++ b/src/field/iterators/FieldIterator.h
@@ -75,7 +75,7 @@ namespace field {
       using pointer = T*;
       using reference = T&;
 
-      using FieldType = Field<typename std::remove_const<T>::type, fieldFSize>;
+      using FieldType = Field<std::remove_const_t<T>, fieldFSize>;
 
       static const uint_t F_SIZE = fieldFSize;
 
@@ -162,7 +162,7 @@ namespace field {
       //****************************************************************************************************************
 
 
-      friend class Field<typename std::remove_const<T>::type, fieldFSize>;
+      friend class Field<std::remove_const_t<T>, fieldFSize>;
 
       void incrementLine();
       void decrementLine();
@@ -174,13 +174,13 @@ namespace field {
       /// In the following vectors [0] is the slowest and [3] the fastest coordinate
       /// Current values of the coordinates, forth coordinate implicitly stored in linePtr_
       /// and if needed written to fastestCoord_
-      cell_idx_t cur_[3];
+      std::array<cell_idx_t, 3> cur_;
 
       /// Number of elements to skip when coordinate wraps around
-      uint_t  skips_[4];
+      std::array<uint_t, 4>  skips_;
 
       /// Size of each coordinate
-      uint_t  sizes_[4];
+      std::array<uint_t, 4>  sizes_;
 
       /// Field where iterator belongs to
       const FieldType * f_;
@@ -220,7 +220,7 @@ namespace field {
    {
    public:
       using Parent = FieldIterator<T, fieldFSize>;
-      using FieldType = Field<typename std::remove_const<T>::type, fieldFSize>;
+      using FieldType = Field<std::remove_const_t<T>, fieldFSize>;
 
       //**Constructor/Destructor****************************************************************************************
       /*!\name Constructor/Destructor */
@@ -263,7 +263,7 @@ namespace field {
    {
    public:
        using Parent = FieldIterator<T, fieldFSize>;
-       using FieldType = Field<typename std::remove_const<T>::type, fieldFSize>;
+       using FieldType = Field<std::remove_const_t<T>, fieldFSize>;
 
       //**Constructor/Destructor****************************************************************************************
       /*!\name Constructor/Destructor */
diff --git a/src/field/iterators/FieldIterator.impl.h b/src/field/iterators/FieldIterator.impl.h
index dad6841f9b1e4599431332d32208db9acdee79ed..f377132dd811319dbb31e0f4fabbc6d2e82c881f 100644
--- a/src/field/iterators/FieldIterator.impl.h
+++ b/src/field/iterators/FieldIterator.impl.h
@@ -47,7 +47,7 @@ FieldIterator<T,fs>::FieldIterator( const typename FieldIterator<T,fs>::FieldTyp
       return;
    }
 
-   using NonConstT = typename std::remove_const<T>::type;
+   using NonConstT = std::remove_const_t<T>;
 
    cur_[0] = cur_[1] = cur_[2] = 0;
    if( f_->layout() == fzyx )
@@ -134,10 +134,10 @@ FieldIterator<T,fs>::FieldIterator( const FieldIterator<T,fs> & o )
      fBegin_        ( o.fBegin_       )
 {
    // no need to copy fastestCoord_, since it is updated before read
-   for(int i=0; i<3; ++i)
+   for(uint_t i=0; i<3; ++i)
       cur_[i] = o.cur_[i];
 
-   for( int i=0; i<4; ++i ) {
+   for(uint_t i=0; i<4; ++i ) {
       skips_[i] = o.skips_[i];
       sizes_[i] = o.sizes_[i];
    }
@@ -164,10 +164,10 @@ FieldIterator<T,fs> & FieldIterator<T,fs>::operator= ( const FieldIterator<T,fs>
    zBegin_    = o.zBegin_   ;
    fBegin_    = o.fBegin_   ;
 
-   for(int i=0; i<3; ++i)
+   for(uint_t i=0; i<3; ++i)
       cur_[i] = o.cur_[i];
 
-   for( int i=0; i<4; ++i ) {
+   for(uint_t i=0; i<4; ++i ) {
       skips_[i] = o.skips_[i];
       sizes_[i] = o.sizes_[i];
    }
@@ -459,9 +459,9 @@ template <typename T, uint_t fs>
 inline Cell FieldIterator<T,fs>::cell() const
 {
    fastestCoord_ = cell_idx_c( linePtr_ - lineBegin_ );
-   return Cell ( xBegin_ + *curX_,
+   return { xBegin_ + *curX_,
                  yBegin_ + *curY_,
-                 zBegin_ + *curZ_ );
+                 zBegin_ + *curZ_ };
 }
 
 
diff --git a/src/field/iterators/FieldNeighborPointer.h b/src/field/iterators/FieldNeighborPointer.h
index 4ab5a13c04c618d54f24f82aef8b30de0a273373..c4fa082fc219c7e29efcf6682ade2e1fc8d63d5c 100644
--- a/src/field/iterators/FieldNeighborPointer.h
+++ b/src/field/iterators/FieldNeighborPointer.h
@@ -92,7 +92,7 @@ namespace field {
       inline cell_idx_t & f()       { return f_; }
       inline cell_idx_t   f() const { return f_; }
 
-      inline Cell cell() const { return Cell( x_, y_, z_ ); }
+      inline Cell cell() const { return { x_, y_, z_ }; }
 
       const FieldMember * getField() const { return &field_; }
 
diff --git a/src/field/iterators/FieldPointer.h b/src/field/iterators/FieldPointer.h
index b36a19af5d57181215a05e3a856b181d8554d13b..5e73a1afcc9c379ae7d38e9f21e3b32941fad3f6 100644
--- a/src/field/iterators/FieldPointer.h
+++ b/src/field/iterators/FieldPointer.h
@@ -114,7 +114,7 @@ namespace field {
       inline cell_idx_t & f()       { return f_; }
       inline cell_idx_t   f() const { return f_; }
 
-      inline Cell cell() const { return Cell( x_, y_, z_ ); }
+      inline Cell cell() const { return { x_, y_, z_ }; }
 
       const FieldMember * getField() const { return &field_; }
 
diff --git a/src/field/refinement/PackInfo.h b/src/field/refinement/PackInfo.h
index bc4f683440109031d0dd9d53bc0ed6167430af66..bb1eb928b44d1385df623641304dd12414d33122 100644
--- a/src/field/refinement/PackInfo.h
+++ b/src/field/refinement/PackInfo.h
@@ -513,7 +513,7 @@ inline Vector3< cell_idx_t > PackInfo< Field_T, Stencil >::getNeighborShift( con
 {
    Vector3< cell_idx_t > shift;
 
-   uint_t branchId = smallBlock.getBranchId();
+   uint_t const branchId = smallBlock.getBranchId();
 
    shift[0] = ( stencil::cx[dir] == 0 ) ? ( ( ( branchId & uint_t(1) ) == uint_t(0) ) ? cell_idx_t(-1) : cell_idx_t(1) ) : cell_idx_t(0);
    shift[1] = ( stencil::cy[dir] == 0 ) ? ( ( ( branchId & uint_t(2) ) == uint_t(0) ) ? cell_idx_t(-1) : cell_idx_t(1) ) : cell_idx_t(0);
@@ -646,11 +646,11 @@ inline bool PackInfo< Field_T, Stencil >::isCornerDirection( stencil::Direction
 template< typename Field_T, typename Stencil >
 inline bool PackInfo< Field_T, Stencil >::blocksConnectedByFaces( const Block * block, const BlockID & neighbor )
 {
-   const uint_t face[] = { uint_t(4), uint_t(10), uint_t(12), uint_t(13), uint_t(15), uint_t(21) };
-   for( int i = 0; i != 6; ++i )
+   const std::array<uint_t, 6> face = { uint_t(4), uint_t(10), uint_t(12), uint_t(13), uint_t(15), uint_t(21) };
+   for(const auto & i : face)
    {
-      for( uint_t n = 0; n != block->getNeighborhoodSectionSize( face[i] ); ++n )
-         if( block->getNeighborId( face[i], n ) == neighbor )
+      for( uint_t n = 0; n != block->getNeighborhoodSectionSize( i ); ++n )
+         if( block->getNeighborId( i, n ) == neighbor )
             return true;
    }
    return false;
@@ -661,13 +661,13 @@ inline bool PackInfo< Field_T, Stencil >::blocksConnectedByFaces( const Block *
 template< typename Field_T, typename Stencil >
 inline bool PackInfo< Field_T, Stencil >::blocksConnectedByEdges( const Block * block, const BlockID & neighbor )
 {
-   const uint_t face[] = { uint_t( 1), uint_t( 3), uint_t( 5), uint_t( 7), uint_t( 9), uint_t(11),
+   const std::array<uint_t, 12> edges = { uint_t( 1), uint_t( 3), uint_t( 5), uint_t( 7), uint_t( 9), uint_t(11),
                            uint_t(14), uint_t(16), uint_t(18), uint_t(20), uint_t(22), uint_t(24) };
 
-   for( int i = 0; i != 12; ++i )
+   for(const auto & i : edges)
    {
-      for( uint_t n = 0; n != block->getNeighborhoodSectionSize( face[i] ); ++n )
-         if( block->getNeighborId( face[i], n ) == neighbor )
+      for( uint_t n = 0; n != block->getNeighborhoodSectionSize( i ); ++n )
+         if( block->getNeighborId( i, n ) == neighbor )
             return true;
    }
    return false;
diff --git a/src/field/vtk/FlagFieldCellFilter.h b/src/field/vtk/FlagFieldCellFilter.h
index d82c3a13e82cbab5851f7572ef44c02a9bb186f5..3792ba944c714388a6bc08cb50eea25497ad3ff0 100644
--- a/src/field/vtk/FlagFieldCellFilter.h
+++ b/src/field/vtk/FlagFieldCellFilter.h
@@ -51,15 +51,15 @@ public:
       WALBERLA_ASSERT_NOT_NULLPTR( flagField );
 
       std::vector< FlagUID > existingFlags;
-      for( auto flag = filteredFlags_.begin(); flag != filteredFlags_.end(); ++flag )
-         if( flagField->flagExists( *flag ) )
-            existingFlags.push_back( *flag );
+      for(auto filteredFlag : filteredFlags_)
+         if( flagField->flagExists( filteredFlag ) )
+            existingFlags.push_back( filteredFlag );
 
       if( !existingFlags.empty() )
       {
          flag_t filterMask( flag_t(0) );
-         for( auto flag = existingFlags.begin(); flag != existingFlags.end(); ++flag )
-            filterMask = static_cast< flag_t >( filterMask | flagField->getFlag( *flag ) );
+         for(const auto & existingFlag : existingFlags)
+            filterMask = static_cast< flag_t >( filterMask | flagField->getFlag( existingFlag ) );
 
          const cell_idx_t gl    = cell_idx_c( ghostLayers );
          const cell_idx_t begin = cell_idx_c( -1 ) * gl;
diff --git a/src/geometry/GeometricalFunctions.cpp b/src/geometry/GeometricalFunctions.cpp
index 3ae39d9ee041d1ccef4ca2bfed7e65ce52e8c389..7922e531242444b97ff17dd41b57a57b44a8ef11 100644
--- a/src/geometry/GeometricalFunctions.cpp
+++ b/src/geometry/GeometricalFunctions.cpp
@@ -74,20 +74,20 @@ void getClosestLineBoxPoints( const Vector3<real_t>& p1, const Vector3<real_t>&
    Vector3<real_t> tmp( R * l );
 
    // Saving the sign of the direction p1--p2
-   const real_t sign[] = { math::sign(tmp[0]), math::sign(tmp[1]), math::sign(tmp[2]) };
+   const std::array<real_t, 3> sign{ math::sign(tmp[0]), math::sign(tmp[1]), math::sign(tmp[2]) };
 
    // Calculating the absolute values of the direction direction
-   const real_t v [] = { sign[0]*tmp[0], sign[1]*tmp[1], sign[2]*tmp[2] };
-   const real_t v2[] = { sq( v[0] )   , sq( v[1] )   , sq( v[2] )    };
+   const std::array<real_t, 3> v { sign[0]*tmp[0], sign[1]*tmp[1], sign[2]*tmp[2] };
+   const std::array<real_t, 3> v2{ sq( v[0] )    , sq( v[1] )    , sq( v[2] )     };
 
    // Calculating the starting point of the line p1--p2 in box-relative coordinates
    tmp = p1 - c;
-   const real_t s[] = { sign[0]*( R[0]*tmp[0] + R[3]*tmp[1] + R[6]*tmp[2] ),
-                      sign[1]*( R[1]*tmp[0] + R[4]*tmp[1] + R[7]*tmp[2] ),
-                      sign[2]*( R[2]*tmp[0] + R[5]*tmp[1] + R[8]*tmp[2] ) };
+   const std::array<real_t, 3> s{ sign[0]*( R[0]*tmp[0] + R[3]*tmp[1] + R[6]*tmp[2] ),
+                                  sign[1]*( R[1]*tmp[0] + R[4]*tmp[1] + R[7]*tmp[2] ),
+                                  sign[2]*( R[2]*tmp[0] + R[5]*tmp[1] + R[8]*tmp[2] ) };
 
    // Calculating the half lengths of the box
-   const real_t h[] = { real_t(0.5)*side[0], real_t(0.5)*side[1], real_t(0.5)*side[2] };
+   const std::array<real_t, 3> h{ real_t(0.5)*side[0], real_t(0.5)*side[1], real_t(0.5)*side[2] };
 
 
    // Estimating the region of the starting point depending on which side of the
@@ -95,8 +95,8 @@ void getClosestLineBoxPoints( const Vector3<real_t>& p1, const Vector3<real_t>&
    // causing a transition from one to another region, or the last one if there
    // are no more. Additionally, d|d|^2/dt is computed for t=0. If it is >= 0
    // then p1 is the closest point since the line points away from the box.
-   int  region [] = { 0, 0, 0 };
-   real_t tanchor[] = { 2, 2, 2 };  // Invalid t values; t cannot be greater than 1
+   std::array<int, 3>    region{ 0 };
+   std::array<real_t, 3> tanchor{ 2 };  // Invalid t values; t cannot be greater than 1
    real_t dd2dt( 0 );
 
    if( v[0] > Limits<real_t>::epsilon() )
diff --git a/src/geometry/GeometricalFunctions.h b/src/geometry/GeometricalFunctions.h
index 27e1f89a786e6a8d6c54a40d68d2a303532f0c04..3c88baff8036ab29917865a30b06a29f829d0999 100644
--- a/src/geometry/GeometricalFunctions.h
+++ b/src/geometry/GeometricalFunctions.h
@@ -89,7 +89,7 @@ inline bool pointInFrontOfPlane( const Vector3<real_t>& normal, const Vector3<re
 inline bool originInTetrahedron( const Vector3<real_t>& A, const Vector3<real_t>& B, const Vector3<real_t>& C, const Vector3<real_t>& D ) {
    using namespace walberla::math;
 
-   Vector3<real_t> aoT = A;
+   Vector3<real_t> const aoT = A;
 
    //using fpuAccuracy instead of real(0.0) to avoid numeric problems
    if((aoT * (B % C)) < -Limits<real_t>::fpuAccuracy()) {
diff --git a/src/geometry/bodies/AABBBody.h b/src/geometry/bodies/AABBBody.h
index bf2aed3c6bbae45dc586459f6036840511b5c049..08093b5494bba7a5156f374e17362193b88683e1 100644
--- a/src/geometry/bodies/AABBBody.h
+++ b/src/geometry/bodies/AABBBody.h
@@ -32,7 +32,7 @@ namespace geometry {
 template<>
 inline real_t overlapFraction ( const AABB & body, const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx, uint_t )
 {
-   AABB box = AABB::createFromMinMaxCorner( cellMidpoint[0] - real_t(0.5)*dx[0], cellMidpoint[1] - real_t(0.5)*dx[1], cellMidpoint[2] - real_t(0.5)*dx[2],
+   AABB const box = AABB::createFromMinMaxCorner( cellMidpoint[0] - real_t(0.5)*dx[0], cellMidpoint[1] - real_t(0.5)*dx[1], cellMidpoint[2] - real_t(0.5)*dx[2],
                                             cellMidpoint[0] + real_t(0.5)*dx[0], cellMidpoint[1] + real_t(0.5)*dx[1], cellMidpoint[2] + real_t(0.5)*dx[2]);
 
    return body.intersectionVolume( box ) / ( dx[0] * dx[1] * dx[2] );
diff --git a/src/geometry/bodies/BodyFromConfig.cpp b/src/geometry/bodies/BodyFromConfig.cpp
index 111de46aedc88a72593356e8e4f4ea8ca33d581d..b7f79ab0b5f314d4c89353bad03a9eff295514fa 100644
--- a/src/geometry/bodies/BodyFromConfig.cpp
+++ b/src/geometry/bodies/BodyFromConfig.cpp
@@ -51,8 +51,8 @@ Cylinder cylinderFromConfig( const Config::BlockHandle & block )
    if ( ! block.isDefined( "radius" ) )
       WALBERLA_ABORT( "Missing parameter 'radius' for cylinder defined in block " << block.getKey() );
 
-   Vector3<real_t> min = block.getParameter<Vector3<real_t> > ( "min" );
-   Vector3<real_t> max = block.getParameter<Vector3<real_t> > ( "max" );
+   Vector3<real_t> const min = block.getParameter<Vector3<real_t> > ( "min" );
+   Vector3<real_t> const max = block.getParameter<Vector3<real_t> > ( "max" );
 
    return Cylinder( min, max, block.getParameter<real_t>( "radius" ) );
 }
@@ -69,8 +69,8 @@ Torus torusFromConfig( const Config::BlockHandle & block )
    if ( ! block.isDefined( "distance" ) )
       WALBERLA_ABORT( "Missing parameter 'distance' for torus defined in block " << block.getKey() );
 
-   Vector3<real_t> midpoint = block.getParameter<Vector3<real_t> > ( "midpoint" );
-   Vector3<real_t> normal   = block.getParameter<Vector3<real_t> > ( "normal"   );
+   Vector3<real_t> const midpoint = block.getParameter<Vector3<real_t> > ( "midpoint" );
+   Vector3<real_t> const normal   = block.getParameter<Vector3<real_t> > ( "normal"   );
 
    return Torus( midpoint, normal, block.getParameter<real_t>( "radius" ), block.getParameter<real_t>( "distance" ) );
 }
@@ -83,7 +83,7 @@ Ellipsoid ellipsoidFromConfig ( const Config::BlockHandle & block )
    if( ! block.isDefined( "radii" ) )
       WALBERLA_ABORT( "Missing parameter 'radii' for ellipsoid defined in block " << block.getKey() );
 
-   Vector3<real_t> radii = block.getParameter<Vector3<real_t> > ( "radii" );
+   Vector3<real_t> const radii = block.getParameter<Vector3<real_t> > ( "radii" );
 
    return Ellipsoid( block.getParameter<Vector3<real_t> >( "midpoint" ),
                      block.getParameter<Vector3<real_t> >( "axis1", Vector3<real_t>( real_t(1),real_t(0),real_t(0) ) ),
@@ -102,7 +102,7 @@ AABB AABBFromConfig( const Config::BlockHandle & block )
    Vector3<real_t> min = block.getParameter<Vector3<real_t> > ( "min" );
    Vector3<real_t> max = block.getParameter<Vector3<real_t> > ( "max" );
 
-   return AABB( min[0], min[1], min[2], max[0], max[1], max[2] );
+   return { min[0], min[1], min[2], max[0], max[1], max[2] };
 }
 
 
@@ -137,7 +137,7 @@ BodyLogicalAND<Sphere,BodyLogicalNOT<Sphere> > hollowSphereFromConfig ( const Co
 
 shared_ptr<AbstractBody> bodyFromConfig (const Config::BlockHandle & block )
 {
-   std::string shape = block.getParameter<std::string>("shape");
+   std::string const shape = block.getParameter<std::string>("shape");
    
    if      ( string_icompare( shape, "Sphere"   ) == 0 )
       return make_DynamicBody(sphereFromConfig   ( block ) );
diff --git a/src/geometry/bodies/Ellipsoid.cpp b/src/geometry/bodies/Ellipsoid.cpp
index bf6727ab5e7b6ccbc4a0760d6775b627b617bbc9..744bd66abc17cb54bec62bda13cd35c2d6788761 100644
--- a/src/geometry/bodies/Ellipsoid.cpp
+++ b/src/geometry/bodies/Ellipsoid.cpp
@@ -21,6 +21,8 @@
 
 #include "Ellipsoid.h"
 
+#include <algorithm>
+
 
 namespace walberla {
 namespace geometry {
@@ -53,8 +55,8 @@ namespace geometry {
 
       mat_ = rotationMatrix_ *  diagonalMatrix * rotationMatrix_.getTranspose() ;
 
-      minRadius_ = std::min( radii_[0], std::min( radii_[1], radii_[2] ) );
-      maxRadius_ = std::max( radii_[0], std::max( radii_[1], radii_[2] ) );
+      minRadius_ = std::min( {radii_[0], radii_[1], radii_[2] } );
+      maxRadius_ = std::max( {radii_[0], radii_[1], radii_[2] } );
 
       updateBoundingBox( );
    }
@@ -75,10 +77,10 @@ namespace geometry {
       diagonalMatrix(0,0) = radii_[0];
       diagonalMatrix(1,1) = radii_[1];
       diagonalMatrix(2,2) = radii_[2];
-      Matrix3<real_t> M = rotationMatrix_.rotate( diagonalMatrix );
-      real_t xMax = (M * ( M.multTranspose( Vector3<real_t>(1, 0, 0 ) ).getNormalized() ) )[0];
-      real_t yMax = (M * ( M.multTranspose( Vector3<real_t>(0, 1, 0 ) ).getNormalized() ) )[1];
-      real_t zMax = (M * ( M.multTranspose( Vector3<real_t>(0, 0, 1 ) ).getNormalized() ) )[2];
+      Matrix3<real_t> const M = rotationMatrix_.rotate( diagonalMatrix );
+      real_t const xMax = (M * ( M.multTranspose( Vector3<real_t>(1, 0, 0 ) ).getNormalized() ) )[0];
+      real_t const yMax = (M * ( M.multTranspose( Vector3<real_t>(0, 1, 0 ) ).getNormalized() ) )[1];
+      real_t const zMax = (M * ( M.multTranspose( Vector3<real_t>(0, 0, 1 ) ).getNormalized() ) )[2];
       boundingBox_ = AABB::createFromMinMaxCorner( midpoint_[0] - xMax, midpoint_[1] - yMax, midpoint_[2] - zMax,
                                                    midpoint_[0] + xMax, midpoint_[1] + yMax, midpoint_[2] + zMax  );
    }
@@ -101,7 +103,7 @@ namespace geometry {
    template<>
    FastOverlapResult fastOverlapCheck ( const Ellipsoid & ellipsoid, const Vector3<real_t> & cellMidpoint, const Vector3<real_t> & dx )
    {
-      AABB box = AABB::createFromMinMaxCorner( cellMidpoint[0] - real_t(0.5)*dx[0], cellMidpoint[1] - real_t(0.5)*dx[1], cellMidpoint[2] - real_t(0.5)*dx[2],
+      AABB const box = AABB::createFromMinMaxCorner( cellMidpoint[0] - real_t(0.5)*dx[0], cellMidpoint[1] - real_t(0.5)*dx[1], cellMidpoint[2] - real_t(0.5)*dx[2],
                                                cellMidpoint[0] + real_t(0.5)*dx[0], cellMidpoint[1] + real_t(0.5)*dx[1], cellMidpoint[2] + real_t(0.5)*dx[2]);
 
       if ( ! ellipsoid.boundingBox().intersects( box ) )
diff --git a/src/geometry/bodies/Sphere.cpp b/src/geometry/bodies/Sphere.cpp
index ffd62b51aa7799e18743b286b86eaf3e6acafe5d..461e86bc34a5341b163feee6690b916d5b06d31a 100644
--- a/src/geometry/bodies/Sphere.cpp
+++ b/src/geometry/bodies/Sphere.cpp
@@ -39,7 +39,7 @@ namespace geometry {
       boundingBox_ = AABB::createFromMinMaxCorner( midpoint_[0] - radius_, midpoint_[1] - radius_, midpoint_[2] - radius_,
                                                    midpoint_[0] + radius_, midpoint_[1] + radius_, midpoint_[2] + radius_ );
 
-      real_t halfBoxEdge = radius_ * oneOverSqrt3;
+      real_t const halfBoxEdge = radius_ * oneOverSqrt3;
       innerBox_ = AABB::createFromMinMaxCorner( midpoint_[0] - halfBoxEdge, midpoint_[1] - halfBoxEdge, midpoint_[2] - halfBoxEdge,
                                                 midpoint_[0] + halfBoxEdge, midpoint_[1] + halfBoxEdge, midpoint_[2] + halfBoxEdge );
    }
diff --git a/src/geometry/containment_octree/BranchNode.h b/src/geometry/containment_octree/BranchNode.h
index cb10fdabbf1b0f54406c2fd853838fbca114c7dd..2fe1167f71ab076684c24d195a01d83095c80b7f 100644
--- a/src/geometry/containment_octree/BranchNode.h
+++ b/src/geometry/containment_octree/BranchNode.h
@@ -1,15 +1,15 @@
 //======================================================================================================================
 //
-//  This file is part of waLBerla. waLBerla is free software: you can 
+//  This file is part of waLBerla. waLBerla 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.
-//  
-//  waLBerla 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 
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
@@ -40,31 +40,30 @@ public:
    using Scalar = typename Node<ContainmentOctreeT>::Scalar;
    using Point = typename Node<ContainmentOctreeT>::Point;
    using AABB = typename Node<ContainmentOctreeT>::AABB;
-   
+
    using KahanAccumulator = typename Node<ContainmentOctreeT>::KahanAccumulator;
-   
+
    inline BranchNode( const shared_ptr<const DistanceObject> & distanceObject, const AABB & aabb, const Scalar epsilon,
                       const uint_t maxDepth, const Scalar minAABBVolume );
 
-   ~BranchNode() override { for( int i = 0; i < 8; ++i ) delete children_[i]; }
+   ~BranchNode() override { for(auto & i : children_) delete i; }
 
-   virtual inline bool contains( const Point & p ) const;
+   inline bool contains( const Point & p ) const override;
 
-   virtual inline uint_t height() const;
-   virtual inline uint_t numNodes() const;
-   virtual inline void numNodes( uint_t & numInside, uint_t & numOutside, uint_t & numIndeterminate, uint_t & numBranch ) const;
-   virtual void volumes( KahanAccumulator & insideVolume, KahanAccumulator & outsideVolume, KahanAccumulator & indeterminateVolume, Scalar volume ) const;
-   virtual uint_t numChildren() const { return 8; }
+   inline uint_t height() const override;
+   inline uint_t numNodes() const override;
+   inline void numNodes( uint_t & numInside, uint_t & numOutside, uint_t & numIndeterminate, uint_t & numBranch ) const override;
+   void volumes( KahanAccumulator & insideVolume, KahanAccumulator & outsideVolume, KahanAccumulator & indeterminateVolume, Scalar volume ) const override;
+   uint_t numChildren() const override { return 8; }
    const Point & center() const { return center_; }
 
-   virtual const Node<ContainmentOctreeT> * getChild( const uint_t idx ) const { WALBERLA_ASSERT_LESS( idx, 8 ); return children_[idx]; }
+   const Node<ContainmentOctreeT> * getChild( const uint_t idx ) const override { WALBERLA_ASSERT_LESS( idx, 8 ); return children_[idx]; }
 
-private:
-   BranchNode( const BranchNode & other );
-   BranchNode & operator=( const BranchNode & other );
+   BranchNode( const BranchNode & other ) = delete;
+   BranchNode & operator=( const BranchNode & other ) = delete;
 
 protected:
-   const Node<ContainmentOctreeT> * children_[8];
+   std::array< const Node<ContainmentOctreeT> *, 8 >  children_;
    Point center_;
 };
 
@@ -73,14 +72,14 @@ template< typename ContainmentOctreeT >
 BranchNode<ContainmentOctreeT>::BranchNode( const shared_ptr<const DistanceObject> & distanceObject, const AABB & aabb, const Scalar epsilon,
                                             const uint_t maxDepth, const Scalar minAABBVolume ) : center_( this->toPoint( aabb.center() ) )
 {
-   for( int i = 0; i < 8; ++i )
+   for( uint_t i = 0; i < uint_t(8); ++i )
       children_[i] = nullptr;
 
    const auto & min = aabb.minCorner();
    const auto & max = aabb.maxCorner();
    const auto & ctr = center_;
 
-   AABB childAABBs[8] = {
+   std::array<AABB, 8> childAABBs = {
       AABB::createFromMinMaxCorner( min[0], min[1], min[2], ctr[0], ctr[1], ctr[2] ),
       AABB::createFromMinMaxCorner( min[0], min[1], ctr[2], ctr[0], ctr[1], max[2] ),
       AABB::createFromMinMaxCorner( min[0], ctr[1], min[2], ctr[0], max[1], ctr[2] ),
@@ -97,8 +96,8 @@ BranchNode<ContainmentOctreeT>::BranchNode( const shared_ptr<const DistanceObjec
    halfAABBDimensions[2] += epsilon;
    Scalar maxSqDistanceCenterAABB = halfAABBDimensions.sqrLength();
 
-   auto childAABBIt = childAABBs;
-   for( auto it = children_; it != children_ + 8; ++it, ++childAABBIt )
+   auto childAABBIt = std::begin(childAABBs);
+   for( auto it = std::begin(children_); it != std::end(children_); ++it, ++childAABBIt )
    {
       const auto childAABBCenter = childAABBIt->center();
 
@@ -162,7 +161,7 @@ template< typename ContainmentOctreeT >
 uint_t BranchNode<ContainmentOctreeT>::height() const
 {
    uint_t maxChildHeight = children_[0]->height();
-   for( int i = 1; i < 8; ++i )
+   for( uint_t i = 1; i < 8; ++i )
    {
       uint_t childHeight = children_[i]->height();
       if( childHeight > maxChildHeight )
@@ -177,8 +176,8 @@ template< typename ContainmentOctreeT >
 uint_t BranchNode<ContainmentOctreeT>::numNodes() const
 {
    uint_t nodes = 1;
-   for( int i = 0; i < 8; ++i )
-      nodes += children_[i]->numNodes();
+   for(auto & i : children_)
+      nodes += i->numNodes();
 
    return nodes;
 }
@@ -188,8 +187,8 @@ template< typename ContainmentOctreeT >
 void BranchNode<ContainmentOctreeT>::numNodes( uint_t & numInside, uint_t & numOutside, uint_t & numIndeterminate, uint_t & numBranch ) const
 {
    ++numBranch;
-   for( int i = 0; i < 8; ++i )
-      children_[i]->numNodes( numInside, numOutside, numIndeterminate, numBranch );
+   for(auto & i : children_)
+      i->numNodes( numInside, numOutside, numIndeterminate, numBranch );
 }
 
 
@@ -197,14 +196,14 @@ template< typename ContainmentOctreeT >
 void BranchNode<ContainmentOctreeT>::volumes( KahanAccumulator & insideVolume, KahanAccumulator & outsideVolume, KahanAccumulator & indeterminateVolume, Scalar volume ) const
 {
    static const Scalar ONE_OVER_EIGHT = Scalar(1) / Scalar(8);
-   for( int i = 0; i < 8; ++i )
-      children_[i]->volumes( insideVolume, outsideVolume, indeterminateVolume, volume * ONE_OVER_EIGHT );
+   for(auto const & i : children_)
+      i->volumes( insideVolume, outsideVolume, indeterminateVolume, volume * ONE_OVER_EIGHT );
 }
 
 
 
 
-   
+
 } // namespace containment_octree
 } // namespace geometry
-} // namespace walberla
+} // namespace walberla
\ No newline at end of file
diff --git a/src/geometry/containment_octree/ContainmentOctree.h b/src/geometry/containment_octree/ContainmentOctree.h
index d95fa55ceb59b1be675ded5b180e4434941cfd99..9cde4e21b791551c4f7b97659d685088c86462a6 100644
--- a/src/geometry/containment_octree/ContainmentOctree.h
+++ b/src/geometry/containment_octree/ContainmentOctree.h
@@ -315,7 +315,7 @@ void ContainmentOctree<DistanceObjectT>::writeVTKOutput( const std::string & fil
    while( !nodeQueue.empty() )
    {
       const Node * frontNode = nodeQueue.front();
-      uint8_t depth = depthQueue.front();
+      uint8_t const depth = depthQueue.front();
       nodeQueue.pop();
       depthQueue.pop();
 
diff --git a/src/geometry/initializer/BoundaryFromImage.impl.h b/src/geometry/initializer/BoundaryFromImage.impl.h
index 0284887aa6bc36bd258869aa22bdcbe5b4ca41e3..dfb02ed78526161aeaddadbb7fbf8012b2b9a8e6 100644
--- a/src/geometry/initializer/BoundaryFromImage.impl.h
+++ b/src/geometry/initializer/BoundaryFromImage.impl.h
@@ -22,6 +22,7 @@
 #include "core/math/Vector3.h"
 #include "field/GhostLayerField.h"
 
+#include <algorithm>
 #include <limits>
 #include "BoundaryFromImage.h"
 
@@ -89,9 +90,9 @@ namespace initializer {
       // the extrusion limit can not be left at numeric_limits::min/max since
       // the blockStorage.transformGlobalToLocal would overflow
       cell_idx_t maxNumberOfCells = cell_idx_c(
-                                    std::max( structuredBlockStorage_.getNumberOfXCells(),
-                                    std::max( structuredBlockStorage_.getNumberOfYCells(),
-                                              structuredBlockStorage_.getNumberOfZCells() ) ) );
+                                    std::max( {structuredBlockStorage_.getNumberOfXCells(),
+                                    structuredBlockStorage_.getNumberOfYCells(),
+                                              structuredBlockStorage_.getNumberOfZCells() } ) );
 
       if ( upperExtrusionLimit > maxNumberOfCells )
          upperExtrusionLimit = maxNumberOfCells;
@@ -167,16 +168,16 @@ namespace initializer {
 
       BoundarySetters mapping;
 
-      for( auto mappingBlock = mappingBlocks.begin(); mappingBlock != mappingBlocks.end(); ++mappingBlock )
+      for(auto & mappingBlock : mappingBlocks)
       {
-         const std::string pixelValueStr =  mappingBlock->template getParameter<std::string> ( "value" );
+         const std::string pixelValueStr =  mappingBlock.template getParameter<std::string> ( "value" );
          auto pixelValue = Image_T::pixelValueFromString( pixelValueStr );
 
          if( mapping.find( pixelValue )  != mapping.end() )
             WALBERLA_ABORT( "BoundaryFromImage: Duplicate BoundaryValueMapping for pixel value " << pixelValue );
 
          BoundarySetter<Handling> boundarySetter;
-         boundarySetter.setConfigBlock( *mappingBlock );
+         boundarySetter.setConfigBlock( mappingBlock );
 
          mapping[pixelValue] = boundarySetter;
       }
diff --git a/src/geometry/initializer/BoundaryFromVoxelFile.cpp b/src/geometry/initializer/BoundaryFromVoxelFile.cpp
index eeadd1f98b21ed9c4c1182b8e5a96e7de12cfb27..7a5d152b04fb3753176178da3a788481eca1da34 100644
--- a/src/geometry/initializer/BoundaryFromVoxelFile.cpp
+++ b/src/geometry/initializer/BoundaryFromVoxelFile.cpp
@@ -59,26 +59,26 @@ CellIntervalDataMap readCellIntervalsOnRoot( const std::string & geometryFile,
 
       sendBuffer << uint8_t(0); // dummy byte to make sure a message is sent even if cellIntervals is empty
 
-      for( auto ciIt = cellIntervals.begin(); ciIt != cellIntervals.end(); ++ciIt )
-         sendBuffer << ciIt->second;
+      for(const auto & cellInterval : cellIntervals)
+         sendBuffer << cellInterval.second;
 
    }
 
 
    allToRootBs.sendAll();
 
-   VoxelFileReader<uint8_t> reader( geometryFile );
+   VoxelFileReader<uint8_t> const reader( geometryFile );
    std::vector<uint8_t> data;
 
    WALBERLA_ROOT_SECTION()
    {
       // Read root cell intervals from geometry file
-      for( auto ciIt = cellIntervals.begin(); ciIt != cellIntervals.end(); ++ciIt )
+      for(const auto & cellInterval : cellIntervals)
       {
-         CellInterval shifted = ciIt->second;
+         CellInterval shifted = cellInterval.second;
          shifted.shift( -offset );
          reader.read(shifted, data);
-         result[ ciIt->first ] = std::make_pair( ciIt->second, data );
+         result[ cellInterval.first ] = std::make_pair( cellInterval.second, data );
       }
    }
 
@@ -89,7 +89,7 @@ CellIntervalDataMap readCellIntervalsOnRoot( const std::string & geometryFile,
       // only root should receive messages
       WALBERLA_ASSERT_EQUAL( MPIManager::instance()->worldRank(), 0 );
 
-      int rank = it.rank();
+      int const rank = it.rank();
       auto & recvBuffer = it.buffer();
       auto & sendBuffer = rootToAllBs.sendBuffer( rank );
 
@@ -121,11 +121,11 @@ CellIntervalDataMap readCellIntervalsOnRoot( const std::string & geometryFile,
       uint8_t dummy;
       recvBuffer >> dummy;
 
-      for( auto ciIt = cellIntervals.begin(); ciIt != cellIntervals.end(); ++ciIt )
+      for(const auto & cellInterval : cellIntervals)
       {
          WALBERLA_ASSERT( !recvBuffer.isEmpty() );
          recvBuffer >> data;
-         result[ ciIt->first ] = std::make_pair( ciIt->second, data );
+         result[ cellInterval.first ] = std::make_pair( cellInterval.second, data );
       }
 
       WALBERLA_ASSERT( recvBuffer.isEmpty() );
diff --git a/src/geometry/initializer/BoundaryFromVoxelFile.impl.h b/src/geometry/initializer/BoundaryFromVoxelFile.impl.h
index de8e99a47aeb14ff63242810653e8211a17a9079..17817eadf37662d2c42db7f9e5e4eba89e9664cd 100644
--- a/src/geometry/initializer/BoundaryFromVoxelFile.impl.h
+++ b/src/geometry/initializer/BoundaryFromVoxelFile.impl.h
@@ -48,13 +48,13 @@ void BoundaryFromVoxelFile<BoundaryHandlerT>::init( BlockStorage & blockStorage,
 
    std::map<uint8_t, BoundarySetter<BoundaryHandlerT> > flags;
 
-   for( auto configBlockIt = configBlocks.begin(); configBlockIt != configBlocks.end(); ++configBlockIt )
+   for(auto & configBlock : configBlocks)
    {
-      if( configBlockIt->getKey() == "Flag" )
+      if( configBlock.getKey() == "Flag" )
       {
-         uint8_t flag = uint8_c( static_cast<int>( configBlockIt->template getParameter<int>( "value" ) ) );
+         uint8_t const flag = uint8_c( static_cast<int>( configBlock.template getParameter<int>( "value" ) ) );
          BoundarySetter<BoundaryHandlerT> boundarySetter;
-         boundarySetter.setConfigBlock( *configBlockIt );
+         boundarySetter.setConfigBlock( configBlock );
          flags[flag] = boundarySetter;
       }
    }
@@ -74,8 +74,8 @@ void BoundaryFromVoxelFile<BoundaryHandlerT>::init( BlockStorage & blockStorage,
          if( cells.empty() )
             continue;
 
-         for( auto it = cells.begin(); it != cells.end(); ++it )
-            structuredBlockStorage_.transformGlobalToBlockLocalCell( *it, *blockIt );
+         for(auto & cell : cells)
+            structuredBlockStorage_.transformGlobalToBlockLocalCell( cell, *blockIt );
 
          setterIt->second.set( cells.begin(), cells.end() );
       }
@@ -93,7 +93,7 @@ BoundaryFromVoxelFile<BoundaryHandlerT>::getIntersectedCellIntervals( const std:
    CellInterval fileCellInterval;
    WALBERLA_ROOT_SECTION()
    {
-      VoxelFileReader <uint8_t> reader( geometryFile );
+      VoxelFileReader <uint8_t> const reader( geometryFile );
       fileCellInterval = CellInterval( cell_idx_c(0), cell_idx_c(0), cell_idx_c(0), cell_idx_c( reader.xSize() ) - 1,
          cell_idx_c( reader.ySize() ) - 1, cell_idx_c( reader.zSize() ) - 1 );
       fileCellInterval.shift(offset);
diff --git a/src/geometry/initializer/BoundarySetter.h b/src/geometry/initializer/BoundarySetter.h
index e793b505ef2c530d5856799d57753e5fc699181d..2b39e82e67ac8e02d854e63f98efb58ebe135cf4 100644
--- a/src/geometry/initializer/BoundarySetter.h
+++ b/src/geometry/initializer/BoundarySetter.h
@@ -120,7 +120,7 @@ namespace initializer {
 
       for( auto blockHandleIt = boundaryConfigBlocks.begin(); blockHandleIt != boundaryConfigBlocks.end(); )
       {
-         std::string key = blockHandleIt->getKey();
+         std::string const key = blockHandleIt->getKey();
          if ( subblocksToIgnore.find( key ) != subblocksToIgnore.end() )
             boundaryConfigBlocks.erase( blockHandleIt );
          else
diff --git a/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h b/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h
index dd5a376ee4649ed4c01a388902c624a23664afc8..046f9567b82f6883b8848230f4ba77e0bd19713e 100644
--- a/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h
+++ b/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h
@@ -90,7 +90,7 @@ namespace initializer {
 
       for( auto blockHandleIt = boundaryConfigBlocks.begin(); blockHandleIt != boundaryConfigBlocks.end(); )
       {
-         std::string key = blockHandleIt->getKey();
+         std::string const key = blockHandleIt->getKey();
          if ( subblocksToIgnore.find( key ) != subblocksToIgnore.end() )
             boundaryConfigBlocks.erase( blockHandleIt );
          else
diff --git a/src/geometry/initializer/InitializationManager.cpp b/src/geometry/initializer/InitializationManager.cpp
index 315541305854c8cfb49bb94c9883f8a72e033e7f..a5252c38e24ccf42532bf462824adfaaf96441f0 100644
--- a/src/geometry/initializer/InitializationManager.cpp
+++ b/src/geometry/initializer/InitializationManager.cpp
@@ -48,23 +48,23 @@ void InitializationManager::init( const Config::BlockHandle & blockHandle )
    Config::Blocks blocks;
    blockHandle.getBlocks(blocks);
 
-   for( auto blockIt = blocks.begin(); blockIt != blocks.end(); ++blockIt)
+   for(auto & block : blocks)
    {
-      auto foundGeometryIt = geometryRegistry_.find( blockIt->getKey() );
+      auto foundGeometryIt = geometryRegistry_.find( block.getKey() );
 
       if( foundGeometryIt == geometryRegistry_.end() )
       {
          std::ostringstream oss;
-         oss << "No Geometry for block " << blockIt->getKey() << " registered at GeometryMaster!\n"
+         oss << "No Geometry for block " << block.getKey() << " registered at GeometryMaster!\n"
              << geometryRegistry_.size() << " Geometry instances are registered" << ( geometryRegistry_.empty() ? "." : ":" );
 
-         for( auto geometryIt = geometryRegistry_.begin(); geometryIt != geometryRegistry_.end(); ++geometryIt )
-            oss <<  "\n   " << geometryIt->first.getIdentifier();
+         for(auto & geometryIt : geometryRegistry_)
+            oss <<  "\n   " << geometryIt.first.getIdentifier();
 
          WALBERLA_ABORT( oss.str() );
       }
 
-      foundGeometryIt->second->init( blockStorage_, *blockIt );
+      foundGeometryIt->second->init( blockStorage_, block );
    }
 }
 
diff --git a/src/geometry/initializer/OverlapFieldFromBody.cpp b/src/geometry/initializer/OverlapFieldFromBody.cpp
index 9452a0563c29f28670267c4913a26e4ad9e8b28d..8e19ba5c71027793d06a858647466befbea336e9 100644
--- a/src/geometry/initializer/OverlapFieldFromBody.cpp
+++ b/src/geometry/initializer/OverlapFieldFromBody.cpp
@@ -57,7 +57,7 @@ namespace initializer {
       blockHandle.getBlocks( subBlocks );
 
       if ( blockHandle.isDefined("initialFill") ) {
-         std::string initialFill = blockHandle.getParameter<std::string>("initialFill");
+         std::string const initialFill = blockHandle.getParameter<std::string>("initialFill");
          if ( initialFill == addKeyword_ )
          {
             for( auto blockIt = structuredBlockStorage_.begin(); blockIt != structuredBlockStorage_.end(); ++blockIt )
@@ -72,13 +72,12 @@ namespace initializer {
          }
       }
 
-      for ( auto it = subBlocks.begin(); it != subBlocks.end(); ++it )
+      for (auto subBlock : subBlocks)
       {
-         Config::BlockHandle subBlock = *it;
          bool addOrSubtract = true;
 
-         bool addDefined      = subBlock.isDefined( addKeyword_ );
-         bool subtractDefined = subBlock.isDefined( subtractKeyword_ );
+         bool const addDefined      = subBlock.isDefined( addKeyword_ );
+         bool const subtractDefined = subBlock.isDefined( subtractKeyword_ );
 
          if ( addDefined && subtractDefined )
             WALBERLA_ABORT( "Specify only one of " << addKeyword_ << " and " << subtractKeyword_ << "!\n"
@@ -87,9 +86,9 @@ namespace initializer {
          if ( subtractDefined )
             addOrSubtract = false;
 
-         std::string shape = subBlock.getParameter<std::string>("shape");
+         std::string const shape = subBlock.getParameter<std::string>("shape");
 
-         uint_t superSamplingDepth = subBlock.getParameter<uint_t>("superSamplingDepth", uint_t(4) );
+         uint_t const superSamplingDepth = subBlock.getParameter<uint_t>("superSamplingDepth", uint_t(4) );
 
          if      ( string_icompare( shape, "Sphere"   ) == 0 )  init ( sphereFromConfig   ( subBlock ), addOrSubtract, superSamplingDepth );
          else if ( string_icompare( shape, "Cylinder" ) == 0 )  init ( cylinderFromConfig ( subBlock ), addOrSubtract, superSamplingDepth );
diff --git a/src/geometry/initializer/OverlapFieldFromBody.h b/src/geometry/initializer/OverlapFieldFromBody.h
index 0438b85e8c545ae3158aa676cc7e41d969ac378d..e2345296bb8227c35bf7a76cb2b59a6e126d966d 100644
--- a/src/geometry/initializer/OverlapFieldFromBody.h
+++ b/src/geometry/initializer/OverlapFieldFromBody.h
@@ -169,7 +169,7 @@ namespace initializer {
                currentMidpoint[0] = firstCellMidpoint[0];
                for( cell_idx_t x = -gl; x < cell_idx_c(ff->xSize())+gl; ++x, currentMidpoint[0] += dx )
                {
-                  real_t overlap = overlapFraction( body, currentMidpoint, dxVec, superSamplingDepth );
+                  real_t const overlap = overlapFraction( body, currentMidpoint, dxVec, superSamplingDepth );
                   real_t & val = ff->get(x,y,z);
                   WALBERLA_ASSERT( val >=0 && val <= 1);
 
diff --git a/src/geometry/initializer/ScalarFieldFromGrayScaleImage.cpp b/src/geometry/initializer/ScalarFieldFromGrayScaleImage.cpp
index aafe0bb3b506dc5963c91f9a87fb374e0eee10b0..fc6bbcd65e312fab89440a0eacc4153d35fe3268 100644
--- a/src/geometry/initializer/ScalarFieldFromGrayScaleImage.cpp
+++ b/src/geometry/initializer/ScalarFieldFromGrayScaleImage.cpp
@@ -24,6 +24,7 @@
 #include "core/math/Vector3.h"
 #include "field/GhostLayerField.h"
 
+#include <algorithm>
 #include <limits>
 
 
@@ -84,19 +85,19 @@ namespace initializer {
 
       const std::string & file = block.getParameter< std::string > ( "file" );
 
-      uint_t extrusionCoordinate = block.getParameter<uint_t>( "extrusionCoordinate", 2 );
+      uint_t const extrusionCoordinate = block.getParameter<uint_t>( "extrusionCoordinate", 2 );
 
       const cell_idx_t minCellIdx = std::numeric_limits<cell_idx_t>::min();
       const cell_idx_t maxCellIdx = std::numeric_limits<cell_idx_t>::max();
 
-      cell_idx_t lowerExtrusionLimit = block.getParameter<cell_idx_t>( "lowerExtrusionLimit", minCellIdx );
-      cell_idx_t upperExtrusionLimit = block.getParameter<cell_idx_t>( "upperExtrusionLimit", maxCellIdx );
+      cell_idx_t const lowerExtrusionLimit = block.getParameter<cell_idx_t>( "lowerExtrusionLimit", minCellIdx );
+      cell_idx_t const upperExtrusionLimit = block.getParameter<cell_idx_t>( "upperExtrusionLimit", maxCellIdx );
 
-      cell_idx_t xOffset = block.getParameter<cell_idx_t>( "xOffset", 0 );
-      cell_idx_t yOffset = block.getParameter<cell_idx_t>( "yOffset", 0 );
+      cell_idx_t const xOffset = block.getParameter<cell_idx_t>( "xOffset", 0 );
+      cell_idx_t const yOffset = block.getParameter<cell_idx_t>( "yOffset", 0 );
 
 
-      GrayScaleImage img ( file );
+      GrayScaleImage const img ( file );
       if ( block.isDefined( "scaleToDomain") )
       {
          if ( xOffset != 0 || yOffset != 0 )
@@ -121,10 +122,10 @@ namespace initializer {
       // the extrusion limit can not be left at numeric_limits::min/max since
       // the blockStorage.transformGlobalToLocal would overflow
 
-      cell_idx_t maxNumberOfCells = cell_idx_c(
-                                    std::max( structuredBlockStorage_.getNumberOfXCells(),
-                                    std::max( structuredBlockStorage_.getNumberOfYCells(),
-                                              structuredBlockStorage_.getNumberOfZCells() ) ) );
+      cell_idx_t const maxNumberOfCells = cell_idx_c(
+                                    std::max( {structuredBlockStorage_.getNumberOfXCells(),
+                                    structuredBlockStorage_.getNumberOfYCells(),
+                                              structuredBlockStorage_.getNumberOfZCells() } ) );
 
       if ( upperExtrusionLimit > maxNumberOfCells )
          upperExtrusionLimit = maxNumberOfCells;
@@ -140,7 +141,7 @@ namespace initializer {
                                    xOffset+ width-1, yOffset + height-1, upperExtrusionLimit-1 );
 
 
-         cell_idx_t lowestGlobalCoord = - cell_idx_c( f->nrOfGhostLayers() );
+         cell_idx_t const lowestGlobalCoord = - cell_idx_c( f->nrOfGhostLayers() );
          if ( lowerExtrusionLimit < lowestGlobalCoord )
             lowerExtrusionLimit = lowestGlobalCoord;
 
diff --git a/src/geometry/mesh/TriangleMesh.cpp b/src/geometry/mesh/TriangleMesh.cpp
index 64c48fcffd98b169a2aef906d329d454d70ed2e8..cbfbf84701ac06ef387a176b578acf3787dba60a 100644
--- a/src/geometry/mesh/TriangleMesh.cpp
+++ b/src/geometry/mesh/TriangleMesh.cpp
@@ -232,9 +232,9 @@ size_t TriangleMesh::removeDuplicateVertices( real_t tolerance )
 
 
    // adapt the indices in the triangles
-   for(size_t i=0; i < vertexIndices_.size(); ++i) {
-      WALBERLA_ASSERT_LESS( oldToNewIndex[ vertexIndices_[i] ], vInd.size() - removedVertices);
-      vertexIndices_[i] = index_t( oldToNewIndex[ vertexIndices_[i] ] );
+   for(unsigned int & vertexIndice : vertexIndices_) {
+      WALBERLA_ASSERT_LESS( oldToNewIndex[ vertexIndice ], vInd.size() - removedVertices);
+      vertexIndice = index_t( oldToNewIndex[ vertexIndice ] );
    }
 
    return removedVertices;
@@ -293,9 +293,9 @@ void TriangleMesh::split( vector<TriangleMesh>& meshes ) const
 
    // split vertices by triangle connections
    set< vector< TriangleMeshNode* > > ssnode;
-   for( auto nit = nodes.begin(); nit != nodes.end(); ++nit )
+   for(auto & nit : nodes)
    {
-      TriangleMeshNode* node = nit->second;
+      TriangleMeshNode* node = nit.second;
       if( node->used )
          continue;
 
@@ -325,9 +325,8 @@ void TriangleMesh::split( vector<TriangleMesh>& meshes ) const
    size_t index = size_t(0u);
    for( auto srcIt = ssnode.begin(); srcIt != ssnode.end(); ++srcIt, ++index)
    {
-      for( auto it = srcIt->begin(); it != srcIt->end(); ++it )
+      for(auto node : *srcIt)
       {
-         TriangleMeshNode* node = *it;
          index_t vIndex;
          if( hasVertexColors() )
             vIndex = meshes[index].addVertex( vertices_[node->vOld], vertexColors_[node->vOld] );
@@ -336,11 +335,11 @@ void TriangleMesh::split( vector<TriangleMesh>& meshes ) const
          vid[index][node->vOld] = vIndex;
 
          if( hasNormalIndices() ){
-            for( auto nOld = node->nOld.begin(); nOld != node->nOld.end(); ++nOld ){
-               if( nid[index].find(*nOld) != nid[index].end() )
+            for(unsigned int  const& nOld : node->nOld){
+               if( nid[index].find(nOld) != nid[index].end() )
                   continue;
-               const index_t nIndex = meshes[index].addVertexNormal( vertexNormals_[*nOld] );
-               nid[index][*nOld] = nIndex;
+               const index_t nIndex = meshes[index].addVertexNormal( vertexNormals_[nOld] );
+               nid[index][nOld] = nIndex;
             }
          } else if( hasVertexNormals() ){
             const index_t nIndex = meshes[index].addVertexNormal( vertexNormals_[node->vOld] );
@@ -377,9 +376,9 @@ void TriangleMesh::split( vector<TriangleMesh>& meshes ) const
    }
 
    // clear memory
-   for( auto it = nodes.begin(); it != nodes.end(); ++it )
+   for(auto & node : nodes)
    {
-      delete it->second;
+      delete node.second;
    }
 }
 
@@ -396,8 +395,8 @@ void TriangleMesh::split( vector<TriangleMesh>& meshes ) const
 //*********************************************************************************************************************/
 void TriangleMesh::merge(const TriangleMesh & other, const Vector3<real_t> & offset)
 {
-   index_t oldNumVertices      = index_c( vertices_.size() );
-   index_t oldNumVertexNormals = index_c( vertexNormals_.size() );
+   index_t const oldNumVertices      = index_c( vertices_.size() );
+   index_t const oldNumVertexNormals = index_c( vertexNormals_.size() );
 
    // Add vertices
    for(index_t i=0; i < other.getNumVertices(); ++i) {
@@ -411,11 +410,11 @@ void TriangleMesh::merge(const TriangleMesh & other, const Vector3<real_t> & off
    std::copy(other.vertexColors_.begin(),  other.vertexColors_.end(),  std::back_inserter(vertexColors_)  );
 
    // Add faces
-   for( auto it = other.vertexIndices_.begin(); it != other.vertexIndices_.end(); ++it )
-      vertexIndices_.push_back( index_c( *it + oldNumVertices ) );
+   for(unsigned int const vertexIndice : other.vertexIndices_)
+      vertexIndices_.push_back( index_c( vertexIndice + oldNumVertices ) );
 
-   for( auto it = other.normalIndices_.begin(); it != other.normalIndices_.end(); ++it )
-      normalIndices_.push_back( index_c( *it + oldNumVertexNormals ) );
+   for(unsigned int const normalIndice : other.normalIndices_)
+      normalIndices_.push_back( index_c( normalIndice + oldNumVertexNormals ) );
 }
 
 math::AABB TriangleMesh::getAABB() const
@@ -424,33 +423,33 @@ math::AABB TriangleMesh::getAABB() const
    if( vertices_.empty() )
       WALBERLA_ABORT( "You are trying to compute the bounding box of an empty mesh!" );
 
-   return math::AABB( vertices_.begin(), vertices_.end() );
+   return { vertices_.begin(), vertices_.end() };
 }
 
 void TriangleMesh::translate( const Vector3<real_t> & offset )
 {
-   for( auto it = vertices_.begin(); it != vertices_.end(); ++it )
-      *it += offset;
+   for(auto & vertice : vertices_)
+      vertice += offset;
 }
 
 void TriangleMesh::scale( const Vector3<real_t> & scaleFactors )
 {
-   for( auto it = vertices_.begin(); it != vertices_.end(); ++it )
+   for(auto & vertice : vertices_)
    {
-      (*it)[0] *= scaleFactors[0];
-      (*it)[1] *= scaleFactors[1];
-      (*it)[2] *= scaleFactors[2];
+      vertice[0] *= scaleFactors[0];
+      vertice[1] *= scaleFactors[1];
+      vertice[2] *= scaleFactors[2];
    }
 }
 
 void TriangleMesh::exchangeAxes( uint_t xAxisId, uint_t yAxisId, uint_t zAxisId )
 {
-   for( auto it = vertices_.begin(); it != vertices_.end(); ++it )
+   for(auto & vertice : vertices_)
    {
-      vertex_t copy = *it;
-      (*it)[0] = copy[xAxisId];
-      (*it)[1] = copy[yAxisId];
-      (*it)[2] = copy[zAxisId];
+      vertex_t copy = vertice;
+      vertice[0] = copy[xAxisId];
+      vertice[1] = copy[yAxisId];
+      vertice[2] = copy[zAxisId];
    }
 }
 
diff --git a/src/geometry/mesh/TriangleMeshIO.cpp b/src/geometry/mesh/TriangleMeshIO.cpp
index cb885950972a8c2621a17ecf897a0187c66385f3..fc52811e21056d268a6f5403611dfab0b7e681c6 100644
--- a/src/geometry/mesh/TriangleMeshIO.cpp
+++ b/src/geometry/mesh/TriangleMeshIO.cpp
@@ -31,6 +31,7 @@
 #include "core/Regex.h"
 #include "core/StringUtility.h"
 
+#include <algorithm>
 #include <cmath>
 #include <fstream>
 #include <map>
@@ -345,13 +346,13 @@ namespace geometry {
       using std::string;
       using std::stringstream;
 
-      std::string source( (std::istreambuf_iterator<char>( is ) ), std::istreambuf_iterator<char>( ) );
+      std::string const source( (std::istreambuf_iterator<char>( is ) ), std::istreambuf_iterator<char>( ) );
 
       // replace multiline comments: /\\*.*?\\*/
       // replace single line comments //.*?\n
       // replace chars: < > , \ n \t
-      walberla::regex r( "/\\*.*?\\*/|//.*?\n|<|>|,|\n|\t" );
-      std::string stripped = walberla::regex_replace( source , r , " " ) ;
+      walberla::regex const r( "/\\*.*?\\*/|//.*?\n|<|>|,|\n|\t" );
+      std::string const stripped = walberla::regex_replace( source , r , " " ) ;
 
       TriangleMesh::index_t faceOffset = 0u;
       if( clear )
@@ -504,7 +505,7 @@ namespace geometry {
       }
 
       std::vector<TriangleMesh> meshVec( 1u + mesh.getNumVertices() / itemsPerMesh );
-      bool hasVertexNormals = mesh.hasVertexNormals();
+      bool const hasVertexNormals = mesh.hasVertexNormals();
 
       size_t j;
 
@@ -516,20 +517,20 @@ namespace geometry {
       }
 
       for( size_t i = 0; i < mesh.getNumTriangles(); ++i ){
-         TriangleMesh::index_t ix = mesh.getVertexIndex( i, 0 );
-         TriangleMesh::index_t iy = mesh.getVertexIndex( i, 1 );
-         TriangleMesh::index_t iz = mesh.getVertexIndex( i, 2 );
+         TriangleMesh::index_t const ix = mesh.getVertexIndex( i, 0 );
+         TriangleMesh::index_t const iy = mesh.getVertexIndex( i, 1 );
+         TriangleMesh::index_t const iz = mesh.getVertexIndex( i, 2 );
 
-         size_t jx = ix / itemsPerMesh;
-         size_t jy = iy / itemsPerMesh;
-         size_t jz = iz / itemsPerMesh;
+         size_t const jx = ix / itemsPerMesh;
+         size_t const jy = iy / itemsPerMesh;
+         size_t const jz = iz / itemsPerMesh;
 
          TriangleMesh::index_t nix = uint32_c( ix % itemsPerMesh );
          TriangleMesh::index_t niy = uint32_c( iy % itemsPerMesh );
          TriangleMesh::index_t niz = uint32_c( iz % itemsPerMesh );
 
          if ( jx != jy || jy != jz ){
-            j = std::max( std::max(jx, jy), jz );
+            j = std::max( {jx, jy, jz} );
             if( jx < j ){
                nix = meshVec[j].addVertex( mesh.getVertex(ix) );
                if( hasVertexNormals )
@@ -618,8 +619,8 @@ namespace geometry {
 
    void writeMeshOff( std::ostream & os, const TriangleMesh & mesh )
    {
-      TriangleMesh::index_t numVertices = mesh.getNumVertices();
-      size_t                numFaces    = mesh.getNumTriangles();
+      TriangleMesh::index_t const numVertices = mesh.getNumVertices();
+      size_t                const numFaces    = mesh.getNumTriangles();
 
       os << "OFF\n";
       os << numVertices << ' ' << mesh.getNumTriangles() << " 0\n"; // Number of edges is unknown, we put 0
@@ -651,9 +652,9 @@ namespace geometry {
          << "        <DataArray type=\"Float32\" NumberOfComponents=\"3\" format=\"ascii\">\n";
 
       os << "          ";
-      for( auto it = mesh.getVertices().begin(); it != mesh.getVertices().end(); ++it )
+      for(const auto & it : mesh.getVertices())
       {
-         os << (*it)[0] << ' ' << (*it)[1] << ' ' << (*it)[2] << ' ';
+         os << it[0] << ' ' << it[1] << ' ' << it[2] << ' ';
       }
       os  << '\n';
 
@@ -664,9 +665,9 @@ namespace geometry {
 
       os << "        <DataArray type=\"Int32\" Name=\"connectivity\" format=\"ascii\">\n";
       os << "          ";
-      for( auto it = mesh.getVertexIndices().begin(); it != mesh.getVertexIndices().end(); ++it )
+      for(unsigned int const it : mesh.getVertexIndices())
       {
-         os << *it << ' ';
+         os << it << ' ';
       }
       os << '\n';
       os << "        </DataArray>\n";
@@ -692,11 +693,11 @@ namespace geometry {
       {
          os << "        <DataArray type=\"UInt8\" Name=\"vertexColors\" NumberOfComponents=\"3\" format=\"ascii\">\n";
          os << "          ";
-         for( auto it = mesh.getVertexColors().begin(); it != mesh.getVertexColors().end(); ++it )
+         for(auto it : mesh.getVertexColors())
          {
-            os << std::lround( (*it)[0] * 255.0f ) << ' '
-               << std::lround( (*it)[1] * 255.0f ) << ' '
-               << std::lround( (*it)[2] * 255.0f ) << ' ';
+            os << std::lround( it[0] * 255.0f ) << ' '
+               << std::lround( it[1] * 255.0f ) << ' '
+               << std::lround( it[2] * 255.0f ) << ' ';
          }
          os << "        </DataArray>\n";
       }
@@ -705,9 +706,9 @@ namespace geometry {
       {
          os << "        <DataArray type=\"Float32\" Name=\"vertexNormals\" NumberOfComponents=\"3\" format=\"ascii\">\n";
          os << "          ";
-         for( auto it = mesh.getVertexNormals().begin(); it != mesh.getVertexNormals().end(); ++it )
+         for(const auto & it : mesh.getVertexNormals())
          {
-            os << (*it)[0] << ' ' << (*it)[1] << ' ' << (*it)[2] << ' ';
+            os << it[0] << ' ' << it[1] << ' ' << it[2] << ' ';
          }
          os << "        </DataArray>\n";
       }
diff --git a/src/geometry/structured/BasicVoxelFileReader.impl.h b/src/geometry/structured/BasicVoxelFileReader.impl.h
index 7c02ed1f8717400273c34bde8f4fb54137e20628..895cf60cd352d19838cf82421ece27c3d43f9d73 100644
--- a/src/geometry/structured/BasicVoxelFileReader.impl.h
+++ b/src/geometry/structured/BasicVoxelFileReader.impl.h
@@ -185,13 +185,13 @@ void BasicVoxelFileReader<T>::open( const std::string & _filename )
    if( filestream_.fail() || filestream_.bad() )
       throw std::runtime_error("I/O Error while reading file \"" + _filename + "\"!");
 
-   std::streampos dataEnd = filestream_.tellg();
+   std::streampos const dataEnd = filestream_.tellg();
    if( filestream_.fail() || filestream_.bad() || dataEnd == std::streampos(-1) )
       throw std::runtime_error("I/O Error while reading file \"" + _filename + "\"!");
 
 
    assert(dataBegin_ <= dataEnd);
-   std::size_t rawDataLengthBytes = static_cast<std::size_t>( dataEnd - dataBegin_ );
+   std::size_t const rawDataLengthBytes = static_cast<std::size_t>( dataEnd - dataBegin_ );
    if( rawDataLengthBytes % sizeof(T) != 0 )
    {
       std::stringstream ss;
@@ -200,7 +200,7 @@ void BasicVoxelFileReader<T>::open( const std::string & _filename )
       throw std::runtime_error(ss.str());
    }
    assert(rawDataLengthBytes % sizeof(T) == 0);
-   std::size_t rawDataLength = rawDataLengthBytes / sizeof(T);
+   std::size_t const rawDataLength = rawDataLengthBytes / sizeof(T);
    if( rawDataLength != numCells() )
    {
       std::stringstream ss;
diff --git a/src/geometry/structured/BinaryRawFile.h b/src/geometry/structured/BinaryRawFile.h
index 2c0421783788400c09a9e322d763214ceadff088..b19945ceb36ad325ac92d449d417c61c315b5545 100644
--- a/src/geometry/structured/BinaryRawFile.h
+++ b/src/geometry/structured/BinaryRawFile.h
@@ -159,9 +159,9 @@ bool BinaryRawFileInterpolator::get( const real_t x, const real_t y, const real_
 
 bool BinaryRawFileInterpolator::getNearestNeighbor( const real_t x, const real_t y, const real_t z ) const
 {
-   uint_t xInt = uint_c( (x - aabb_.xMin()) / aabb_.xSize() * real_t( binaryRawFile_.size()[0] ) + real_t( 0.5 ) );
-   uint_t yInt = uint_c( (y - aabb_.yMin()) / aabb_.ySize() * real_t( binaryRawFile_.size()[1] ) + real_t( 0.5 ) );
-   uint_t zInt = uint_c( (z - aabb_.zMin()) / aabb_.zSize() * real_t( binaryRawFile_.size()[2] ) + real_t( 0.5 ) );
+   uint_t const xInt = uint_c( (x - aabb_.xMin()) / aabb_.xSize() * real_t( binaryRawFile_.size()[0] ) + real_t( 0.5 ) );
+   uint_t const yInt = uint_c( (y - aabb_.yMin()) / aabb_.ySize() * real_t( binaryRawFile_.size()[1] ) + real_t( 0.5 ) );
+   uint_t const zInt = uint_c( (z - aabb_.zMin()) / aabb_.zSize() * real_t( binaryRawFile_.size()[2] ) + real_t( 0.5 ) );
 
    return binaryRawFile_.get( xInt, yInt, zInt );
 }
diff --git a/src/geometry/structured/GrayScaleImage.cpp b/src/geometry/structured/GrayScaleImage.cpp
index edb2cb2cfa048f771d261a0aedf87dad07613b16..d27852086170f53d1c9a2488844e5940d70d36af 100644
--- a/src/geometry/structured/GrayScaleImage.cpp
+++ b/src/geometry/structured/GrayScaleImage.cpp
@@ -40,7 +40,7 @@ namespace geometry   {
    {
       unsigned int tmpWidth;
       unsigned int tmpHeight;
-      unsigned int error = lodepng::decode( image_, tmpWidth, tmpHeight, pngFilename, LCT_GREY, 8 );
+      unsigned int const error = lodepng::decode( image_, tmpWidth, tmpHeight, pngFilename, LCT_GREY, 8 );
       size_[0] = tmpWidth;
       size_[1] = tmpHeight;
 
@@ -50,7 +50,7 @@ namespace geometry   {
 
    void GrayScaleImage::save( const std::string & pngFilename )
    {
-      uint32_t error = lodepng::encode( pngFilename, image_,
+      uint32_t const error = lodepng::encode( pngFilename, image_,
                                         uint32_c( size_[0] ), uint32_c( size_[1] ),
                                         LCT_GREY, 8 );
 
@@ -87,18 +87,18 @@ namespace geometry   {
 
       if ( bilinear )
       {
-         real_t scaleX = real_c( size_[0]-1 ) / real_c( newWidth );
-         real_t scaleY = real_c( size_[1]-1 ) / real_c( newHeight);
+         real_t const scaleX = real_c( size_[0]-1 ) / real_c( newWidth );
+         real_t const scaleY = real_c( size_[1]-1 ) / real_c( newHeight);
 
          for( cell_idx_t y = 0; y < cell_idx_c( newHeight ); ++y )
             for( cell_idx_t x = 0; x < cell_idx_c( newWidth ); ++x )
             {
-               real_t oldX = real_c(x) * scaleX;
-               real_t oldY = real_c(y) * scaleY;
-               cell_idx_t oldXi = cell_idx_c( oldX );
-               cell_idx_t oldYi = cell_idx_c( oldY );
-               real_t xDiff = oldX - real_c(oldXi);
-               real_t yDiff = oldY - real_c(oldYi);
+               real_t const oldX = real_c(x) * scaleX;
+               real_t const oldY = real_c(y) * scaleY;
+               cell_idx_t const oldXi = cell_idx_c( oldX );
+               cell_idx_t const oldYi = cell_idx_c( oldY );
+               real_t const xDiff = oldX - real_c(oldXi);
+               real_t const yDiff = oldY - real_c(oldYi);
 
                // bilinear interpolation
 
@@ -112,16 +112,16 @@ namespace geometry   {
       }
       else
       {
-         real_t scaleX = real_c( size_[0] ) / real_c( newWidth );
-         real_t scaleY = real_c( size_[1] ) / real_c( newHeight);
+         real_t const scaleX = real_c( size_[0] ) / real_c( newWidth );
+         real_t const scaleY = real_c( size_[1] ) / real_c( newHeight);
 
          for( cell_idx_t y = 0; y < cell_idx_c( newHeight ); ++y )
             for( cell_idx_t x = 0; x < cell_idx_c( newWidth ); ++x )
             {
-               real_t oldX = real_c(x) * scaleX;
-               real_t oldY = real_c(y) * scaleY;
-               cell_idx_t oldXi = cell_idx_c( oldX );
-               cell_idx_t oldYi = cell_idx_c( oldY );
+               real_t const oldX = real_c(x) * scaleX;
+               real_t const oldY = real_c(y) * scaleY;
+               cell_idx_t const oldXi = cell_idx_c( oldX );
+               cell_idx_t const oldYi = cell_idx_c( oldY );
 
                resizedImage.getElement( x, y ) = getElement( oldXi, oldYi );
             }
diff --git a/src/geometry/structured/GrayScaleImage.h b/src/geometry/structured/GrayScaleImage.h
index 43e39359b3ce578e7114de1dd3b6f9e69db8879b..f8594ab23751bfd53428bcfe71001e550257cc21 100644
--- a/src/geometry/structured/GrayScaleImage.h
+++ b/src/geometry/structured/GrayScaleImage.h
@@ -24,6 +24,7 @@
 #include "core/DataTypes.h"
 #include "core/debug/Debug.h"
 
+#include <array>
 #include <string>
 #include <vector>
 
@@ -72,7 +73,7 @@ namespace geometry   {
    protected:
       GrayScaleImage() = default;
 
-      uint_t size_[2];                   //< 0=width,  1=height
+      std::array<uint_t, 2> size_;                   //< 0=width,  1=height
       std::vector<unsigned char> image_; //< raw pixels
    };
 
diff --git a/src/geometry/structured/RGBAImage.cpp b/src/geometry/structured/RGBAImage.cpp
index 159c252ff2b56844cf7af4399fe1113f14607752..747163adc2c264b6597a0c562882432d83f7f3f6 100644
--- a/src/geometry/structured/RGBAImage.cpp
+++ b/src/geometry/structured/RGBAImage.cpp
@@ -35,11 +35,11 @@ namespace geometry   {
 
 
    bool RGBAImage::pixel_t::operator< ( const pixel_t & o ) const {
-      return std::lexicographical_compare(   values,   values+4, o.values, o.values+4 );
+      return std::lexicographical_compare(   values.begin(),   values.end(), o.values.begin(), o.values.end() );
    }
 
    bool RGBAImage::pixel_t::operator== ( const pixel_t & o ) const {
-      return std::equal(   values,   values+4, o.values );
+      return std::equal(   values.begin(),   values.end(), o.values.begin() );
    }
 
 
@@ -54,7 +54,7 @@ namespace geometry   {
    {
       unsigned int tmpWidth;
       unsigned int tmpHeight;
-      unsigned int error = lodepng::decode( image_, tmpWidth, tmpHeight, pngFilename, LCT_RGBA, 8 );
+      unsigned int const error = lodepng::decode( image_, tmpWidth, tmpHeight, pngFilename, LCT_RGBA, 8 );
       size_[0] = tmpWidth;
       size_[1] = tmpHeight;
 
@@ -64,7 +64,7 @@ namespace geometry   {
 
    void RGBAImage::save( const std::string & pngFilename )
    {
-      uint32_t error = lodepng::encode( pngFilename, image_,
+      uint32_t const error = lodepng::encode( pngFilename, image_,
                                         uint32_c( size_[0] ), uint32_c( size_[1] ),
                                         LCT_RGBA, 8 );
 
@@ -105,19 +105,19 @@ namespace geometry   {
 
       if ( bilinear )
       {
-         real_t scaleX = real_c( size_[0] - 1 ) / real_c( newWidth );
-         real_t scaleY = real_c( size_[1] - 1 ) / real_c( newHeight);
+         real_t const scaleX = real_c( size_[0] - 1 ) / real_c( newWidth );
+         real_t const scaleY = real_c( size_[1] - 1 ) / real_c( newHeight);
 
          for( cell_idx_t y = 0; y < cell_idx_c( newHeight ); ++y )
             for( cell_idx_t x = 0; x < cell_idx_c( newWidth ); ++x )
                for( int c = 0; c < 4; ++c )
                {
-                  real_t oldX = real_c(x) * scaleX;
-                  real_t oldY = real_c(y) * scaleY;
-                  cell_idx_t oldXi = cell_idx_c( oldX );
-                  cell_idx_t oldYi = cell_idx_c( oldY );
-                  real_t xDiff = oldX - real_c(oldXi);
-                  real_t yDiff = oldY - real_c(oldYi);
+                  real_t const oldX = real_c(x) * scaleX;
+                  real_t const oldY = real_c(y) * scaleY;
+                  cell_idx_t const oldXi = cell_idx_c( oldX );
+                  cell_idx_t const oldYi = cell_idx_c( oldY );
+                  real_t const xDiff = oldX - real_c(oldXi);
+                  real_t const yDiff = oldY - real_c(oldYi);
 
                   // bilinear interpolation
 
@@ -131,17 +131,17 @@ namespace geometry   {
       }
       else
       {
-         real_t scaleX = real_c( size_[0] ) / real_c( newWidth );
-         real_t scaleY = real_c( size_[1] ) / real_c( newHeight);
+         real_t const scaleX = real_c( size_[0] ) / real_c( newWidth );
+         real_t const scaleY = real_c( size_[1] ) / real_c( newHeight);
 
          for( cell_idx_t y = 0; y < cell_idx_c( newHeight ); ++y )
             for( cell_idx_t x = 0; x < cell_idx_c( newWidth ); ++x )
                for( int c = 0; c < 4; ++c )
                {
-                  real_t oldX = real_c(x) * scaleX;
-                  real_t oldY = real_c(y) * scaleY;
-                  cell_idx_t oldXi = cell_idx_c( oldX );
-                  cell_idx_t oldYi = cell_idx_c( oldY );
+                  real_t const oldX = real_c(x) * scaleX;
+                  real_t const oldY = real_c(y) * scaleY;
+                  cell_idx_t const oldXi = cell_idx_c( oldX );
+                  cell_idx_t const oldYi = cell_idx_c( oldY );
                   resizedImage.getElement( x, y, Channel(c) ) = getElement( oldXi, oldYi, Channel(c) );
                }
       }
@@ -160,7 +160,7 @@ namespace geometry   {
 
       for( uint_t i=0; i < 4 && i < value.size() / 2; ++i)
       {
-         std::string hexPair = value.substr( i*2, 2 );
+         std::string const hexPair = value.substr( i*2, 2 );
          std::stringstream ss ( hexPair );
          int tmp;
          ss >> std::hex >> tmp;
diff --git a/src/geometry/structured/RGBAImage.h b/src/geometry/structured/RGBAImage.h
index 4e2871659e215f6e2e8ab60cb0637d23b861f9b8..a34fae29b306c796dbbf1a45890fbdf93d214832 100644
--- a/src/geometry/structured/RGBAImage.h
+++ b/src/geometry/structured/RGBAImage.h
@@ -24,6 +24,7 @@
 #include "core/DataTypes.h"
 #include "core/debug/Debug.h"
 
+#include <array>
 #include <string>
 #include <vector>
 
@@ -63,7 +64,7 @@ namespace geometry   {
          union
          {
             RGBAColor color;
-            unsigned char values[4];
+            std::array<unsigned char, 4> values;
             uint32_t value;
          };
 
@@ -101,7 +102,7 @@ namespace geometry   {
    protected:
       RGBAImage() = default;
 
-      uint_t size_[2];                   //< 0=width,  1=height
+      std::array<uint_t, 2> size_;                   //< 0=width,  1=height
       std::vector<unsigned char> image_; //< raw pixels
    };
 
diff --git a/src/geometry/structured/VoxelFileReader.impl.h b/src/geometry/structured/VoxelFileReader.impl.h
index 8f64c77caff2b58724179f58d47ccec89519689e..0fdc05db7f03585aab4f7dcffd64b6c940dccafd 100644
--- a/src/geometry/structured/VoxelFileReader.impl.h
+++ b/src/geometry/structured/VoxelFileReader.impl.h
@@ -329,12 +329,12 @@ CellAABB toCellAABB( const CellInterval & cellInterval )
     WALBERLA_ASSERT( !cellInterval.empty(), cellInterval );
     WALBERLA_ASSERT( cellInterval.positiveIndicesOnly(), cellInterval );
 
-    return CellAABB ( numeric_cast<size_t>( cellInterval.xMin() ),
+    return { numeric_cast<size_t>( cellInterval.xMin() ),
                       numeric_cast<size_t>( cellInterval.yMin() ),
                       numeric_cast<size_t>( cellInterval.zMin() ),
                       numeric_cast<size_t>( cellInterval.xMax() ),
                       numeric_cast<size_t>( cellInterval.yMax() ),
-                      numeric_cast<size_t>( cellInterval.zMax() ) );
+                      numeric_cast<size_t>( cellInterval.zMax() ) };
 }
 
 } // namespace geometry
diff --git a/src/gpu/AddGPUFieldToStorage.impl.h b/src/gpu/AddGPUFieldToStorage.impl.h
index 610b853265cf7b94ad5be81bb1bd9444ce2b008b..e38041a6a5f1a56b48c787dfea52777d07758f42 100644
--- a/src/gpu/AddGPUFieldToStorage.impl.h
+++ b/src/gpu/AddGPUFieldToStorage.impl.h
@@ -52,7 +52,7 @@ namespace gpu
                                   bool usePitchedMem
                                 )
       {
-         typedef GPUField< typename Field_T::value_type> GPUField_T;
+         using GPUField_T = GPUField<typename Field_T::value_type>;
 
          const Field_T * f = block->getData<Field_T>( cpuFieldID );
          auto gpuField = new GPUField_T( f->xSize(), f->ySize(), f->zSize(), f->fSize(),
@@ -85,7 +85,7 @@ namespace gpu
                                      const std::string & identifier,
                                      bool usePitchedMem )
    {
-      auto func = std::bind ( internal::createGPUFieldFromCPUField<Field_T>, std::placeholders::_1, std::placeholders::_2, cpuFieldID, usePitchedMem );
+      auto func = [cpuFieldID, usePitchedMem](auto && PH1, auto && PH2) { return internal::createGPUFieldFromCPUField<Field_T>(std::forward<decltype(PH1)>(PH1), std::forward<decltype(PH2)>(PH2), cpuFieldID, usePitchedMem); };
       return bs->addStructuredBlockData< GPUField<typename Field_T::value_type> >( func, identifier );
    }
 
diff --git a/src/gpu/DeviceWrapper.h b/src/gpu/DeviceWrapper.h
index b5270a57c52b9b52092e74340cd185e358a9e00c..a82932156c52b9a7635deabca0166d94e1446118 100644
--- a/src/gpu/DeviceWrapper.h
+++ b/src/gpu/DeviceWrapper.h
@@ -74,6 +74,8 @@ namespace gpustubs {
    //NOLINTEND(bugprone-reserved-identifier)
 #endif
 
+//NOLINTBEGIN
+
 using gpuError_t = int;
 const gpuError_t gpuSuccess = 0;
 
@@ -290,6 +292,8 @@ inline gpuError_t gpuLaunchHostFunc(gpuStream_t /*stream*/, gpuHostFn_t /*fn*/,
 
 #undef WALBERLA_DEVICE_FUNCTION_ERROR
 
+//NOLINTEND
+
 } // namespace gpustubs
 using namespace gpustubs;
 
diff --git a/src/gpu/FieldCopy.h b/src/gpu/FieldCopy.h
index 6895661ecac9f983c2a08f16fad5bf991908dfc3..1880357037c74a59f51aef2654c27ae307911999 100644
--- a/src/gpu/FieldCopy.h
+++ b/src/gpu/FieldCopy.h
@@ -52,7 +52,7 @@ namespace gpu
    std::function<void()> fieldCpyFunctor( const shared_ptr< StructuredBlockStorage > & blocks,
                                             BlockDataID dstID, ConstBlockDataID srcID )
    {
-      return std::bind( fieldCpy<DstType,SrcType>, blocks, dstID, srcID );
+      return [blocks, dstID, srcID] { fieldCpy<DstType,SrcType>(blocks, dstID, srcID); };
    }
 
 
@@ -105,7 +105,7 @@ namespace gpu
 
          if (dst.layout() != src.layout()) { WALBERLA_ABORT("Cannot copy fields with different layout") }
 
-         bool canCopy =
+         bool const canCopy =
             (src.layout() == fzyx && dst.fAllocSize() == src.fAllocSize() && dst.zAllocSize() == src.zAllocSize() &&
              dst.yAllocSize() == src.yAllocSize() && dst.xSize() == src.xSize()) ||
             (src.layout() == zyxf && dst.zAllocSize() == src.zAllocSize() && dst.yAllocSize() == src.yAllocSize() &&
@@ -154,7 +154,7 @@ namespace gpu
 
          if (dst.layout() != src.layout()) { WALBERLA_ABORT("Cannot copy fields with different layout") }
 
-         bool canCopy =
+         bool const canCopy =
             (src.layout() == fzyx && dst.fAllocSize() == src.fAllocSize() && dst.zAllocSize() == src.zAllocSize() &&
              dst.yAllocSize() == src.yAllocSize() && dst.xSize() == src.xSize()) ||
             (src.layout() == zyxf && dst.zAllocSize() == src.zAllocSize() && dst.yAllocSize() == src.yAllocSize() &&
diff --git a/src/gpu/FieldIndexing3D.impl.h b/src/gpu/FieldIndexing3D.impl.h
index 5aa027872d08d73da4315115c63c32344ba32702..d2c4962c46d6bf008a49e4232b11635b694b8c00 100644
--- a/src/gpu/FieldIndexing3D.impl.h
+++ b/src/gpu/FieldIndexing3D.impl.h
@@ -38,7 +38,7 @@ namespace gpu
 inline unsigned int iDivUp( unsigned int a, unsigned int b ) { return ( a + b - 1 ) / b; }
 
 
-dim3 FieldIndexing3DBase::preferredBlockDim_( 32, 2, 2 );
+inline dim3 FieldIndexing3DBase::preferredBlockDim_( 32, 2, 2 );
 
 
 template< typename T>
@@ -88,20 +88,20 @@ FieldIndexing3D<T> FieldIndexing3D<T>::interval( const GPUField<T> & f, const Ce
    char * data = (char*)f.pitchedPtr().ptr;
 
    // position data according to ci
-   cell_idx_t gl = cell_idx_c( f.nrOfGhostLayers() );
+   cell_idx_t const gl = cell_idx_c( f.nrOfGhostLayers() );
    data += ( ci.xMin() + gl ) * cell_idx_c(xOffset) +
            ( ci.yMin() + gl ) * cell_idx_c(yOffset) +
            ( ci.zMin() + gl ) * cell_idx_c(zOffset);
 
 
-   dim3 idxDim( (unsigned int)ci.xSize(), (unsigned int)ci.ySize(), (unsigned int)ci.zSize() );
+   dim3 const idxDim( (unsigned int)ci.xSize(), (unsigned int)ci.ySize(), (unsigned int)ci.zSize() );
    unsigned int const bx = std::min( preferredBlockDim_.x, idxDim.x );
    unsigned int const by = std::min( preferredBlockDim_.y, idxDim.y );
    unsigned int const bz = std::min( preferredBlockDim_.z, idxDim.z );
-   dim3 gridDim( iDivUp( idxDim.x, bx ),
+   dim3 const gridDim( iDivUp( idxDim.x, bx ),
                  iDivUp( idxDim.y, by ),
                  iDivUp( idxDim.z, bz ) );
-   dim3 blockDim( bx, by, bz );
+   dim3 const blockDim( bx, by, bz );
 
    return FieldIndexing3D<T>( f, blockDim, gridDim,
                               FieldAccessor3D<T>( data, xOffset, yOffset, zOffset, fOffset,
@@ -111,7 +111,7 @@ FieldIndexing3D<T> FieldIndexing3D<T>::interval( const GPUField<T> & f, const Ce
 template< typename T>
 FieldIndexing3D<T> FieldIndexing3D<T>::xyz ( const GPUField<T> & f )
 {
-   CellInterval ci( 0,0,0,
+   CellInterval const ci( 0,0,0,
                     cell_idx_c( f.xSize() ) - 1,
                     cell_idx_c( f.ySize() ) - 1,
                     cell_idx_c( f.zSize() ) - 1 );
diff --git a/src/gpu/GPUField.h b/src/gpu/GPUField.h
index 7d004c76203060c5fb77c350f306007a091ca0c9..c8ed2853535f5d9fa0fae0fd39d5d2537bbbe09f 100755
--- a/src/gpu/GPUField.h
+++ b/src/gpu/GPUField.h
@@ -65,7 +65,7 @@ namespace gpu
    class GPUField
    {
    public:
-      typedef T value_type;
+      using value_type = T;
 
       GPUField( uint_t _xSize, uint_t _ySize, uint_t _zSize, uint_t _fSize,
                 uint_t _nrOfGhostLayers, const Layout & _layout = fzyx, bool usePitchedMem = true );
@@ -170,7 +170,7 @@ namespace gpu
       uint_t         fAllocSize_;
       Layout         layout_;
       bool           usePitchedMem_;
-      uint8_t        timestepCounter_;
+      uint8_t        timestepCounter_ = uint8_c(0);
    };
 
 
diff --git a/src/gpu/GPUField.impl.h b/src/gpu/GPUField.impl.h
index dd42d088c77a3dc2c5eecddba4ae1895e31df5b3..c982ea7d555757e4dc0a6045731c79bd3660ed9e 100644
--- a/src/gpu/GPUField.impl.h
+++ b/src/gpu/GPUField.impl.h
@@ -124,7 +124,7 @@ template<typename T>
 void GPUField<T>::getGhostRegion(stencil::Direction d, CellInterval & ci,
                                  cell_idx_t thickness, bool fullSlice ) const
 {
-   const cell_idx_t sizeArr [] = { cell_idx_c( xSize() ),
+   const std::array<cell_idx_t, 3> sizeArr = { cell_idx_c( xSize() ),
                                    cell_idx_c( ySize() ),
                                    cell_idx_c( zSize() )};
 
@@ -170,7 +170,7 @@ void GPUField<T>::getSlice(stencil::Direction d, CellInterval & ci,
 {
    WALBERLA_ASSERT_GREATER( thickness, 0 )
 
-   const cell_idx_t sizeArr [] = { cell_idx_c( xSize() ),
+   const std::array<cell_idx_t, 3> sizeArr = { cell_idx_c( xSize() ),
                                    cell_idx_c( ySize() ),
                                    cell_idx_c( zSize() ) };
 
diff --git a/src/gpu/Kernel.h b/src/gpu/Kernel.h
index 59366e5bc6d2bcdbd990cfd8d968a07121efb904..4db49561f8c5cfadc516f87b7adf1fb250502250 100644
--- a/src/gpu/Kernel.h
+++ b/src/gpu/Kernel.h
@@ -124,16 +124,16 @@ namespace gpu
       //** Type checking of parameters **********************************************************************************
       /*! \name Type checking of parameters  */
       //@{
-      typedef typename std::remove_pointer<FuncPtr>::type FuncType;
+      using FuncType = std::remove_pointer_t<FuncPtr>;
 
       #define CHECK_PARAMETER_FUNC( Number ) \
       template<typename T> \
-      bool checkParameter##Number( typename std::enable_if< (FunctionTraits<FuncType>::arity > Number ), T >::type *  = 0 ) { \
+      bool checkParameter##Number( typename std::enable_if_t< (FunctionTraits<FuncType>::arity > Number ), T > *  = 0 ) { \
          typedef typename FunctionTraits<FuncType>::template argument<Number>::type ArgType; \
-         return std::is_same< T, ArgType >::value; \
+         return std::is_same_v< T, ArgType >; \
       } \
       template<typename T> \
-      bool checkParameter##Number( typename std::enable_if< (FunctionTraits<FuncType>::arity <= Number ),T >::type *  = 0 ) { \
+      bool checkParameter##Number( typename std::enable_if_t< (FunctionTraits<FuncType>::arity <= Number ),T > *  = 0 ) { \
          return false; \
       }
 
@@ -241,8 +241,8 @@ namespace gpu
 
       // register all parameters
       std::vector<void*> args;
-      for( auto paramIt = params_.begin(); paramIt != params_.end(); ++paramIt )  {
-         args.push_back( const_cast<char*>(paramIt->data()) );
+      for(const auto & param : params_)  {
+         args.push_back( const_cast<char*>(param.data()) );
       }
 
       // .. and launch the kernel
diff --git a/src/gpu/ParallelStreams.cpp b/src/gpu/ParallelStreams.cpp
index aed66f6932b48fcad2b2dcb945d3868382266c6a..e22c677b28d924dd146ebe201f1980947c2c2bc8 100644
--- a/src/gpu/ParallelStreams.cpp
+++ b/src/gpu/ParallelStreams.cpp
@@ -29,7 +29,7 @@ namespace gpu
 
 
    ParallelSection::ParallelSection(ParallelStreams * parent, gpuStream_t mainStream)
-     : parent_( parent ), mainStream_( mainStream ), counter_( 0 )
+     : parent_( parent ), mainStream_( mainStream )
    {
       WALBERLA_DEVICE_SECTION()
       {
@@ -101,7 +101,7 @@ namespace gpu
    }
 
    ParallelSection ParallelStreams::parallelSection( gpuStream_t stream ) {
-      return ParallelSection(this, stream);
+      return {this, stream};
    }
 
    void ParallelStreams::ensureSize( uint_t size ) {
diff --git a/src/gpu/ParallelStreams.h b/src/gpu/ParallelStreams.h
index 0eca060569adf0e404c510f7847d9348f535df0f..99ea6aa230f3938dababfd07c1c547167ad2ec5f 100644
--- a/src/gpu/ParallelStreams.h
+++ b/src/gpu/ParallelStreams.h
@@ -48,7 +48,7 @@ namespace gpu
       ParallelStreams * parent_;
       gpuStream_t mainStream_;
       gpuEvent_t startEvent_;
-      uint_t counter_;
+      uint_t counter_ = 0;
    };
 
 
diff --git a/src/gpu/communication/GPUPackInfo.h b/src/gpu/communication/GPUPackInfo.h
index f700c372924a310e3ba816164692b1b6650c13d5..86cb38b4d0826df46bc35e8fb25d651bccf61653 100644
--- a/src/gpu/communication/GPUPackInfo.h
+++ b/src/gpu/communication/GPUPackInfo.h
@@ -74,32 +74,32 @@ template<typename GPUField_T>
 class GPUPackInfo : public walberla::communication::UniformPackInfo
 {
 public:
-   typedef typename GPUField_T::value_type FieldType;
+   using FieldType = typename GPUField_T::value_type;
 
    GPUPackInfo( const BlockDataID & bdId )
    : bdId_( bdId ), communicateAllGhostLayers_( true ), numberOfGhostLayers_( 0 ),
-     copyAsync_( false ), communicationStream_( 0 )
+     copyAsync_( false ), communicationStream_( nullptr )
    {
    }
 
    GPUPackInfo( const BlockDataID & bdId, const uint_t numberOfGHostLayers )
    : bdId_( bdId ), communicateAllGhostLayers_( false ), numberOfGhostLayers_(  numberOfGHostLayers ),
-     copyAsync_( false ), communicationStream_( 0 )
+     copyAsync_( false ), communicationStream_( nullptr )
    {
    }
 
-   virtual ~GPUPackInfo() {}
+   ~GPUPackInfo() override = default;
 
-   bool constantDataExchange() const { return mpi::BufferSizeTrait<FieldType>::constantSize; }
-   bool threadsafeReceiving()  const { return true; }
+   bool constantDataExchange() const override { return mpi::BufferSizeTrait<FieldType>::constantSize; }
+   bool threadsafeReceiving()  const override { return true; }
 
-   void unpackData(IBlock * receiver, stencil::Direction dir, mpi::RecvBuffer & buffer);
+   void unpackData(IBlock * receiver, stencil::Direction dir, mpi::RecvBuffer & buffer) override;
 
-   void communicateLocal(const IBlock * sender, IBlock * receiver, stencil::Direction dir);
+   void communicateLocal(const IBlock * sender, IBlock * receiver, stencil::Direction dir) override;
 
    void setCommunicationStream( gpuStream_t stream )
    {
-      if ( stream != 0 )
+      if ( stream != nullptr )
       {
          copyAsync_ = true;
          communicationStream_ = stream;
@@ -107,7 +107,7 @@ public:
    }
 
 protected:
-   void packDataImpl(const IBlock * sender, stencil::Direction dir, mpi::SendBuffer & outBuffer) const;
+   void packDataImpl(const IBlock * sender, stencil::Direction dir, mpi::SendBuffer & outBuffer) const override;
 
    uint_t numberOfGhostLayersToCommunicate( const GPUField_T * const field ) const;
 
diff --git a/src/gpu/communication/NonUniformGPUScheme.h b/src/gpu/communication/NonUniformGPUScheme.h
index ddd9fafe971e809e476595f5b67caac7340623d6..7851253c952376fe6f19672d4a1295592bd8e491 100644
--- a/src/gpu/communication/NonUniformGPUScheme.h
+++ b/src/gpu/communication/NonUniformGPUScheme.h
@@ -129,7 +129,7 @@ class NonUniformGPUScheme
    Set< SUID > requiredBlockSelectors_;
    Set< SUID > incompatibleBlockSelectors_;
 
-   gpuStream_t streams_[Stencil::Q];
+   std::array<gpuStream_t, Stencil::Q> streams_;
    std::vector< uint8_t > timestepPerLevel_;
 };
 
diff --git a/src/gpu/communication/UniformGPUScheme.h b/src/gpu/communication/UniformGPUScheme.h
index 183df0497a53e11f2260fc3e591d65462800c036..231b03294bd9d58e7cf7a970c56b8a05ddb2ab88 100644
--- a/src/gpu/communication/UniformGPUScheme.h
+++ b/src/gpu/communication/UniformGPUScheme.h
@@ -135,7 +135,7 @@ namespace communication {
        Set<SUID> requiredBlockSelectors_;
        Set<SUID> incompatibleBlockSelectors_;
 
-       gpuStream_t streams_[Stencil::Q];
+       std::array<gpuStream_t, Stencil::Q> streams_;
    };
 
 
diff --git a/src/gpu/communication/UniformGPUScheme.impl.h b/src/gpu/communication/UniformGPUScheme.impl.h
index 0221290f425dec2c0fc07214022cf8d80f079b25..0b271d00c55afda3b5670cecd8af49eeae50587c 100644
--- a/src/gpu/communication/UniformGPUScheme.impl.h
+++ b/src/gpu/communication/UniformGPUScheme.impl.h
@@ -103,7 +103,7 @@ namespace communication {
 
 
       if( !sendFromGPU_ )
-         for( auto it : headers_ )
+         for( const auto& it : headers_ )
             bufferSystemGPU_.sendBuffer( it.first ).clear();
 
       // wait until communication dependent kernels are finished
diff --git a/src/lbm/boundary/ParserUBB.h b/src/lbm/boundary/ParserUBB.h
index 8559af959fd29f619b3d2284b8a7453de9fa1db9..e4cea769ac982f7be139fad36dbb1221bd30d224 100644
--- a/src/lbm/boundary/ParserUBB.h
+++ b/src/lbm/boundary/ParserUBB.h
@@ -117,7 +117,7 @@ public:
 
 
    ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField,
-              FlagField<flag_t> * const flagField, const shared_ptr< TimeTracker > & timeTracker,
+              const FlagField<flag_t> * const flagField, const shared_ptr< TimeTracker > & timeTracker,
               const uint_t level, const AABB & aabb );
    ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField,
               FlagField<flag_t> * const flagField,  const uint_t level, const AABB & aabb );
@@ -285,7 +285,7 @@ Vector3< real_t > ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce
 
 template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce, bool StoreForce>
 inline ParserUBB<LatticeModel_T, flag_t, AdaptVelocityToExternalForce, StoreForce>::ParserUBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField * const pdfField,
-                                                                                   FlagField<flag_t> * const flagField, const shared_ptr< TimeTracker > & timeTracker,
+                                                                                   const FlagField<flag_t> * const flagField, const shared_ptr< TimeTracker > & timeTracker,
                                                                                    const uint_t level, const AABB & aabb )
    : Boundary<flag_t>( boundaryUID ), uid_( uid ), pdfField_( pdfField ), timeTracker_( timeTracker ), time_( real_t(0) ), level_( level )
 {
diff --git a/src/lbm/boundary/SimpleDiffusionDirichlet.h b/src/lbm/boundary/SimpleDiffusionDirichlet.h
index 5fa9db33d07f1559913f0e0a8c9fb590b3dd3e4e..b2d1b5779af2119d44ca63b5635f70e6d79620de 100644
--- a/src/lbm/boundary/SimpleDiffusionDirichlet.h
+++ b/src/lbm/boundary/SimpleDiffusionDirichlet.h
@@ -102,13 +102,13 @@ private:
    PDFField* const pdfField_;
 
    real_t val_;
-   bool   init_;
+   bool   init_{false};
 
 }; // class SimpleDiffusionDirichlet
 
 template< typename LatticeModel_T, typename flag_t >
 inline SimpleDiffusionDirichlet< LatticeModel_T, flag_t >::SimpleDiffusionDirichlet( const BoundaryUID& boundaryUID, const FlagUID& uid, PDFField* const pdfField, const real_t val ) :
-   Boundary<flag_t>( boundaryUID ), uid_( uid ), pdfField_( pdfField ), val_( val ), init_(false)
+   Boundary<flag_t>( boundaryUID ), uid_( uid ), pdfField_( pdfField ), val_( val )
 {
    WALBERLA_ASSERT_NOT_NULLPTR( pdfField_ );
 }
diff --git a/src/lbm/boundary/UBB.h b/src/lbm/boundary/UBB.h
index 9b1e46fa72895b87325ba7a8c4f63d827753a241..9a49e3f442e642ad3ad318fce0de041a02403b1f 100644
--- a/src/lbm/boundary/UBB.h
+++ b/src/lbm/boundary/UBB.h
@@ -87,7 +87,7 @@ public:
 
 
 
-   inline UBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField* const pdfField, FlagField<flag_t> * const flagField = nullptr );
+   inline UBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField* const pdfField, const FlagField<flag_t> * const flagField = nullptr );
 
    void pushFlags( std::vector< FlagUID > & uids ) const { uids.push_back( uid_ ); }
 
@@ -141,7 +141,7 @@ inline UBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce, StoreForce >::
 
 
 template< typename LatticeModel_T, typename flag_t, bool AdaptVelocityToExternalForce, bool StoreForce >
-inline UBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce, StoreForce >::UBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField* const pdfField, FlagField<flag_t> * const flagField ) :
+inline UBB< LatticeModel_T, flag_t, AdaptVelocityToExternalForce, StoreForce >::UBB( const BoundaryUID & boundaryUID, const FlagUID & uid, PDFField* const pdfField, const FlagField<flag_t> * const flagField ) :
 
    Boundary<flag_t>( boundaryUID ), uid_( uid ), pdfField_( pdfField )
 {
diff --git a/src/lbm/boundary/factories/DefaultBoundaryHandling.h b/src/lbm/boundary/factories/DefaultBoundaryHandling.h
index bdd2fb493326ca19af173aae9c1a4c769b97c319..9154638cba96d20d8caea5a305c7bfb52d633593 100644
--- a/src/lbm/boundary/factories/DefaultBoundaryHandling.h
+++ b/src/lbm/boundary/factories/DefaultBoundaryHandling.h
@@ -173,8 +173,8 @@ DefaultBoundaryHandlingFactory<LatticeModel, FlagFieldT>::operator()( walberla::
    FlagFieldT * const flagField = block->getData< FlagFieldT >( flagField_ );
 
    flag_t mask = 0;
-   for( auto flag = flagUIDSet_.begin(); flag != flagUIDSet_.end(); ++flag )
-      mask = static_cast< flag_t >( mask | flagField->getOrRegisterFlag( *flag ) );
+   for(auto flag : flagUIDSet_)
+      mask = static_cast< flag_t >( mask | flagField->getOrRegisterFlag( flag ) );
 
    BoundaryHandling * handling = new BoundaryHandling( "default lbm boundary handling", flagField, mask,
         BcNoSlip        ( getNoSlipBoundaryUID(),    getNoSlip(),    pdfField ),
diff --git a/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h b/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h
index 89fb33500f56417bbee3eb083f9a8ce44909daa0..d4d324f317f2e5cb664c2252f9e77bc0439a16b6 100644
--- a/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h
+++ b/src/lbm/boundary/factories/DefaultDiffusionBoundaryHandling.h
@@ -98,8 +98,8 @@ private:
       WALBERLA_ASSERT_NOT_NULLPTR( pdfField );
 
       flag_t domainMask(0u);
-      for( auto domainFlagUID = domainFlagUIDs.begin(); domainFlagUID != domainFlagUIDs.end(); ++domainFlagUID )
-         field::addMask( domainMask, flagField->getOrRegisterFlag( *domainFlagUID ) );
+      for(auto domainFlagUID : domainFlagUIDs)
+         field::addMask( domainMask, flagField->getOrRegisterFlag( domainFlagUID ) );
 
       BoundaryHandling_T * handling = new BoundaryHandling_T( "Diffusion Boundary Handling", flagField, domainMask,
          DiffusionDirichlet_T      ( getDiffusionDirichletBoundaryUID(),        getDiffusionDirichletFlagUID(),        pdfField, flagField ),
@@ -112,11 +112,11 @@ private:
       if( initFlagUIDs.size() > size_t(0u) )
       {
          flag_t initMask(0u);
-         for( auto initFlagUID = initFlagUIDs.begin(); initFlagUID != initFlagUIDs.end(); ++initFlagUID )
-            if( flagField->flagExists( *initFlagUID ) )
-               field::addMask( initMask, flagField->getFlag( *initFlagUID ) );
+         for(auto initFlagUID : initFlagUIDs)
+            if( flagField->flagExists( initFlagUID ) )
+               field::addMask( initMask, flagField->getFlag( initFlagUID ) );
             else
-               WALBERLA_ABORT( "Try to init flag field with a non registered flag: " << *initFlagUID );
+               WALBERLA_ABORT( "Try to init flag field with a non registered flag: " << initFlagUID );
          handling->fillWithDomain( initMask, uint_t(0u) );
       }
 
diff --git a/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h b/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h
index 730ceb008f7897c0d608119ad925940517d28421..1fad29cbfe2676a70dca881056204348bc728749 100644
--- a/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h
+++ b/src/lbm/boundary/factories/ExtendedBoundaryHandlingFactory.h
@@ -87,7 +87,7 @@ public:
    using BoundaryHandling = walberla::boundary::BoundaryHandling<FlagFieldT, Stencil, BcNoSlip, BcFreeSlip, BcPressure, BcUBB, BcOutlet, BcCurved>;
 
    static BlockDataID addBoundaryHandlingToStorage( const shared_ptr< StructuredBlockStorage > & bs, const std::string & identifier,
-                                                    BlockDataID flagFieldID, BlockDataID pdfFieldID, const Set< FlagUID > & flagUIDSet)
+                                                    BlockDataID  /*flagFieldID*/, BlockDataID pdfFieldID, const Set< FlagUID > & flagUIDSet)
    {
       return addBoundaryHandlingToStorage(bs, identifier, pdfFieldID, pdfFieldID, flagUIDSet,BoundaryHandling::Mode::OPTIMIZED_SPARSE_TRAVERSAL );
    }
@@ -158,8 +158,8 @@ ExtendedBoundaryHandlingFactory<LatticeModel, FlagFieldT>::operator()( IBlock *
    FlagFieldT * const flagField = block->getData< FlagFieldT >( flagField_ );
 
    flag_t mask = 0;
-   for( auto flag = flagUIDSet_.begin(); flag != flagUIDSet_.end(); ++flag )
-      mask = static_cast< flag_t >( mask | flagField->getOrRegisterFlag( *flag ) );
+   for(auto flag : flagUIDSet_)
+      mask = static_cast< flag_t >( mask | flagField->getOrRegisterFlag( flag ) );
 
 
 
diff --git a/src/lbm/communication/SparsePdfFieldPackInfo.h b/src/lbm/communication/SparsePdfFieldPackInfo.h
index aebdd204c47667f991c9386dc6843e808a476b90..5c7679cf8f96eef3bda18d926c7b5a0da140442e 100644
--- a/src/lbm/communication/SparsePdfFieldPackInfo.h
+++ b/src/lbm/communication/SparsePdfFieldPackInfo.h
@@ -61,25 +61,25 @@ class SparsePdfFieldPackInfo : public communication::UniformPackInfo
 {
 public:
 
-   typedef lbm::PdfField<LatticeModel_T>     PdfField_T;
-   typedef typename FlagField_T::flag_t      flag_t;
-   typedef typename LatticeModel_T::Stencil  Stencil;
+   using PdfField_T = lbm::PdfField<LatticeModel_T>;
+   using flag_t = typename FlagField_T::flag_t;
+   using Stencil = typename LatticeModel_T::Stencil;
 
    SparsePdfFieldPackInfo( const BlockDataID & pdfFieldId, const BlockDataID & flagFieldId, FlagUID flag, bool flagFieldConstant )
       : pdfFieldId_( pdfFieldId ), flagFieldId_( flagFieldId ), flag_( flag ), flagFieldConstant_( flagFieldConstant ) {}
 
    ~SparsePdfFieldPackInfo() override = default;
 
-   bool constantDataExchange() const { return flagFieldConstant_; }
-   bool threadsafeReceiving()  const { return true; }
+   bool constantDataExchange() const override { return flagFieldConstant_; }
+   bool threadsafeReceiving()  const override { return true; }
 
-   void unpackData( IBlock * receiver, stencil::Direction dir, mpi::RecvBuffer & buffer );
+   void unpackData( IBlock * receiver, stencil::Direction dir, mpi::RecvBuffer & buffer ) override;
 
-   void communicateLocal( const IBlock * sender, IBlock * receiver, stencil::Direction dir );
+   void communicateLocal( const IBlock * sender, IBlock * receiver, stencil::Direction dir ) override;
 
 protected:
 
-   void packDataImpl( const IBlock * sender, stencil::Direction dir, mpi::SendBuffer & outBuffer ) const;
+   void packDataImpl( const IBlock * sender, stencil::Direction dir, mpi::SendBuffer & outBuffer ) const override;
 
 
    BlockDataID pdfFieldId_;
diff --git a/src/lbm/free_surface/bubble_model/FloodFill.impl.h b/src/lbm/free_surface/bubble_model/FloodFill.impl.h
index 96f1c0361466b96fcf71ac093acee0e14fa57415..1cf617cb612399bc454c1dd06e688fa76b36320f 100644
--- a/src/lbm/free_surface/bubble_model/FloodFill.impl.h
+++ b/src/lbm/free_surface/bubble_model/FloodFill.impl.h
@@ -54,7 +54,7 @@ void FloodFillUsingFillLevel< Stencil_T >::run(IBlock& block, BlockDataID bubble
    std::vector< bool > addedLast;
 
    using namespace stencil;
-   const int dirs[4]    = { N, S, T, B };
+   const uint_t dirs[4]    = { N, S, T, B };
    const uint_t numDirs = uint_c(4);
 
    CellInterval fieldSizeInterval = fillField->xyzSize();
@@ -149,7 +149,7 @@ void FloodFillUsingFlagField< FlagField_T >::run(IBlock& block, BlockDataID bubb
    std::vector< bool > addedLast;
 
    using namespace stencil;
-   const int dirs[4]    = { N, S, T, B };
+   const uint_t dirs[4]    = { N, S, T, B };
    const uint_t numDirs = uint_c(4);
 
    CellInterval fieldSizeInterval = flagField->xyzSize();
diff --git a/src/lbm/vtk/NonEquilibrium.h b/src/lbm/vtk/NonEquilibrium.h
index 4a756dba9651096f677b12627305b6e7f68b238b..fb3bf6abfb66f70c99aa7d493a41824f3829d235 100644
--- a/src/lbm/vtk/NonEquilibrium.h
+++ b/src/lbm/vtk/NonEquilibrium.h
@@ -59,7 +59,7 @@ protected:
 
       real_t rho = pdf_->getDensityAndEquilibriumMomentumDensity( v, x, y, z );
 
-      return numeric_cast< OutputType >( pdf_->get( x, y, z, f ) - lbm::EquilibriumDistribution< LatticeModel_T >::get( Stencil::dir[f], v, rho ) );
+      return numeric_cast< OutputType >( pdf_->get( x, y, z, f ) - lbm::EquilibriumDistribution< LatticeModel_T >::get( Stencil::dir[uint_c(f)], v, rho ) );
    }
 
    const ConstBlockDataID bdid_;
diff --git a/src/lbm/vtk/VTKOutput.h b/src/lbm/vtk/VTKOutput.h
index 9e58cf06f49d214d9c50f3d0b9cd55c01d681fd4..db07ed6958a8d97ae667a28a805cce91b0646e6a 100644
--- a/src/lbm/vtk/VTKOutput.h
+++ b/src/lbm/vtk/VTKOutput.h
@@ -206,9 +206,9 @@ void VTKOutput<LatticeModel, FlagFieldT>::addToTimeloop( Timeloop & timeloop, co
    std::map< std::string, vtk::SelectableOutputFunction > vtkOutputFunctions;
    vtk::initializeVTKOutput( vtkOutputFunctions, vtkOutput, blocks, config, configBlockName );
 
-   for( auto output = vtkOutputFunctions.begin(); output != vtkOutputFunctions.end(); ++output )
-      timeloop.addFuncBeforeTimeStep( output->second.outputFunction, std::string("VTK (LBM): ") + output->first,
-                                      output->second.requiredGlobalStates, output->second.incompatibleGlobalStates );
+   for(auto & vtkOutputFunction : vtkOutputFunctions)
+      timeloop.addFuncBeforeTimeStep( vtkOutputFunction.second.outputFunction, std::string("VTK (LBM): ") + vtkOutputFunction.first,
+                                      vtkOutputFunction.second.requiredGlobalStates, vtkOutputFunction.second.incompatibleGlobalStates );
 }
 
 
diff --git a/src/lbm_mesapd_coupling/DataTypesCodegen.h b/src/lbm_mesapd_coupling/DataTypesCodegen.h
index 99583a6131a846193826d968e9b8695c5d51d4f6..a49c9ea1ade8275f22935b9725b9e1e820304c3c 100644
--- a/src/lbm_mesapd_coupling/DataTypesCodegen.h
+++ b/src/lbm_mesapd_coupling/DataTypesCodegen.h
@@ -40,7 +40,7 @@ namespace psm
 namespace gpu
 {
 
-const uint MaxParticlesPerCell = MAX_PARTICLES_PER_CELL; // MAX_PARTICLES_PER_CELL comes from CMake
+const uint_t MaxParticlesPerCell = MAX_PARTICLES_PER_CELL; // MAX_PARTICLES_PER_CELL comes from CMake
 
 // nOverlappingParticlesField is used to store the amount of overlapping particles per cell
 // B denotes the local weighting factor and is calculated by taking the sum of all local particle
@@ -96,9 +96,9 @@ struct ParticleAndVolumeFractionSoA_T
                                                                         field::fzyx, uint_t(1), true);
       BFieldID = walberla::gpu::addGPUFieldToStorage< BFieldGPU_T >(bs, "B field GPU", 1, field::fzyx, uint_t(1), true);
       particleVelocitiesFieldID = walberla::gpu::addGPUFieldToStorage< particleVelocitiesFieldGPU_T >(
-         bs, "particle velocities field GPU", uint_t(MaxParticlesPerCell * 3), field::fzyx, uint_t(1), true);
+         bs, "particle velocities field GPU", MaxParticlesPerCell * 3, field::fzyx, uint_t(1), true);
       particleForcesFieldID = walberla::gpu::addGPUFieldToStorage< particleForcesFieldGPU_T >(
-         bs, "particle forces field GPU", uint_t(MaxParticlesPerCell * 3), field::fzyx, uint_t(1), true);
+         bs, "particle forces field GPU", MaxParticlesPerCell * 3, field::fzyx, uint_t(1), true);
 #else
       nOverlappingParticlesFieldID = field::addToStorage< nOverlappingParticlesField_T >(
          bs, "number of overlapping particles field CPU", uint_t(0), field::fzyx, uint_t(1), true);
diff --git a/src/lbm_mesapd_coupling/amr/weight_assignment/WeightEvaluationFunctions.h b/src/lbm_mesapd_coupling/amr/weight_assignment/WeightEvaluationFunctions.h
index 6219f4f43f6c2212231b21afe68ce03c4251abc5..77e29cd0e2f0dbf0343333b9d868723ca63d1c62 100644
--- a/src/lbm_mesapd_coupling/amr/weight_assignment/WeightEvaluationFunctions.h
+++ b/src/lbm_mesapd_coupling/amr/weight_assignment/WeightEvaluationFunctions.h
@@ -26,7 +26,7 @@ namespace walberla {
 namespace lbm_mesapd_coupling  {
 namespace amr {
 
-real_t defaultWeightEvaluationFunction(const PhantomBlock * /*block*/)
+inline real_t defaultWeightEvaluationFunction(const PhantomBlock * /*block*/)
 {
    return real_t(1);
 }
diff --git a/src/lbm_mesapd_coupling/mapping/ParticleBoundingBox.h b/src/lbm_mesapd_coupling/mapping/ParticleBoundingBox.h
index 7c2f49a3b8ea4808d9ea8306917579c83b0c3d52..e55a075b38f26058dbd9b81a73ae597704dcf80f 100644
--- a/src/lbm_mesapd_coupling/mapping/ParticleBoundingBox.h
+++ b/src/lbm_mesapd_coupling/mapping/ParticleBoundingBox.h
@@ -59,7 +59,7 @@ inline CellInterval getCellBBFromAABB( const math::AABB & aabb, bool AABBIsInfin
       blockStorage.getCellBBFromAABB( cellBB, aabb.getIntersection( extendedBlockAABB ), level );
 
       // if (partly) infinite aabb does not intersect with the extended block AABB, return an empty interval
-      if( cellBB.empty() ) return CellInterval();
+      if( cellBB.empty() ) return {};
    }
    else
    {
diff --git a/src/lbm_mesapd_coupling/mapping/ParticleMapping.h b/src/lbm_mesapd_coupling/mapping/ParticleMapping.h
index 507156382398311804affce080bc800df8abc1ad..5bf1232516689ec74a984e05e4cb72b4f4658777 100644
--- a/src/lbm_mesapd_coupling/mapping/ParticleMapping.h
+++ b/src/lbm_mesapd_coupling/mapping/ParticleMapping.h
@@ -52,7 +52,7 @@ public:
    template<typename ParticleAccessor_T>
    void operator()(const size_t particleIdx, const ParticleAccessor_T& ac, const FlagUID & obstacle )
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       for( auto blockIt = blockStorage_->begin(); blockIt != blockStorage_->end(); ++blockIt )
       {
@@ -66,7 +66,7 @@ private:
    void mapParticleOnBlock( const size_t particleIdx, const ParticleAccessor_T& ac,
                            IBlock & block, const FlagUID & obstacle )
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       WALBERLA_ASSERT_EQUAL( &block.getBlockStorage(), &(blockStorage_->getBlockStorage()) );
 
diff --git a/src/lbm_mesapd_coupling/momentum_exchange_method/MovingParticleMapping.h b/src/lbm_mesapd_coupling/momentum_exchange_method/MovingParticleMapping.h
index 88d3112369193368602fec3c9e9506bad89a2b7f..e69c452b7912c211467360901080221afc00bf0b 100644
--- a/src/lbm_mesapd_coupling/momentum_exchange_method/MovingParticleMapping.h
+++ b/src/lbm_mesapd_coupling/momentum_exchange_method/MovingParticleMapping.h
@@ -59,7 +59,7 @@ namespace lbm_mesapd_coupling {
 template< typename PdfField_T, typename BoundaryHandling_T, typename ParticleAccessor_T, typename ParticleSelector_T>
 class MovingParticleMapping
 {
-   static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+   static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
 public:
 
@@ -277,7 +277,7 @@ public:
    template<typename ParticleAccessor_T>
    void operator()(const size_t particleIdx, const ParticleAccessor_T& ac, const FlagUID & obstacle )
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       for( auto blockIt = blockStorage_->begin(); blockIt != blockStorage_->end(); ++blockIt )
       {
@@ -291,7 +291,7 @@ private:
    void mapMovingParticleOnBlock( const size_t particleIdx, const ParticleAccessor_T& ac,
                                   IBlock & block, const FlagUID & obstacle )
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       WALBERLA_ASSERT_EQUAL( &block.getBlockStorage(), &(blockStorage_->getBlockStorage()) );
 
diff --git a/src/lbm_mesapd_coupling/momentum_exchange_method/boundary/CurvedLinear.h b/src/lbm_mesapd_coupling/momentum_exchange_method/boundary/CurvedLinear.h
index 215c03f3a543ea81545b5e291187bfce15e66734..da102ac0f1a099764dbfa943a2b9566c413606aa 100644
--- a/src/lbm_mesapd_coupling/momentum_exchange_method/boundary/CurvedLinear.h
+++ b/src/lbm_mesapd_coupling/momentum_exchange_method/boundary/CurvedLinear.h
@@ -68,7 +68,7 @@ class CurvedLinear : public Boundary< typename FlagField_T::flag_t >
    using Stencil_T = typename LatticeModel_T::Stencil;
    using flag_t = typename FlagField_T::flag_t;
 
-   static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+   static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
 public:
 
diff --git a/src/lbm_mesapd_coupling/momentum_exchange_method/boundary/SimpleBB.h b/src/lbm_mesapd_coupling/momentum_exchange_method/boundary/SimpleBB.h
index 7d5c528489cae9578b34586238f282ba2dd0df7a..3beb44af9cefe917f5387fd92faf25acf443faed 100644
--- a/src/lbm_mesapd_coupling/momentum_exchange_method/boundary/SimpleBB.h
+++ b/src/lbm_mesapd_coupling/momentum_exchange_method/boundary/SimpleBB.h
@@ -60,7 +60,7 @@ class SimpleBB : public Boundary< typename FlagField_T::flag_t >
    using Stencil_T = typename LatticeModel_T::Stencil;
    using flag_t = typename FlagField_T::flag_t;
 
-   static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+   static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
 public:
 
diff --git a/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/ExtrapolationDirectionFinder.h b/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/ExtrapolationDirectionFinder.h
index 22ebdfb3b72b2e98a43e2696d45cd316ae3c50f8..3857f8b588b9da9aa107917d2b9921df139ee6e5 100644
--- a/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/ExtrapolationDirectionFinder.h
+++ b/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/ExtrapolationDirectionFinder.h
@@ -136,7 +136,7 @@ public:
    Vector3<cell_idx_t> operator()( IBlock * const block, const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z,
                                    const size_t particleIdx, const ParticleAccessor_T & ac) const
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       real_t cx, cy, cz;
       blockStorage_->getBlockLocalCellCenter( *block, Cell(x,y,z), cx, cy, cz );
diff --git a/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/PdfReconstructionManager.h b/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/PdfReconstructionManager.h
index dcf4c750ece66a25a5ee24019d41ac43a10877bb..ccce39b3ca37a57cb1695dbf7fba43614de983f1 100644
--- a/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/PdfReconstructionManager.h
+++ b/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/PdfReconstructionManager.h
@@ -67,7 +67,7 @@ namespace lbm_mesapd_coupling {
 template< typename PdfField_T, typename BoundaryHandling_T, typename ParticleAccessor_T, typename Reconstructor_T>
 class PdfReconstructionManager
 {
-   static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+   static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
 public:
 
diff --git a/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/Reconstructor.h b/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/Reconstructor.h
index e3d7ae05a958b6610affdda29d5327a3d452f41a..486aa7cde9a5c599c7ae5386a216f104e07c83ca 100644
--- a/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/Reconstructor.h
+++ b/src/lbm_mesapd_coupling/momentum_exchange_method/reconstruction/Reconstructor.h
@@ -124,7 +124,7 @@ public:
    void operator()( IBlock * const block, const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z, PdfField_T * const pdfField,
                     const size_t particleIdx, const ParticleAccessor_T & ac)
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       WALBERLA_ASSERT_NOT_NULLPTR( block );
       WALBERLA_ASSERT_NOT_NULLPTR( pdfField );
@@ -209,7 +209,7 @@ public:
    void operator()( IBlock * const block, const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z, PdfField_T * const pdfField,
                     const size_t particleIdx, const ParticleAccessor_T & ac)
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       WALBERLA_ASSERT_NOT_NULLPTR( block );
       WALBERLA_ASSERT_NOT_NULLPTR( pdfField );
@@ -224,7 +224,7 @@ public:
    void operator()( IBlock * const block, const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z, PdfField_T * const pdfField,
                     const size_t particleIdx, const ParticleAccessor_T & ac, const Vector3<cell_idx_t> & extrapolationDirection )
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       WALBERLA_ASSERT_NOT_NULLPTR( block );
       WALBERLA_ASSERT_NOT_NULLPTR( pdfField );
@@ -380,7 +380,7 @@ public:
    void operator()( IBlock * const block, const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z, PdfField_T * const pdfField,
                     const size_t particleIdx, const ParticleAccessor_T & ac)
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       WALBERLA_ASSERT_NOT_NULLPTR(block);
       WALBERLA_ASSERT_NOT_NULLPTR(pdfField);
@@ -449,7 +449,7 @@ private:
    {
       using LatticeModel_T = typename PdfField_T::LatticeModel;
 
-      static_assert(std::is_same<typename LatticeModel_T::Stencil, stencil::D3Q19>::value || !EnforceNoSlipConstraintAfterExtrapolation, "Enforcing no-slip constraint after extrapolation currently only works with D3Q19 stencil!");
+      static_assert(std::is_same_v<typename LatticeModel_T::Stencil, stencil::D3Q19> || !EnforceNoSlipConstraintAfterExtrapolation, "Enforcing no-slip constraint after extrapolation currently only works with D3Q19 stencil!");
 
       WALBERLA_ASSERT_NOT_NULLPTR( pdfField );
       WALBERLA_ASSERT( !math::isnan(localParticleVelocity) );
@@ -596,7 +596,7 @@ public:
    void operator()( IBlock * const block, const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z, PdfField_T * const pdfField,
                     const size_t particleIdx, const ParticleAccessor_T & ac)
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       WALBERLA_ASSERT_NOT_NULLPTR( block );
       WALBERLA_ASSERT_NOT_NULLPTR( pdfField );
diff --git a/src/lbm_mesapd_coupling/overlapping/OverlapFraction.h b/src/lbm_mesapd_coupling/overlapping/OverlapFraction.h
index c1fa9d7c99583356f122595d8d8df4190f3e82ad..a177bdd6843a1157606eabbddcbb011aeb6a39f9 100644
--- a/src/lbm_mesapd_coupling/overlapping/OverlapFraction.h
+++ b/src/lbm_mesapd_coupling/overlapping/OverlapFraction.h
@@ -58,7 +58,7 @@ struct OverlapFractionFunctor
                      const shared_ptr< ParticleAccessor_T >& ac, const Vector3< real_t >& point,
                      const Vector3< real_t >& dxVec, uint_t superSamplingDepth)
    {
-      WALBERLA_STATIC_ASSERT((std::is_base_of< mesa_pd::data::IAccessor, ParticleAccessor_T >::value));
+      WALBERLA_STATIC_ASSERT((std::is_base_of_v< mesa_pd::data::IAccessor, ParticleAccessor_T >));
 
       SphereWithOverlap sphereWithOverlap(particleIdx, ac, sphere);
       return geometry::overlapFraction< geometry::AbstractBody >(sphereWithOverlap, point, dxVec, superSamplingDepth);
@@ -69,7 +69,7 @@ struct OverlapFractionFunctor
                      const shared_ptr< ParticleAccessor_T >& ac, const Vector3< real_t >& point, real_t dxVec,
                      uint_t superSamplingDepth)
    {
-      WALBERLA_STATIC_ASSERT((std::is_base_of< mesa_pd::data::IAccessor, ParticleAccessor_T >::value));
+      WALBERLA_STATIC_ASSERT((std::is_base_of_v< mesa_pd::data::IAccessor, ParticleAccessor_T >));
 
       HalfSpaceWithOverlap halfSpaceWithOverlap(particleIdx, ac, halfSphere);
       return geometry::overlapFraction< geometry::AbstractBody >(halfSpaceWithOverlap, point, dxVec,
@@ -81,7 +81,7 @@ struct OverlapFractionFunctor
                      const shared_ptr< ParticleAccessor_T >& ac, const Vector3< real_t >& point, real_t dxVec,
                      uint_t superSamplingDepth)
    {
-      WALBERLA_STATIC_ASSERT((std::is_base_of< mesa_pd::data::IAccessor, ParticleAccessor_T >::value));
+      WALBERLA_STATIC_ASSERT((std::is_base_of_v< mesa_pd::data::IAccessor, ParticleAccessor_T >));
 
       CylindricalBoundaryWithOverlap cylindricalBoundaryWithOverlap(particleIdx, ac, cylindricalBoundary);
       return geometry::overlapFraction< geometry::AbstractBody >(cylindricalBoundaryWithOverlap, point, dxVec,
@@ -93,7 +93,7 @@ struct OverlapFractionFunctor
                      const shared_ptr< ParticleAccessor_T >& ac, const Vector3< real_t >& point, real_t dxVec,
                      uint_t superSamplingDepth)
    {
-      WALBERLA_STATIC_ASSERT((std::is_base_of< mesa_pd::data::IAccessor, ParticleAccessor_T >::value));
+      WALBERLA_STATIC_ASSERT((std::is_base_of_v< mesa_pd::data::IAccessor, ParticleAccessor_T >));
 
       BoxWithOverlap boxWithOverlap(particleIdx, ac, box);
       return geometry::overlapFraction< geometry::AbstractBody >(boxWithOverlap, point, dxVec, superSamplingDepth);
@@ -104,7 +104,7 @@ struct OverlapFractionFunctor
                      const shared_ptr< ParticleAccessor_T >& ac, const Vector3< real_t >& point, real_t dxVec,
                      uint_t superSamplingDepth)
    {
-      WALBERLA_STATIC_ASSERT((std::is_base_of< mesa_pd::data::IAccessor, ParticleAccessor_T >::value));
+      WALBERLA_STATIC_ASSERT((std::is_base_of_v< mesa_pd::data::IAccessor, ParticleAccessor_T >));
 
       EllipsoidWithOverlap ellipsoidWithOverlap(particleIdx, ac, ellipsoid);
       return geometry::overlapFraction< geometry::AbstractBody >(ellipsoidWithOverlap, point, dxVec,
diff --git a/src/lbm_mesapd_coupling/partially_saturated_cells_method/PSMSweep.h b/src/lbm_mesapd_coupling/partially_saturated_cells_method/PSMSweep.h
index d056e2e76ab010cd2732297778a0e4d6750560cd..cd63d2ff83dc7e1d83aacf0e5f6899a9a50746ee 100644
--- a/src/lbm_mesapd_coupling/partially_saturated_cells_method/PSMSweep.h
+++ b/src/lbm_mesapd_coupling/partially_saturated_cells_method/PSMSweep.h
@@ -194,7 +194,7 @@ void PSMSweep< LatticeModel_T, Filter_T, DensityVelocityIn_T, DensityVelocityOut
             {
                using namespace stencil;
 
-               real_t pdfs[Stencil_T::Size];
+               std::array<real_t, Stencil_T::Size> pdfs;
 
                // stream pull & temporal storage of PDFs
                for (auto d = Stencil_T::begin(); d != Stencil_T::end(); ++d)
@@ -372,7 +372,7 @@ void PSMSweep< LatticeModel_T, Filter_T, DensityVelocityIn_T, DensityVelocityOut
             {
                using namespace stencil;
 
-               real_t pdfs[Stencil_T::Size];
+               std::array<real_t, Stencil_T::Size> pdfs;
 
                // temporal storage of PDFs
                for (auto d = Stencil_T::begin(); d != Stencil_T::end(); ++d)
diff --git a/src/lbm_mesapd_coupling/partially_saturated_cells_method/ParticleAndVolumeFractionMapping.h b/src/lbm_mesapd_coupling/partially_saturated_cells_method/ParticleAndVolumeFractionMapping.h
index e85a9ef259e8e4e68519c79f4db25d1317bd6ca2..bc4e421ead7e85bf8dfd3df15357c28a1b106c77 100644
--- a/src/lbm_mesapd_coupling/partially_saturated_cells_method/ParticleAndVolumeFractionMapping.h
+++ b/src/lbm_mesapd_coupling/partially_saturated_cells_method/ParticleAndVolumeFractionMapping.h
@@ -56,7 +56,7 @@ class ParticleAndVolumeFractionMapping
       : blockStorage_(blockStorage), ac_(ac), mappingParticleSelector_(mappingParticleSelector),
         particleAndVolumeFractionFieldID_(particleAndVolumeFractionFieldID), superSamplingDepth_(superSamplingDepth)
    {
-      static_assert(std::is_base_of< mesa_pd::data::IAccessor, ParticleAccessor_T >::value,
+      static_assert(std::is_base_of_v< mesa_pd::data::IAccessor, ParticleAccessor_T >,
                     "Provide a valid accessor as template");
    }
 
@@ -110,10 +110,8 @@ class ParticleAndVolumeFractionMapping
          Vector3< real_t > dxVec(blockStorage_->dx(level), blockStorage_->dy(level), blockStorage_->dz(level));
 
          // compute the overlap fraction for each cell that has to be considered and save the information
-         for (auto cellIt = cellBB.begin(); cellIt != cellBB.end(); ++cellIt)
+         for (auto cell : cellBB)
          {
-            Cell cell(*cellIt);
-
             Vector3< real_t > cellCenter;
             cellCenter = blockStorage_->getBlockLocalCellCenter(*blockIt, cell);
 
diff --git a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMSweepCollection.h b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMSweepCollection.h
index ec0ed85e2ab09b86eee1034d9f9ca8d9c2120b67..f4d8400fae806d82f28f0332646e2d7aa5069c82 100644
--- a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMSweepCollection.h
+++ b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMSweepCollection.h
@@ -39,7 +39,7 @@ namespace gpu
 {
 
 // The deviceSyncWrapper can be used so that the timeloop measures the correct device runtime
-auto deviceSyncWrapper = [](std::function< void(IBlock*) > sweep) {
+inline auto deviceSyncWrapper = [](std::function< void(IBlock*) > sweep) {
    return [sweep](IBlock* b) {
       sweep(b);
 #ifdef WALBERLA_BUILD_WITH_GPU_SUPPORT
diff --git a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMUtilityGPU.h b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMUtilityGPU.h
index 6ac6d0a9a53321b18c964da6bdc5b72df501b788..b325eab9d93c21751a9d5fa8801bdd9cd4ed119a 100644
--- a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMUtilityGPU.h
+++ b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMUtilityGPU.h
@@ -32,7 +32,7 @@ namespace psm
 namespace gpu
 {
 
-__device__ void cross(real_t* __restrict__ const crossResult, const real_t* __restrict__ const lhs,
+inline __device__ void cross(real_t* __restrict__ const crossResult, const real_t* __restrict__ const lhs,
                       const real_t* __restrict__ const rhs)
 {
    crossResult[0] = lhs[1] * rhs[2] - lhs[2] * rhs[1];
@@ -40,20 +40,20 @@ __device__ void cross(real_t* __restrict__ const crossResult, const real_t* __re
    crossResult[2] = lhs[0] * rhs[1] - lhs[1] * rhs[0];
 }
 
-__device__ void getVelocityAtWFPoint(real_t* __restrict__ const velocityAtWFPoint,
+inline __device__ void getVelocityAtWFPoint(real_t* __restrict__ const velocityAtWFPoint,
                                      const real_t* __restrict__ const linearVelocity,
                                      const real_t* __restrict__ const angularVelocity,
                                      const real_t* __restrict__ const position, const real_t* __restrict__ const wf_pt)
 {
-   real_t crossResult[3];
-   real_t rhs[] = { wf_pt[0] - position[0], wf_pt[1] - position[1], wf_pt[2] - position[2] };
+   real_t crossResult[3]; // NOLINT(*-avoid-c-arrays)
+   real_t rhs[] = { wf_pt[0] - position[0], wf_pt[1] - position[1], wf_pt[2] - position[2] }; // NOLINT(*-avoid-c-arrays)
    cross(crossResult, angularVelocity, rhs);
    velocityAtWFPoint[0] = linearVelocity[0] + crossResult[0];
    velocityAtWFPoint[1] = linearVelocity[1] + crossResult[1];
    velocityAtWFPoint[2] = linearVelocity[2] + crossResult[2];
 }
 
-__device__ void addHydrodynamicForceTorqueAtWFPosAtomic(real_t* __restrict__ const particleForce,
+inline __device__ void addHydrodynamicForceTorqueAtWFPosAtomic(real_t* __restrict__ const particleForce,
                                                         real_t* __restrict__ const particleTorque,
                                                         const real_t* __restrict__ const f,
                                                         const real_t* __restrict__ const pos,
@@ -73,8 +73,8 @@ __device__ void addHydrodynamicForceTorqueAtWFPosAtomic(real_t* __restrict__ con
    unsafeAtomicAdd(&(particleForce[2]), f[2]);
 #endif
 
-   real_t torque[] = { 0.0, 0.0, 0.0 };
-   real_t lhs[]    = { wf_pt[0] - pos[0], wf_pt[1] - pos[1], wf_pt[2] - pos[2] };
+   real_t torque[] = { 0.0, 0.0, 0.0 }; // NOLINT(*-avoid-c-arrays)
+   real_t lhs[]    = { wf_pt[0] - pos[0], wf_pt[1] - pos[1], wf_pt[2] - pos[2] }; // NOLINT(*-avoid-c-arrays)
    cross(torque, lhs, f);
 
 #if defined(WALBERLA_BUILD_WITH_CUDA)
diff --git a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMWrapperKernels.cu b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMWrapperKernels.cu
index 880eebf128f36fc21918f19ad32eea27565452af..fae5e4d113ac7a7614e1687b68ff49afe9d21593 100644
--- a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMWrapperKernels.cu
+++ b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/PSMWrapperKernels.cu
@@ -47,14 +47,14 @@ __global__ void SetParticleVelocities(walberla::gpu::FieldAccessor< uint_t > nOv
    particleVelocitiesField.set(blockIdx_uint3, threadIdx_uint3);
 
    // Cell center is needed in order to compute the particle velocity at this WF point
-   const real_t cellCenter[] = { real_t(blockStart.x + (threadIdx.x + real_t(0.5)) * dx),
+   const real_t cellCenter[] = { real_t(blockStart.x + (threadIdx.x + real_t(0.5)) * dx), // NOLINT(*-avoid-c-arrays)
                                  real_t(blockStart.y + (blockIdx.x + real_t(0.5)) * dx),
                                  real_t(blockStart.z + (blockIdx.y + real_t(0.5)) * dx) };
 
    // Compute the particle velocity at the cell center for all overlapping particles
    for (uint_t p = 0; p < nOverlappingParticlesField.get(); p++)
    {
-      real_t particleVelocityAtWFPoint[] = { real_t(0.0), real_t(0.0), real_t(0.0) };
+      real_t particleVelocityAtWFPoint[] = { real_t(0.0), real_t(0.0), real_t(0.0) }; // NOLINT(*-avoid-c-arrays)
       getVelocityAtWFPoint(particleVelocityAtWFPoint, &linearVelocities[idxField.get(p) * 3],
                            &angularVelocities[idxField.get(p) * 3], &positions[idxField.get(p) * 3], cellCenter);
       particleVelocitiesField.get(p * 3 + 0) = particleVelocityAtWFPoint[0];
@@ -79,15 +79,15 @@ __global__ void ReduceParticleForces(walberla::gpu::FieldAccessor< uint_t > nOve
    particleForcesField.set(blockIdx_uint3, threadIdx_uint3);
 
    // Cell center is needed in order to compute the particle velocity at this WF point
-   const real_t cellCenter[] = { real_t(blockStart.x + (threadIdx.x + real_t(0.5)) * dx),
+   const real_t cellCenter[] = { real_t(blockStart.x + (threadIdx.x + real_t(0.5)) * dx), // NOLINT(*-avoid-c-arrays)
                                  real_t(blockStart.y + (blockIdx.x + real_t(0.5)) * dx),
                                  real_t(blockStart.z + (blockIdx.y + real_t(0.5)) * dx) };
 
    // Reduce the forces for all overlapping particles
    for (uint_t p = 0; p < nOverlappingParticlesField.get(); p++)
    {
-      real_t forceOnParticle[] = { particleForcesField.get(p * 3 + 0), particleForcesField.get(p * 3 + 1),
-                                   particleForcesField.get(p * 3 + 2) };
+      real_t forceOnParticle[] = { particleForcesField.get(p * 3 + 0), // NOLINT(*-avoid-c-arrays)
+                                   particleForcesField.get(p * 3 + 1), particleForcesField.get(p * 3 + 2) };
       forceOnParticle[0] *= forceScalingFactor;
       forceOnParticle[1] *= forceScalingFactor;
       forceOnParticle[2] *= forceScalingFactor;
diff --git a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingKernels.cu b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingKernels.cu
index fe22d4eb1dd4e1d75eeb7c8c5a7bd137a15a6b64..8b5e7a680b35f610780e92a6d19eeb25e6acca6b 100644
--- a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingKernels.cu
+++ b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingKernels.cu
@@ -21,7 +21,7 @@
 
 #include "lbm_mesapd_coupling/DataTypesCodegen.h"
 
-#include <assert.h>
+#include <cassert>
 
 #include "ParticleAndVolumeFractionMappingKernels.h"
 
@@ -36,7 +36,7 @@ namespace gpu
 
 // Functions to calculate Bs
 template< int Weighting_T >
-__device__ void calculateWeighting(real_t* __restrict__ const weighting, const real_t& /*epsilon*/,
+__device__ void calculateWeighting(real_t* __restrict__ const  /*weighting*/, const real_t& /*epsilon*/,
                                    const real_t& /*tau*/)
 {
    WALBERLA_STATIC_ASSERT(Weighting_T == 1 || Weighting_T == 2);
diff --git a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingSweepsCPU.h b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingSweepsCPU.h
index 1ab47b344512d165b8e6c7d5718179f5725a3525..39cad82802916260c44069710785ddd94108b3d0 100644
--- a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingSweepsCPU.h
+++ b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingSweepsCPU.h
@@ -50,18 +50,18 @@ namespace gpu
 {
 
 template< int Weighting_T >
-void calculateWeighting(real_t* const weighting, const real_t& /*epsilon*/, const real_t& /*tau*/)
+inline void calculateWeighting(real_t* const  /*weighting*/, const real_t& /*epsilon*/, const real_t& /*tau*/)
 {
    WALBERLA_STATIC_ASSERT(Weighting_T == 1 || Weighting_T == 2);
 }
 
 template<>
-void calculateWeighting< 1 >(real_t* const weighting, const real_t& epsilon, const real_t& /*tau*/)
+inline void calculateWeighting< 1 >(real_t* const weighting, const real_t& epsilon, const real_t& /*tau*/)
 {
    *weighting = epsilon;
 }
 template<>
-void calculateWeighting< 2 >(real_t* const weighting, const real_t& epsilon, const real_t& tau)
+inline void calculateWeighting< 2 >(real_t* const weighting, const real_t& epsilon, const real_t& tau)
 {
    *weighting = epsilon * (tau - real_t(0.5)) / ((real_t(1) - epsilon) + (tau - real_t(0.5)));
 }
diff --git a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingSweepsGPU.h b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingSweepsGPU.h
index 7576d9476764d092a5c8c3defa4a85117f34b2d5..bab6655fce9685131685590058f943283dc8ab91 100644
--- a/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingSweepsGPU.h
+++ b/src/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/ParticleAndVolumeFractionMappingSweepsGPU.h
@@ -99,7 +99,7 @@ class SphereFractionMappingSweep
       : blockStorage_(blockStorage), ac_(ac), mappingParticleSelector_(mappingParticleSelector),
         particleAndVolumeFractionSoA_(particleAndVolumeFractionSoA), subBlockSize_(subBlockSize)
    {
-      static_assert(std::is_base_of< mesa_pd::data::IAccessor, ParticleAccessor_T >::value,
+      static_assert(std::is_base_of_v< mesa_pd::data::IAccessor, ParticleAccessor_T >,
                     "Provide a valid accessor as template");
       for (auto blockIt = blockStorage_->begin(); blockIt != blockStorage_->end(); ++blockIt)
       {
@@ -305,7 +305,7 @@ class BoxFractionMappingSweep
       : blockStorage_(blockStorage), ac_(ac), boxUid_(boxUid), boxEdgeLength_(boxEdgeLength),
         particleAndVolumeFractionSoA_(particleAndVolumeFractionSoA), mappingParticleSelector_(mappingParticleSelector)
    {
-      static_assert(std::is_base_of< mesa_pd::data::IAccessor, ParticleAccessor_T >::value,
+      static_assert(std::is_base_of_v< mesa_pd::data::IAccessor, ParticleAccessor_T >,
                     "Provide a valid accessor as template");
    }
 
diff --git a/src/lbm_mesapd_coupling/utility/AddForceOnParticlesKernel.h b/src/lbm_mesapd_coupling/utility/AddForceOnParticlesKernel.h
index 703550f2e75a598e162765faafaa59db40498096..8a4598022d668408888b38ef692c3fcee08fd2b5 100644
--- a/src/lbm_mesapd_coupling/utility/AddForceOnParticlesKernel.h
+++ b/src/lbm_mesapd_coupling/utility/AddForceOnParticlesKernel.h
@@ -49,7 +49,7 @@ public:
    template< typename ParticleAccessor_T >
    void operator()(const size_t idx, ParticleAccessor_T& ac) const
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       mesa_pd::addForceAtomic(idx, ac, force_);
    }
diff --git a/src/lbm_mesapd_coupling/utility/AddHydrodynamicInteractionKernel.h b/src/lbm_mesapd_coupling/utility/AddHydrodynamicInteractionKernel.h
index 768b5a8eb280d4d4b6444b9182c22706d4b9bc08..b0bf799b9ead36b2c8a8bf30776bb1aeff34d0f3 100644
--- a/src/lbm_mesapd_coupling/utility/AddHydrodynamicInteractionKernel.h
+++ b/src/lbm_mesapd_coupling/utility/AddHydrodynamicInteractionKernel.h
@@ -43,7 +43,7 @@ public:
    template< typename ParticleAccessor_T >
    void operator()(const size_t idx, ParticleAccessor_T& ac) const
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       mesa_pd::addForceAtomic(idx, ac, ac.getHydrodynamicForce(idx));
       mesa_pd::addTorqueAtomic(idx, ac, ac.getHydrodynamicTorque(idx));
diff --git a/src/lbm_mesapd_coupling/utility/AverageHydrodynamicForceTorqueKernel.h b/src/lbm_mesapd_coupling/utility/AverageHydrodynamicForceTorqueKernel.h
index e354a68b97c0cebc6aa479b964ecd7e565a08549..6e3ee5f259b6728ad4b549d69b3292fbc4e3a12e 100644
--- a/src/lbm_mesapd_coupling/utility/AverageHydrodynamicForceTorqueKernel.h
+++ b/src/lbm_mesapd_coupling/utility/AverageHydrodynamicForceTorqueKernel.h
@@ -44,7 +44,7 @@ public:
    template< typename ParticleAccessor_T >
    void operator()(const size_t idx, ParticleAccessor_T& ac) const
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       auto hydForce = ac.getHydrodynamicForce(idx);
       auto hydTorque = ac.getHydrodynamicTorque(idx);
diff --git a/src/lbm_mesapd_coupling/utility/InitializeHydrodynamicForceTorqueForAveragingKernel.h b/src/lbm_mesapd_coupling/utility/InitializeHydrodynamicForceTorqueForAveragingKernel.h
index 4daa31e5a8d95be58f76b8e35f39c82f34044f99..4808002d31c4baf02ca810bc97f2c40b87ae9128 100644
--- a/src/lbm_mesapd_coupling/utility/InitializeHydrodynamicForceTorqueForAveragingKernel.h
+++ b/src/lbm_mesapd_coupling/utility/InitializeHydrodynamicForceTorqueForAveragingKernel.h
@@ -41,7 +41,7 @@ public:
    template< typename ParticleAccessor_T >
    void operator()(const size_t idx, ParticleAccessor_T& ac) const
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
       
       ac.setOldHydrodynamicForce( idx, ac.getHydrodynamicForce(idx) );
       ac.setOldHydrodynamicTorque( idx, ac.getHydrodynamicTorque(idx) );
diff --git a/src/lbm_mesapd_coupling/utility/OmegaBulkAdaption.h b/src/lbm_mesapd_coupling/utility/OmegaBulkAdaption.h
index f8a60c3a943e3e046d45038c8d86513f5c088c55..eea64184e5732889b0a1445c70a612708d093ccc 100644
--- a/src/lbm_mesapd_coupling/utility/OmegaBulkAdaption.h
+++ b/src/lbm_mesapd_coupling/utility/OmegaBulkAdaption.h
@@ -53,7 +53,7 @@ inline real_t omegaBulkFromOmega(real_t omega, real_t LambdaBulk = real_t(1))
 template< typename ParticleAccessor_T, typename ParticleSelector_T >
 class OmegaBulkAdapter
 {
-   static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+   static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
 public:
    OmegaBulkAdapter(const shared_ptr<StructuredBlockStorage> & blockStorage,
diff --git a/src/lbm_mesapd_coupling/utility/ParticleSelector.h b/src/lbm_mesapd_coupling/utility/ParticleSelector.h
index a18a91af44075a41384b513093b6062a180bac92..e9832268304d880c8d92571252d4fe6e671092b4 100644
--- a/src/lbm_mesapd_coupling/utility/ParticleSelector.h
+++ b/src/lbm_mesapd_coupling/utility/ParticleSelector.h
@@ -34,7 +34,7 @@ struct RegularParticlesSelector
    template< typename ParticleAccessor_T >
    bool inline operator()(const size_t particleIdx, const ParticleAccessor_T & ac) const
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
       return !mesa_pd::data::particle_flags::isSet( ac.getFlags(particleIdx), mesa_pd::data::particle_flags::FIXED) &&
              !mesa_pd::data::particle_flags::isSet( ac.getFlags(particleIdx), mesa_pd::data::particle_flags::GLOBAL);
    }
@@ -45,7 +45,7 @@ struct FixedParticlesSelector
    template< typename ParticleAccessor_T >
    bool inline operator()(const size_t particleIdx, const ParticleAccessor_T & ac) const
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
       return mesa_pd::data::particle_flags::isSet( ac.getFlags(particleIdx), mesa_pd::data::particle_flags::FIXED) &&
              !mesa_pd::data::particle_flags::isSet( ac.getFlags(particleIdx), mesa_pd::data::particle_flags::GLOBAL);
    }
@@ -56,7 +56,7 @@ struct GlobalParticlesSelector
    template< typename ParticleAccessor_T >
    bool inline operator()(const size_t particleIdx, const ParticleAccessor_T & ac) const
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
       return mesa_pd::data::particle_flags::isSet( ac.getFlags(particleIdx), mesa_pd::data::particle_flags::GLOBAL);
    }
 };
@@ -74,7 +74,7 @@ struct StokesNumberBasedSphereSelector
    template< typename ParticleAccessor_T >
    bool inline operator()(const size_t particleIdx, const ParticleAccessor_T & ac) const
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       lbm_mesapd_coupling::RegularParticlesSelector regularParticlesSelector;
       mesa_pd::kernel::SelectLocal localParticlesSelector;
diff --git a/src/lbm_mesapd_coupling/utility/ResetHydrodynamicForceTorqueKernel.h b/src/lbm_mesapd_coupling/utility/ResetHydrodynamicForceTorqueKernel.h
index 3cb84299928fc8b803f5e209af25191e23107abf..f45a2693bbdcd5be6f3af9e5d24d9a1c8a069b1f 100644
--- a/src/lbm_mesapd_coupling/utility/ResetHydrodynamicForceTorqueKernel.h
+++ b/src/lbm_mesapd_coupling/utility/ResetHydrodynamicForceTorqueKernel.h
@@ -41,7 +41,7 @@ public:
    template< typename ParticleAccessor_T>
    void operator()(const size_t idx, ParticleAccessor_T& ac) const
    {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, ParticleAccessor_T>::value, "Provide a valid accessor as template");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, ParticleAccessor_T>, "Provide a valid accessor as template");
 
       ac.setHydrodynamicForce(idx, Vector3<real_t>(real_t(0)));
       ac.setHydrodynamicTorque(idx, Vector3<real_t>(real_t(0)));
diff --git a/src/lbm_mesapd_coupling/utility/SubCyclingManager.cpp b/src/lbm_mesapd_coupling/utility/SubCyclingManager.cpp
index c9e09bed462bf18bb5e7db5bbe96491221cfbf45..895b4dac3af45b1213c2b54574e5be1f0c492127 100644
--- a/src/lbm_mesapd_coupling/utility/SubCyclingManager.cpp
+++ b/src/lbm_mesapd_coupling/utility/SubCyclingManager.cpp
@@ -27,7 +27,7 @@ namespace walberla {
 namespace lbm_mesapd_coupling {
 
 SubCyclingManager::SubCyclingManager(size_t numberOfSubCycles, shared_ptr<WcTimingPool> timingPool)
-   : numberOfSubCycles_(numberOfSubCycles), timingPool_(std::move(timingPool)), currentTimeStep_(0) {}
+   : numberOfSubCycles_(numberOfSubCycles), timingPool_(std::move(timingPool)) {}
 
 void SubCyclingManager::operator()() {
    executeBeforeFunctions();
diff --git a/src/lbm_mesapd_coupling/utility/SubCyclingManager.h b/src/lbm_mesapd_coupling/utility/SubCyclingManager.h
index b46ed444b60757f36628ea1f996f9d3fb7a1517c..c91d5fe707c2b86c913b3d139c2ee1a6731bf1ce 100644
--- a/src/lbm_mesapd_coupling/utility/SubCyclingManager.h
+++ b/src/lbm_mesapd_coupling/utility/SubCyclingManager.h
@@ -77,7 +77,7 @@ private:
 
    size_t numberOfSubCycles_;
    shared_ptr<WcTimingPool> timingPool_;
-   uint_t currentTimeStep_;
+   uint_t currentTimeStep_{0};
 
    std::vector<IdentifiedFunc> beforeFunctions_;
    std::vector<IdentifiedFunc> duringFunctions_;
diff --git a/src/lbm_mesapd_coupling/utility/virtualmass/AddVirtualForceTorqueKernel.h b/src/lbm_mesapd_coupling/utility/virtualmass/AddVirtualForceTorqueKernel.h
index 6f4a7ea35dc80f974a3e257760ff8e4cbf7fdd95..63b8c8fdbb2c9b04c315772d8800568bd8d999fc 100644
--- a/src/lbm_mesapd_coupling/utility/virtualmass/AddVirtualForceTorqueKernel.h
+++ b/src/lbm_mesapd_coupling/utility/virtualmass/AddVirtualForceTorqueKernel.h
@@ -50,7 +50,7 @@ public:
 
    template <typename Accessor_T>
    void operator()(const size_t idx, Accessor_T& ac) {
-      static_assert(std::is_base_of<mesa_pd::data::IAccessor, Accessor_T>::value, "please provide a valid accessor");
+      static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, Accessor_T>, "please provide a valid accessor");
 
       WALBERLA_CHECK_FLOAT_UNEQUAL(ac.getVirtualMass(idx), real_t(0.),
                                    "No virtual mass set on body. Was the virtualMass kernel not called before?");
diff --git a/src/lbm_mesapd_coupling/utility/virtualmass/InitializeVirtualMassKernel.h b/src/lbm_mesapd_coupling/utility/virtualmass/InitializeVirtualMassKernel.h
index 461dcafb0dfcacc4d2e2b6ec782bb90d09d063f5..c5e8e79a8919e7f4e54426da076bc149d1bdb3be 100644
--- a/src/lbm_mesapd_coupling/utility/virtualmass/InitializeVirtualMassKernel.h
+++ b/src/lbm_mesapd_coupling/utility/virtualmass/InitializeVirtualMassKernel.h
@@ -47,7 +47,7 @@ public:
 template <typename Accessor>
 inline void InitializeVirtualMassKernel::operator()(const size_t i, Accessor& ac, const real_t C_v, const real_t C_v_omega,
         const real_t fluidDensity) const {
-   static_assert(std::is_base_of<mesa_pd::data::IAccessor, Accessor>::value, "please provide a valid accessor");
+   static_assert(std::is_base_of_v<mesa_pd::data::IAccessor, Accessor>, "please provide a valid accessor");
 
    const real_t virtualMass = C_v * fluidDensity * ac.getVolume(i);
    ac.setVirtualMass(i, virtualMass);
diff --git a/src/mesh/MeshConversion.h b/src/mesh/MeshConversion.h
index 99aba1e6222031d9fcd3b3fa611efbaa58b4e112..3a2eca046d8ff48074a58ec962f9255d4b8d5896 100644
--- a/src/mesh/MeshConversion.h
+++ b/src/mesh/MeshConversion.h
@@ -88,9 +88,9 @@ void convertWalberlaToOpenMesh( const geometry::TriangleMesh & wbMesh, OpenMeshT
    std::map< uint32_t, typename OpenMeshType::VertexHandle > indexToOmVertexHandles;
 
    uint32_t ctr = 0;
-   for( auto v_it = wbMesh.getVertices().begin(); v_it != wbMesh.getVertices().end(); ++v_it )
+   for(const auto & v_it : wbMesh.getVertices())
    {
-      indexToOmVertexHandles[ ctr++ ] = omMesh.add_vertex( typename OpenMeshType::Point( toOpenMesh( *v_it ) ) );
+      indexToOmVertexHandles[ ctr++ ] = omMesh.add_vertex( typename OpenMeshType::Point( toOpenMesh( v_it ) ) );
    }
 
    WALBERLA_ASSERT_EQUAL( wbMesh.getVertexIndices().size() % size_t(3), size_t(0) );
diff --git a/src/mesh/blockforest/BlockWorkloadMemory.h b/src/mesh/blockforest/BlockWorkloadMemory.h
index 3e623b79ef594478ac548b68c597e2b8942da55a..cce5ea9bcfadbc6ac15b70f378f54de92364b192 100644
--- a/src/mesh/blockforest/BlockWorkloadMemory.h
+++ b/src/mesh/blockforest/BlockWorkloadMemory.h
@@ -40,9 +40,9 @@ template< typename DistanceObject >
 class MeshWorkloadMemory
 {
 public:
-   typedef blockforest::memory_t           memory_t;
-   typedef blockforest::workload_t         workload_t;
-   typedef typename DistanceObject::Scalar Scalar;
+   using memory_t = blockforest::memory_t;
+   using workload_t = blockforest::workload_t;
+   using Scalar = typename DistanceObject::Scalar;
 
    MeshWorkloadMemory( const shared_ptr< DistanceObject > & distanceObject, const Vector3< Scalar > & cellSize ) : distanceObject_( distanceObject ), cellSize_( cellSize ) { defaultInit(); }
    MeshWorkloadMemory( const shared_ptr< DistanceObject > & distanceObject, const Scalar cellSize ) : distanceObject_( distanceObject ), cellSize_( cellSize, cellSize, cellSize ) { defaultInit(); }
diff --git a/src/mesh/blockforest/RefinementSelection.h b/src/mesh/blockforest/RefinementSelection.h
index 13bd0a3dbf8f9ab4ed260945274e0d8a8770648b..ca1dc8a2a26ada38523e71a8d71745efada621f8 100644
--- a/src/mesh/blockforest/RefinementSelection.h
+++ b/src/mesh/blockforest/RefinementSelection.h
@@ -42,7 +42,7 @@ template< typename DistanceObject >
 class RefinementSelection
 {
 public:
-   typedef typename DistanceObject::Scalar Scalar;
+   using Scalar = typename DistanceObject::Scalar;
 
    RefinementSelection( const shared_ptr< DistanceObject > & distanceObject, const uint_t level, const real_t distance, real_t maxError ) : distanceObject_( distanceObject ), level_( level ), distance_( distance ), maxError_( maxError )  {  }
 
diff --git a/src/mesh/boundary/BoundaryInfo.h b/src/mesh/boundary/BoundaryInfo.h
index f41ca5b081ce87c55e966860bcffb634358c20db..71297b693945bcc02cac6ae840d93a0dc3cb0c84 100644
--- a/src/mesh/boundary/BoundaryInfo.h
+++ b/src/mesh/boundary/BoundaryInfo.h
@@ -30,8 +30,8 @@ namespace mesh {
 class BoundaryInfo
 {
 public:
-   typedef boundary::BoundaryUID UID;
-   typedef shared_ptr< boundary::BoundaryConfiguration > ConfigPtr;
+   using UID = boundary::BoundaryUID;
+   using ConfigPtr = shared_ptr<boundary::BoundaryConfiguration>;
 
    BoundaryInfo() : config_( boundary::BoundaryConfiguration::nullPtr() ) { }
    BoundaryInfo( const UID & uid ) : uid_( uid ), config_( boundary::BoundaryConfiguration::nullPtr() ) { }
diff --git a/src/mesh/boundary/BoundarySetup.cpp b/src/mesh/boundary/BoundarySetup.cpp
index 7003fa77260d548d8db0a7e73aac29728e818ec5..5646869039cd9dce883d11e395f3a00da8e66c28 100644
--- a/src/mesh/boundary/BoundarySetup.cpp
+++ b/src/mesh/boundary/BoundarySetup.cpp
@@ -33,12 +33,9 @@ BoundarySetup::BoundarySetup( const shared_ptr< StructuredBlockStorage > & struc
 
     if (doRefinementCorrection)
     {
-        try {
-            auto & blockForest = dynamic_cast< StructuredBlockForest & >( *structuredBlockStorage_ );
-            if( !blockForest.storesUniformBlockGrid() )
-                refinementCorrection( blockForest );
-        }
-        catch( const std::bad_cast &  ) {} // If it's not a BlockForest no refinement correction is done
+         auto & blockForest = dynamic_cast< StructuredBlockForest & >( *structuredBlockStorage_ );
+         if( !blockForest.storesUniformBlockGrid() )
+             refinementCorrection( blockForest );
     }
 }
 
@@ -208,7 +205,7 @@ void BoundarySetup::refinementCorrection( StructuredBlockForest & blockForest )
             {
                const auto c = stencil::c[i][*dir];
 
-               if( c == -1 ) 
+               if( c == -1 )
                {
                   coarseRegion.min()[i] -= cell_idx_c( numGhostLayers_ );
                   coarseRegion.max()[i] = cells.min()[i] + cell_idx_c( 2 * numGhostLayers_ - 1 );
diff --git a/src/mesh/boundary/BoundarySetup.h b/src/mesh/boundary/BoundarySetup.h
index 1993738499166006a8ef0a9eaa50589192709632..83186cda3a49b6d423d35f86b1e0ee0a35c9e4a3 100644
--- a/src/mesh/boundary/BoundarySetup.h
+++ b/src/mesh/boundary/BoundarySetup.h
@@ -46,9 +46,9 @@ namespace walberla::mesh {
 class BoundarySetup
 {
 public:
-   typedef field::GhostLayerField< uint8_t, uint_t(1) > VoxelizationField;
+   using VoxelizationField = field::GhostLayerField<uint8_t, uint_t(1)>;
 
-   typedef std::function< real_t ( const Vector3< real_t > &) > DistanceFunction;
+   using DistanceFunction = std::function<real_t (const Vector3<real_t> &)>;
 
    enum Location { INSIDE, OUTSIDE };
 
diff --git a/src/mesh/pe/DefaultTesselation.h b/src/mesh/pe/DefaultTesselation.h
index 9391779ca9b7f65ae93e1480407477acfbbf0046..119338385a3c0648a412e272b46d726870a17c35 100644
--- a/src/mesh/pe/DefaultTesselation.h
+++ b/src/mesh/pe/DefaultTesselation.h
@@ -34,8 +34,8 @@ template< typename MeshType >
 class DefaultTesselation
 {
 public:
-   typedef typename MeshType::VertexHandle VertexHandle;
-   typedef typename MeshType::FaceHandle   FaceHandle;
+   using VertexHandle = typename MeshType::VertexHandle;
+   using FaceHandle = typename MeshType::FaceHandle;
 
    void operator()( const walberla::pe::RigidBody & body, MeshType & mesh, std::vector<VertexHandle> & newVertices, std::vector<FaceHandle> & newFaces )
    {
diff --git a/src/mesh/pe/Types.h b/src/mesh/pe/Types.h
index 6d94fad9c463f5ee0ff1bd645bf8d7e16ec18834..2a507f38e0e67b40907eb0637acf9d19b8e405fa 100644
--- a/src/mesh/pe/Types.h
+++ b/src/mesh/pe/Types.h
@@ -27,9 +27,9 @@ namespace pe {
 
 class ConvexPolyhedron;
 
-typedef ConvexPolyhedron        ConvexPolyhedronType;    //!< Type of the convex polyhedron geometric primitive.
-typedef ConvexPolyhedron*       ConvexPolyhedronID;      //!< Handle for a convexpolyhedron primitive.
-typedef const ConvexPolyhedron* ConstConvexPolyhedronID; //!< Handle for a constant convex polyhedron primitive.
+using ConvexPolyhedronType = ConvexPolyhedron;    //!< Type of the convex polyhedron geometric primitive.
+using ConvexPolyhedronID = ConvexPolyhedron *;      //!< Handle for a convexpolyhedron primitive.
+using ConstConvexPolyhedronID = const ConvexPolyhedron *; //!< Handle for a constant convex polyhedron primitive.
 using   ConvexPolyhedronPtr   = std::unique_ptr<ConvexPolyhedron>;
 
 } // namespace pe
diff --git a/src/mesh/pe/raytracing/Intersects.h b/src/mesh/pe/raytracing/Intersects.h
index f9c772ff4d7dd10abb78df1cee97ba923e742b44..be6f0f3816dc23b3fd4b3791be6a6f347a4709bc 100644
--- a/src/mesh/pe/raytracing/Intersects.h
+++ b/src/mesh/pe/raytracing/Intersects.h
@@ -31,7 +31,7 @@ namespace raytracing {
 
 // Implemented following the description in
 // "FAST RAY - CONVEX POLYHEDRON INTERSECTION" by Eric Haines
-inline bool intersects(const mesh::pe::ConvexPolyhedronID poly, const Ray& ray, real_t& t_near, Vec3& n)
+inline bool intersects(mesh::pe::ConstConvexPolyhedronID poly, const Ray& ray, real_t& t_near, Vec3& n)
 {
    Ray transformedRay = ray.transformedToBF(poly);
 
@@ -80,4 +80,4 @@ inline bool intersects(const mesh::pe::ConvexPolyhedronID poly, const Ray& ray,
 
 } //namespace raytracing
 } //namespace pe
-} //namespace walberla
+} //namespace walberla
\ No newline at end of file
diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp b/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
index f8c1efee0549b2c2e89e41752f9413c98239a8d8..62f8b8fa200e0fdf739768cf6bba8d25c034d1b7 100644
--- a/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
+++ b/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
@@ -84,7 +84,7 @@ void ConvexPolyhedron::init( const Vec3& gpos,  const Quat& q,
    real_t maxSqRadius(0);
    for(auto vh : mesh_.vertices())
    {
-      real_t sqRadius = mesh_.point( vh ).sqrnorm();
+      real_t const sqRadius = mesh_.point( vh ).sqrnorm();
       if( sqRadius > maxSqRadius )
          maxSqRadius = sqRadius;
    }
@@ -219,7 +219,7 @@ Vec3 ConvexPolyhedron::support( const Vec3& d ) const
       }
    }
 
-   TriangleMesh::VertexHandle vh = supportVertex( d_loc, startVertex );
+   TriangleMesh::VertexHandle const vh = supportVertex( d_loc, startVertex );
 
    return pointFromBFtoWF( toWalberla( mesh_.point( vh ) ) );
 
diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedron.h b/src/mesh/pe/rigid_body/ConvexPolyhedron.h
index fcd74b627b18dae077c55132df54810e4d000b1c..0bbdc11b1b68adcea95b132c30812960bf0dcc7f 100644
--- a/src/mesh/pe/rigid_body/ConvexPolyhedron.h
+++ b/src/mesh/pe/rigid_body/ConvexPolyhedron.h
@@ -25,6 +25,7 @@
 // Includes
 //*************************************************************************************************
 
+#include <array>
 #include "mesh_common/TriangleMeshes.h"
 #include "mesh/pe/Types.h"
 
@@ -74,7 +75,7 @@ public:
    //**Destructor**********************************************************************************
    /*!\name Destructor */
    //@{
-   virtual ~ConvexPolyhedron();
+   ~ConvexPolyhedron() override;
    //@}
    //**********************************************************************************************
    //**********************************************************************************************
@@ -86,7 +87,7 @@ public:
    //**Get functions*******************************************************************************
    /*!\name Get functions */
    //@{
-   virtual real_t getVolume() const;
+   real_t getVolume() const override;
    real_t getSurfaceArea() const;
    const TriangleMesh & getMesh() const { return mesh_; }
    //@}
@@ -102,15 +103,15 @@ public:
    //**Output functions****************************************************************************
    /*!\name Output functions */
    //@{
-   virtual void print( std::ostream& os, const char* tab ) const;
+   void print( std::ostream& os, const char* tab ) const override;
    //@}
    //**********************************************************************************************
 
    //**Utility functions***************************************************************************
    /*!\name Utility functions */
    //@{
-   inline virtual Vec3 support( const Vec3& d ) const;
-   inline virtual Vec3 supportContactThreshold( const Vec3& d ) const;
+   inline Vec3 support( const Vec3& d ) const override;
+   inline Vec3 supportContactThreshold( const Vec3& d ) const override;
    //@}
    //**********************************************************************************************
 
@@ -118,22 +119,22 @@ protected:
    //**Utility functions***************************************************************************
    /*!\name Utility functions */
    //@{
-   virtual bool containsRelPointImpl ( real_t px, real_t py, real_t pz ) const;
-   virtual bool isSurfaceRelPointImpl( real_t px, real_t py, real_t pz ) const;
+   bool containsRelPointImpl ( real_t px, real_t py, real_t pz ) const override;
+   bool isSurfaceRelPointImpl( real_t px, real_t py, real_t pz ) const override;
    //@}
    //**********************************************************************************************
 
    //**Utility functions***************************************************************************
    /*!\name Utility functions */
    //@{
-   virtual void calcBoundingBox();  // Calculation of the axis-aligned bounding box
+   void calcBoundingBox() override;  // Calculation of the axis-aligned bounding box
    virtual TriangleMesh::VertexHandle supportVertex( const TriangleMesh::Normal & d, const TriangleMesh::VertexHandle startVertex ) const;
    //@}
    //**********************************************************************************************
 
    TriangleMesh mesh_;
    real_t boundingSphereRadius_;
-   TriangleMesh::VertexHandle octandVertices_[8];
+   std::array<TriangleMesh::VertexHandle, 8> octandVertices_;
 private:
    static id_t staticTypeID_;  //< type id of ConvexPolyhedron, will be set by SetBodyTypeIDs
    static void setStaticTypeID(id_t typeID) {staticTypeID_ = typeID;}
@@ -175,4 +176,4 @@ std::ostream& operator<<( std::ostream& os, ConstConvexPolyhedronID s );
 
 } // namespace pe
 } // namespace mesh
-} // namespace walberla
+} // namespace walberla
\ No newline at end of file
diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp b/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp
index e0685e8dbdf5544525b68b3f6e6dcff9279eaf89..06d42b77f9be32523763a2788b01daa8793df7bf 100644
--- a/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp
+++ b/src/mesh/pe/rigid_body/ConvexPolyhedronFactory.cpp
@@ -49,7 +49,7 @@ ConvexPolyhedronID createConvexPolyhedron( BodyStorage& globalStorage, BlockStor
    if( pointCloud.size() < size_t(4) )
       WALBERLA_ABORT( "Polyhedron needs at least 4 points!" );
    
-   shared_ptr< TriangleMesh > mesh = make_shared<TriangleMesh>();
+   shared_ptr< TriangleMesh > const mesh = make_shared<TriangleMesh>();
    mesh::QHull<TriangleMesh> qhull( pointCloud, mesh );
    qhull.run();
 
@@ -67,7 +67,7 @@ ConvexPolyhedronID createConvexPolyhedron( BodyStorage& globalStorage, BlockStor
 
    ConvexPolyhedronID poly = nullptr;
 
-   Vec3 centroid = toWalberla( computeCentroid( mesh ) );
+   Vec3 const centroid = toWalberla( computeCentroid( mesh ) );
    translate( mesh, -centroid );
 
    gpos += centroid;
diff --git a/src/mesh/pe/vtk/CommonDataSources.h b/src/mesh/pe/vtk/CommonDataSources.h
index 0cdb62a23ec882c6b2dc4706b093da976a38e203..15366fa9185907b0e4272fdf3d9571d6c8c3e5ce 100644
--- a/src/mesh/pe/vtk/CommonDataSources.h
+++ b/src/mesh/pe/vtk/CommonDataSources.h
@@ -42,10 +42,10 @@ template< typename MeshType, typename Tesselation, typename OutputType = uint64_
 class SIDVertexDataSource : public PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource< OutputType >
 {
 public:
-   typedef typename PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource< OutputType > Base;
-   typedef typename Base::Vertices Vertices;
-   typedef typename Base::value_type value_type;
-   typedef typename Base::BodyPointerVPropManager BodyPointerVPropManager;
+   using Base = typename PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource<OutputType>;
+   using Vertices = typename Base::Vertices;
+   using value_type = typename Base::value_type;
+   using BodyPointerVPropManager = typename Base::BodyPointerVPropManager;
 
    SIDVertexDataSource( const std::string & _name = "sid" )
       : Base( _name ) { }
@@ -69,10 +69,10 @@ template< typename MeshType, typename Tesselation, typename OutputType = uint64_
 class SIDFaceDataSource : public PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource< OutputType >
 {
 public:
-   typedef typename PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource< OutputType > Base;
-   typedef typename Base::Faces Faces;
-   typedef typename Base::value_type value_type;
-   typedef typename Base::BodyPointerFPropManager BodyPointerFPropManager;
+   using Base = typename PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource<OutputType>;
+   using Faces = typename Base::Faces;
+   using value_type = typename Base::value_type;
+   using BodyPointerFPropManager = typename Base::BodyPointerFPropManager;
 
    SIDFaceDataSource( const std::string & _name = "sid" )
       : Base( _name ) { }
@@ -96,10 +96,10 @@ template< typename MeshType, typename Tesselation, typename OutputType = uint64_
 class UIDVertexDataSource : public PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource< OutputType >
 {
 public:
-   typedef typename PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource< OutputType > Base;
-   typedef typename Base::Vertices Vertices;
-   typedef typename Base::value_type value_type;
-   typedef typename Base::BodyPointerVPropManager BodyPointerVPropManager;
+   using Base = typename PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource<OutputType>;
+   using Vertices = typename Base::Vertices;
+   using value_type = typename Base::value_type;
+   using BodyPointerVPropManager = typename Base::BodyPointerVPropManager;
 
    UIDVertexDataSource( const std::string & _name = "uid" )
       : Base( _name ) { }
@@ -123,10 +123,10 @@ template< typename MeshType, typename Tesselation, typename OutputType = uint64_
 class UIDFaceDataSource : public PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource< OutputType >
 {
 public:
-   typedef typename PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource< OutputType > Base;
-   typedef typename Base::Faces Faces;
-   typedef typename Base::value_type value_type;
-   typedef typename Base::BodyPointerFPropManager BodyPointerFPropManager;
+   using Base = typename PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource<OutputType>;
+   using Faces = typename Base::Faces;
+   using value_type = typename Base::value_type;
+   using BodyPointerFPropManager = typename Base::BodyPointerFPropManager;
 
    UIDFaceDataSource( const std::string & _name = "uid" )
       : Base( _name ) { }
@@ -151,10 +151,10 @@ template< typename MeshType, typename Tesselation, typename OutputType = real_t
 class LinearVelocityVertexDataSource : public PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource< OutputType >
 {
 public:
-   typedef typename PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource< OutputType > Base;
-   typedef typename Base::Vertices Vertices;
-   typedef typename Base::value_type value_type;
-   typedef typename Base::BodyPointerVPropManager BodyPointerVPropManager;
+   using Base = typename PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource<OutputType>;
+   using Vertices = typename Base::Vertices;
+   using value_type = typename Base::value_type;
+   using BodyPointerVPropManager = typename Base::BodyPointerVPropManager;
 
    LinearVelocityVertexDataSource( const std::string & _name = "linearVelocity" )
       : Base( _name ) { }
@@ -181,19 +181,19 @@ template< typename MeshType, typename Tesselation, typename OutputType = real_t
 class LinearVelocityFaceDataSource : public PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource< OutputType >
 {
 public:
-   typedef typename PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource< OutputType > Base;
-   typedef typename Base::Faces Faces;
-   typedef typename Base::value_type value_type;
-   typedef typename Base::BodyPointerFPropManager BodyPointerFPropManager;
+   using Base = typename PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource<OutputType>;
+   using Faces = typename Base::Faces;
+   using value_type = typename Base::value_type;
+   using BodyPointerFPropManager = typename Base::BodyPointerFPropManager;
 
    LinearVelocityFaceDataSource( const std::string & _name = "linearVelocity" )
       : Base( _name ) { }
 
    virtual ~LinearVelocityFaceDataSource() = default;
 
-   virtual uint_t numComponents() { return uint_t(3); }
+   uint_t numComponents() override { return uint_t(3); }
 
-   virtual void getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data, const BodyPointerFPropManager & bodyPointer )
+   void getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data, const BodyPointerFPropManager & bodyPointer ) override
    {
       data.reserve( size_t(3) * faces.size() );
 
@@ -213,10 +213,10 @@ template< typename MeshType, typename Tesselation, typename OutputType = real_t
 class AngularVelocityVertexDataSource : public PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource< OutputType >
 {
 public:
-   typedef typename PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource< OutputType > Base;
-   typedef typename Base::Vertices Vertices;
-   typedef typename Base::value_type value_type;
-   typedef typename Base::BodyPointerVPropManager BodyPointerVPropManager;
+   using Base = typename PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource<OutputType>;
+   using Vertices = typename Base::Vertices;
+   using value_type = typename Base::value_type;
+   using BodyPointerVPropManager = typename Base::BodyPointerVPropManager;
 
    AngularVelocityVertexDataSource( const std::string & _name = "angularVelocity" )
       : Base( _name ) { }
@@ -243,19 +243,19 @@ template< typename MeshType, typename Tesselation, typename OutputType = real_t
 class AngularVelocityFaceDataSource : public PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource< OutputType >
 {
 public:
-   typedef typename PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource< OutputType > Base;
-   typedef typename Base::Faces Faces;
-   typedef typename Base::value_type value_type;
-   typedef typename Base::BodyPointerFPropManager BodyPointerFPropManager;
+   using Base = typename PeVTKMeshWriter<MeshType, Tesselation>::template FaceDataSource<OutputType>;
+   using Faces = typename Base::Faces;
+   using value_type = typename Base::value_type;
+   using BodyPointerFPropManager = typename Base::BodyPointerFPropManager;
 
    AngularVelocityFaceDataSource( const std::string & _name = "angularVelocity" )
       : Base( _name ) { }
 
    virtual ~AngularVelocityFaceDataSource() = default;
 
-   virtual uint_t numComponents() { return uint_t(3); }
+   uint_t numComponents() override { return uint_t(3); }
 
-   virtual void getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data, const BodyPointerFPropManager & bodyPointer )
+   void getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data, const BodyPointerFPropManager & bodyPointer ) override
    {
       data.reserve( size_t(3) * faces.size() );
 
@@ -275,19 +275,19 @@ template< typename MeshType, typename Tesselation, typename OutputType = real_t
 class SurfaceVelocityVertexDataSource : public PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource< OutputType >
 {
 public:
-   typedef typename PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource< OutputType > Base;
-   typedef typename Base::Vertices Vertices;
-   typedef typename Base::value_type value_type;
-   typedef typename Base::BodyPointerVPropManager BodyPointerVPropManager;
+   using Base = typename PeVTKMeshWriter<MeshType, Tesselation>::template VertexDataSource<OutputType>;
+   using Vertices = typename Base::Vertices;
+   using value_type = typename Base::value_type;
+   using BodyPointerVPropManager = typename Base::BodyPointerVPropManager;
 
    SurfaceVelocityVertexDataSource( const std::string & _name = "surfaceVelocity" )
       : Base( _name ) { }
 
    virtual ~SurfaceVelocityVertexDataSource() = default;
 
-   virtual uint_t numComponents() { return uint_t(3); }
+   uint_t numComponents() override { return uint_t(3); }
 
-   virtual void getData( const MeshType & mesh, const Vertices & vertices, std::vector<value_type> & data, const BodyPointerVPropManager & bodyPointer )
+   void getData( const MeshType & mesh, const Vertices & vertices, std::vector<value_type> & data, const BodyPointerVPropManager & bodyPointer ) override
    {
       data.reserve( size_t(3) * vertices.size() );
 
diff --git a/src/mesh/pe/vtk/PeVTKMeshWriter.h b/src/mesh/pe/vtk/PeVTKMeshWriter.h
index 9c414c8b9610e0a767d4ca0fc02ff94c3ad483d7..d4b466c9d73cbf4c8fc7655570bdc2aa66122820 100644
--- a/src/mesh/pe/vtk/PeVTKMeshWriter.h
+++ b/src/mesh/pe/vtk/PeVTKMeshWriter.h
@@ -44,14 +44,14 @@ class PeVTKMeshWriter
 public:
    static_assert( MeshType::IsPolyMesh == 1, "PeVTKMeshWriter only works with polygonal meshes!" );
 
-   typedef typename MeshType::VertexHandle VertexHandle;
-   typedef typename MeshType::FaceHandle   FaceHandle;
-   typedef typename VTKMeshWriter<MeshType>::Faces    Faces;
-   typedef typename VTKMeshWriter<MeshType>::Vertices Vertices;
-   typedef typename OpenMesh::FPropHandleT< const walberla::pe::RigidBody * > BodyPointerFPropHandle;
-   typedef typename OpenMesh::VPropHandleT< const walberla::pe::RigidBody * > BodyPointerVPropHandle;
-   typedef OpenMesh::PropertyManager< BodyPointerFPropHandle, MeshType > BodyPointerFPropManager;
-   typedef OpenMesh::PropertyManager< BodyPointerVPropHandle, MeshType > BodyPointerVPropManager;
+   using VertexHandle = typename MeshType::VertexHandle;
+   using FaceHandle = typename MeshType::FaceHandle;
+   using Faces = typename VTKMeshWriter<MeshType>::Faces;
+   using Vertices = typename VTKMeshWriter<MeshType>::Vertices;
+   using BodyPointerFPropHandle = typename OpenMesh::FPropHandleT<const walberla::pe::RigidBody *>;
+   using BodyPointerVPropHandle = typename OpenMesh::VPropHandleT<const walberla::pe::RigidBody *>;
+   using BodyPointerFPropManager = OpenMesh::PropertyManager<BodyPointerFPropHandle, MeshType>;
+   using BodyPointerVPropManager = OpenMesh::PropertyManager<BodyPointerVPropHandle, MeshType>;
 
    PeVTKMeshWriter( const shared_ptr<BlockStorage> & storage, const BlockDataID bodyStorageId, const Tesselation & tesselation,
                     const std::string & identifier, const uint_t writeFrequency, const std::string & baseFolder = "vtk_out" )
@@ -66,7 +66,7 @@ public:
    {
    public:
       DataSource( const std::string & _name ) : name_( _name ) { }
-      typedef T value_type;
+      using value_type = T;
       virtual uint_t      numComponents() = 0;
       const std::string & name() { return name_; }
    protected:
@@ -77,9 +77,9 @@ public:
    class VertexDataSource : public DataSource<T>
    {
    public:
-      typedef typename DataSource<T>::value_type value_type;
-      typedef typename PeVTKMeshWriter::Vertices Vertices;
-      typedef typename PeVTKMeshWriter::BodyPointerVPropManager BodyPointerVPropManager;
+      using value_type = typename DataSource<T>::value_type;
+      using Vertices = typename PeVTKMeshWriter::Vertices;
+      using BodyPointerVPropManager = typename PeVTKMeshWriter::BodyPointerVPropManager;
 
       VertexDataSource( const std::string & _name ) : DataSource<T>( _name ) { }
       virtual void getData( const MeshType &, const Vertices &, std::vector<T> &, const BodyPointerVPropManager & ) = 0;
@@ -89,9 +89,9 @@ public:
    class FaceDataSource : public DataSource<T>
    {
    public:
-      typedef typename DataSource<T>::value_type value_type;
-      typedef typename PeVTKMeshWriter::Faces Faces;
-      typedef typename PeVTKMeshWriter::BodyPointerFPropManager BodyPointerFPropManager;
+      using value_type = typename DataSource<T>::value_type;
+      using Faces = typename PeVTKMeshWriter::Faces;
+      using BodyPointerFPropManager = typename PeVTKMeshWriter::BodyPointerFPropManager;
 
       FaceDataSource( const std::string & _name ) : DataSource<T>( _name ) { }
       virtual void getData( const MeshType &, const Faces &, std::vector<T> &, const BodyPointerFPropManager & ) = 0;
@@ -133,19 +133,19 @@ protected:
    class VertexDataSourceWrapper : public DistributedVTKMeshWriter<MeshType>::template VertexDataSource<T>
    {
    public:
-      typedef typename PeVTKMeshWriter::BodyPointerVPropManager BodyPointerVPropManager;
+      using BodyPointerVPropManager = typename PeVTKMeshWriter::BodyPointerVPropManager;
    
       VertexDataSourceWrapper( const shared_ptr<PeVTKMeshWriter::VertexDataSource<T>> & vertexDataSource, const BodyPointerVPropManager & bodyPointerProp )
          : DistributedVTKMeshWriter<MeshType>::template VertexDataSource<T>( vertexDataSource->name() ),
            vertexDataSource_(vertexDataSource), bodyPointerProp_(bodyPointerProp)
       { }
    
-      virtual void getData( const MeshType & mesh, const Vertices & vertices, std::vector<T> & data )
+      void getData( const MeshType & mesh, const Vertices & vertices, std::vector<T> & data ) override
       {
          return vertexDataSource_->getData( mesh, vertices, data, bodyPointerProp_ );
       };
    
-      virtual uint_t numComponents() { return vertexDataSource_->numComponents(); }
+      uint_t numComponents() override { return vertexDataSource_->numComponents(); }
    
    protected:
       shared_ptr<PeVTKMeshWriter::VertexDataSource<T>> vertexDataSource_;
@@ -156,19 +156,19 @@ protected:
    class FaceDataSourceWrapper : public DistributedVTKMeshWriter<MeshType>::template FaceDataSource<T>
    {
    public:
-      typedef typename PeVTKMeshWriter::BodyPointerFPropManager BodyPointerFPropManager;
+      using BodyPointerFPropManager = typename PeVTKMeshWriter::BodyPointerFPropManager;
 
       FaceDataSourceWrapper( const shared_ptr<PeVTKMeshWriter::FaceDataSource<T>> & faceDataSource, const BodyPointerFPropManager & bodyPointerProp )
          : DistributedVTKMeshWriter<MeshType>::template FaceDataSource<T>( faceDataSource->name() ),
          faceDataSource_(faceDataSource), bodyPointerProp_(bodyPointerProp)
       { }
 
-      virtual void getData( const MeshType & mesh, const Faces & faces, std::vector<T> & data )
+      void getData( const MeshType & mesh, const Faces & faces, std::vector<T> & data ) override
       {
          return faceDataSource_->getData( mesh, faces, data, bodyPointerProp_ );
       };
 
-      virtual uint_t numComponents() { return faceDataSource_->numComponents(); }
+      uint_t numComponents() override { return faceDataSource_->numComponents(); }
 
    protected:
       shared_ptr<PeVTKMeshWriter::FaceDataSource<T>> faceDataSource_;
diff --git a/src/mesh_common/DistanceComputations.h b/src/mesh_common/DistanceComputations.h
index 215ea75eb3a938059959e296b954d551af67e88d..61bdd1c095354ad91b4b4334f14fcb0485d39755 100644
--- a/src/mesh_common/DistanceComputations.h
+++ b/src/mesh_common/DistanceComputations.h
@@ -38,10 +38,10 @@ namespace mesh {
 template< typename MeshType >
 struct DistanceProperties
 {
-   typedef OpenMesh::VectorT< typename MeshType::Scalar, 2 > Vec2;
-   typedef OpenMesh::VectorT< typename MeshType::Scalar, 3 > Vec3;
-   typedef typename MeshType::Scalar Scalar;
-   typedef math::Matrix3<Scalar> Matrix;
+   using Vec2 = OpenMesh::VectorT<typename MeshType::Scalar, 2>;
+   using Vec3 = OpenMesh::VectorT<typename MeshType::Scalar, 3>;
+   using Scalar = typename MeshType::Scalar;
+   using Matrix = math::Matrix3<Scalar>;
 
    // Dummy constructor to suppress GCC 7 warnings
    DistanceProperties() : e0(real_t(0)), e1(real_t(0)), e2(real_t(0)),
@@ -89,12 +89,12 @@ template< typename MeshType >
 class TriangleDistance
 {
 public:
-   typedef typename MeshType::Scalar     Scalar;
-   typedef typename MeshType::Point      Point;
-   typedef typename MeshType::Normal     Normal;
-   typedef typename MeshType::FaceHandle FaceHandle;
-   typedef math::Vector3<Scalar>         Vec3;
-   typedef math::GenericAABB<Scalar>     BoundingBox;
+   using Scalar = typename MeshType::Scalar;
+   using Point = typename MeshType::Point;
+   using Normal = typename MeshType::Normal;
+   using FaceHandle = typename MeshType::FaceHandle;
+   using Vec3 = math::Vector3<Scalar>;
+   using BoundingBox = math::GenericAABB<Scalar>;
 
    TriangleDistance( const shared_ptr<MeshType> & mesh )
       : mesh_(mesh), distanceProperties_( *mesh, "DistanceProperties" ) 
@@ -185,7 +185,7 @@ public:
    void triangleToStream( const FaceHandle fh, std::ostream & os ) const;
 
 protected:
-   typedef typename OpenMesh::FPropHandleT< DistanceProperties<MeshType> > DistancePropertyHandle;
+   using DistancePropertyHandle = typename OpenMesh::FPropHandleT<DistanceProperties<MeshType>>;
 
    void computeNormals();
    void computeDistanceProperties();
diff --git a/src/mesh_common/MeshOperations.h b/src/mesh_common/MeshOperations.h
index ecaec8ebbb3b7ae91e557cfa052ef6f27e539b5e..3714050589d9358d0af92917bbea65fd0ca7e354 100644
--- a/src/mesh_common/MeshOperations.h
+++ b/src/mesh_common/MeshOperations.h
@@ -274,7 +274,7 @@ typename MeshType::Point computeCentroid( const MeshType & mesh )
    for( auto fIt = mesh.faces_begin(); fIt != mesh.faces_end(); ++fIt )
    {
       getVertexPositions( mesh, *fIt, v0, v1, v2 );
-      Scalar tetraVolume = ( v0 | ( v1 % v2 ) ) / Scalar(6);
+      Scalar const tetraVolume = ( v0 | ( v1 % v2 ) ) / Scalar(6);
       // v0 + v1 + v2 + 0 / 4 is the tetraeder centroid
       centroid += tetraVolume * (v0 + v1 + v2);
       volume += tetraVolume;
@@ -309,7 +309,7 @@ Matrix3<typename MeshType::Scalar> computeInertiaTensor( const MeshType & mesh )
    for( auto fIt = mesh.faces_begin(); fIt != mesh.faces_end(); ++fIt )
    {
       getVertexPositions( mesh, *fIt, v0, v1, v2 );
-      Scalar tetraVolume = ( v0 | ( v1 % v2 ) );
+      Scalar const tetraVolume = ( v0 | ( v1 % v2 ) );
       p00 += tetraVolume * deltaP_jk(0,0);
       p01 += tetraVolume * deltaP_jk(0,1);
       p02 += tetraVolume * deltaP_jk(0,2);
@@ -387,12 +387,12 @@ void computeMassProperties(const MeshType & mesh, typename MeshType::Scalar dens
    typedef typename MeshType::Point Point;
    typedef typename MeshType::Scalar Scalar;
 
-   const Scalar mult[10] = {Scalar(1)/Scalar(6),
-                            Scalar(1)/Scalar(24), Scalar(1)/Scalar(24), Scalar(1)/Scalar(24),
-                            Scalar(1)/Scalar(60), Scalar(1)/Scalar(60), Scalar(1)/Scalar(60),
-                            Scalar(1)/Scalar(120), Scalar(1)/Scalar(120), Scalar(1)/Scalar(120)};
+   std::array<const Scalar, 10> mult {Scalar(1)/Scalar(6),
+                                      Scalar(1)/Scalar(24), Scalar(1)/Scalar(24), Scalar(1)/Scalar(24),
+                                      Scalar(1)/Scalar(60), Scalar(1)/Scalar(60), Scalar(1)/Scalar(60),
+                                      Scalar(1)/Scalar(120), Scalar(1)/Scalar(120), Scalar(1)/Scalar(120)};
 
-   Scalar intg[10] = {0,0,0,0,0,0,0,0,0,0};
+   std::array<Scalar, 10> intg{0,0,0,0,0,0,0,0,0,0};
 
    auto subExpr = [](Scalar& w0, Scalar& w1, Scalar& w2,
          Scalar& f1, Scalar& f2, Scalar& f3,
@@ -779,4 +779,4 @@ void vertexToFaceColor( const MeshType & mesh, const typename MeshType::Color& d
 
 
 } // namespace mesh
-} // namespace walberla
+} // namespace walberla
\ No newline at end of file
diff --git a/src/mesh_common/PolyMeshes.h b/src/mesh_common/PolyMeshes.h
index dc2e1f3f7abb8b7c9891be2083f58c0f7d29215f..93107716aefc21e58b175756e2d1c2347b16f457 100644
--- a/src/mesh_common/PolyMeshes.h
+++ b/src/mesh_common/PolyMeshes.h
@@ -28,9 +28,9 @@
 namespace walberla {
 namespace mesh {
 
-typedef OpenMesh::PolyMesh_ArrayKernelT<OpenMesh::Python::MeshTraits> PythonPolyMesh;
-typedef OpenMesh::PolyMesh_ArrayKernelT<RealTraits>                   PolyMesh;
-typedef OpenMesh::PolyMesh_ArrayKernelT<FloatTraits>                  FloatPolyMesh;
+using PythonPolyMesh = OpenMesh::PolyMesh_ArrayKernelT<OpenMesh::Python::MeshTraits>;
+using PolyMesh = OpenMesh::PolyMesh_ArrayKernelT<RealTraits>;
+using FloatPolyMesh = OpenMesh::PolyMesh_ArrayKernelT<FloatTraits>;
 
 } // namespace mesh
 } // namespace walberla
\ No newline at end of file
diff --git a/src/mesh_common/QHull.h b/src/mesh_common/QHull.h
index 6011ce09b5a4ee3fc6d9edb36e08a4f82859ea54..2c698afcc19c2c06dcd7ffddf9922a9bef18ce2a 100644
--- a/src/mesh_common/QHull.h
+++ b/src/mesh_common/QHull.h
@@ -62,11 +62,11 @@ class QHull
 public:
    static_assert( MeshType::IsTriMesh == 1, "QHull only works on triangular meshes!" );
 
-   typedef typename MeshType::Point Point;
-   typedef typename MeshType::Scalar Scalar;
-   typedef typename MeshType::FaceHandle FaceHandle;
-   typedef typename MeshType::VertexHandle VertexHandle;
-   typedef typename MeshType::HalfedgeHandle HalfedgeHandle;
+   using Point = typename MeshType::Point;
+   using Scalar = typename MeshType::Scalar;
+   using FaceHandle = typename MeshType::FaceHandle;
+   using VertexHandle = typename MeshType::VertexHandle;
+   using HalfedgeHandle = typename MeshType::HalfedgeHandle;
 
    QHull( const std::vector< Vector3<real_t> > & pointCloud, const shared_ptr<MeshType> & mesh = make_shared< MeshType >());
    QHull( const std::vector< Point > & pointCloud, const shared_ptr<MeshType> & mesh = make_shared< MeshType >() );
@@ -108,7 +108,7 @@ private:
    
    std::vector< Point > pointCloud_; /// The initial point cloud
    shared_ptr< MeshType > mesh_; /// The generated convex mesh
-   typedef typename OpenMesh::FPropHandleT< std::vector<Point> > VisiblePointsPropertyHandle;
+   using VisiblePointsPropertyHandle = typename OpenMesh::FPropHandleT<std::vector<Point>>;
    OpenMesh::PropertyManager< VisiblePointsPropertyHandle, MeshType > visiblePoints_; /// Property storing the points of a certain face
    std::priority_queue<FaceHandle, std::vector<FaceHandle>, QHullFaceSorter<MeshType> > queue_; /// queue to prioritize faces
 
@@ -159,20 +159,20 @@ template< typename MeshType >
 class QHullPointDataSource : public vtk::PointDataSource
 {
 public:
-   typedef typename MeshType::Point Point;
-   typedef typename MeshType::Scalar Scalar;
+   using Point = typename MeshType::Point;
+   using Scalar = typename MeshType::Scalar;
 
    QHullPointDataSource( const QHull<MeshType> & qhull ) : qhull_( qhull ) {}
 
-   virtual std::vector< Attributes > getAttributes() const 
+   std::vector< Attributes > getAttributes() const override 
    {
       std::vector< Attributes > attributes; 
-      attributes.push_back( Attributes("Int32", "index", uint_t(1)) );
+      attributes.emplace_back("Int32", "index", uint_t(1) );
       return attributes;
    }
 
-   virtual std::vector< Vector3< real_t > > getPoints() { return points_; }
-   virtual void configure()
+   std::vector< Vector3< real_t > > getPoints() override { return points_; }
+   void configure() override
    {
       points_.clear();
       indices_.clear();
@@ -185,12 +185,12 @@ public:
       }
    };
 
-   virtual void push( std::ostream& os,  const uint_t /*data*/, const uint_t point, const uint_t /*component*/ )
+   void push( std::ostream& os,  const uint_t /*data*/, const uint_t point, const uint_t /*component*/ ) override
    {
       os << indices_[point];
    };
 
-   virtual void push( vtk::Base64Writer& b64, const uint_t /*data*/, const uint_t point, const uint_t /*component*/ )
+   void push( vtk::Base64Writer& b64, const uint_t /*data*/, const uint_t point, const uint_t /*component*/ ) override
    {
       b64 << indices_[point];
    };
@@ -253,7 +253,7 @@ void QHull<MeshType>::iteration()
    });
 
    // Remove the point from the remaining points
-   Point p = *it;
+   Point const p = *it;
    visiblePoints_[fh].erase(it);
 
    // Delete all faces visible by p
@@ -323,7 +323,7 @@ void QHull<MeshType>::createInitialSimplex()
       }
 
    // find the most distant point in ep to the previously found line
-   Point dir = base0 - base1;
+   Point const dir = base0 - base1;
    Scalar maxDist = Scalar(0);
    Point base2;
 
@@ -338,8 +338,8 @@ void QHull<MeshType>::createInitialSimplex()
    }
 
    // find the most distant point in the cloud to the previously found triangle
-   Point basePlaneNormal = (base0 - base2) % (base1 - base2);
-   Scalar basePlaneOffset = base0 | basePlaneNormal;
+   Point const basePlaneNormal = (base0 - base2) % (base1 - base2);
+   Scalar const basePlaneOffset = base0 | basePlaneNormal;
 
    Point tip;
    Scalar maxDistanceToBasePlane =  Scalar(0);
@@ -417,7 +417,7 @@ void QHull<MeshType>::deleteVisibleFaces( const FaceHandle startFaceHandle, cons
    // Move the horizon farther outwards
    while(!q.empty())
    {
-      HalfedgeHandle heh = q.front();
+      HalfedgeHandle const heh = q.front();
       q.pop();
 
       // If the face belonging to the half edge  has already been removed just go on with the next half edge
@@ -451,13 +451,13 @@ void QHull<MeshType>::addNewFaces( const Point & p )
 {
    newFaces_.clear();
 
-   VertexHandle v0h = mesh_->add_vertex(p);
+   VertexHandle const v0h = mesh_->add_vertex(p);
    for(const auto heh : horizon_)
    {
-      VertexHandle v1h = mesh_->to_vertex_handle(heh);
-      VertexHandle v2h = mesh_->from_vertex_handle(heh);
+      VertexHandle const v1h = mesh_->to_vertex_handle(heh);
+      VertexHandle const v2h = mesh_->from_vertex_handle(heh);
 
-      FaceHandle fh = mesh_->add_face( v0h, v1h, v2h );
+      FaceHandle const fh = mesh_->add_face( v0h, v1h, v2h );
       mesh_->update_normal(fh);
       newFaces_.push_back(fh);         
    }
diff --git a/src/mesh_common/TriangleMeshes.h b/src/mesh_common/TriangleMeshes.h
index 9d3aeb1b1720869690cfc1e8705bd659c941aee9..0f23da56999817e8836875b0ac359d5d8132204d 100644
--- a/src/mesh_common/TriangleMeshes.h
+++ b/src/mesh_common/TriangleMeshes.h
@@ -42,13 +42,13 @@ namespace Python {
 
 struct MeshTraits : public OpenMesh::DefaultTraits {
    /** Use double precision points */
-   typedef OpenMesh::Vec3d Point;
+   using Point = OpenMesh::Vec3d;
 
    /** Use double precision normals */
-   typedef OpenMesh::Vec3d Normal;
+   using Normal = OpenMesh::Vec3d;
 
    /** Use RGBA colors */
-   typedef OpenMesh::Vec4f Color;
+   using Color = OpenMesh::Vec4f;
 };
 
 }
@@ -58,22 +58,22 @@ struct MeshTraits : public OpenMesh::DefaultTraits {
 namespace walberla {
 namespace mesh {
 
-typedef OpenMesh::TriMesh_ArrayKernelT<OpenMesh::Python::MeshTraits> PythonTriangleMesh;
+using PythonTriangleMesh = OpenMesh::TriMesh_ArrayKernelT<OpenMesh::Python::MeshTraits>;
 
 struct RealTraits : public OpenMesh::DefaultTraits
 {
-   typedef OpenMesh::VectorT<real_t, 3> Point;
-   typedef OpenMesh::VectorT<real_t, 3> Normal;
+   using Point = OpenMesh::VectorT<real_t, 3>;
+   using Normal = OpenMesh::VectorT<real_t, 3>;
 };
-typedef OpenMesh::TriMesh_ArrayKernelT<RealTraits> TriangleMesh;
+using TriangleMesh = OpenMesh::TriMesh_ArrayKernelT<RealTraits>;
 
 
 struct FloatTraits : public OpenMesh::DefaultTraits
 {
-   typedef OpenMesh::Vec3f Point;
-   typedef OpenMesh::Vec3f Normal;
+   using Point = OpenMesh::Vec3f;
+   using Normal = OpenMesh::Vec3f;
 };
-typedef OpenMesh::TriMesh_ArrayKernelT<FloatTraits> FloatTriangleMesh;
+using FloatTriangleMesh = OpenMesh::TriMesh_ArrayKernelT<FloatTraits>;
 
 
 template< typename MeshType >
diff --git a/src/mesh_common/distance_octree/BranchNode.h b/src/mesh_common/distance_octree/BranchNode.h
index d7017b0b33d0f1ddc4d7596ff4abc427db71fd44..aaa2b5a209b345c160532ac82767a4a247aa5e12 100644
--- a/src/mesh_common/distance_octree/BranchNode.h
+++ b/src/mesh_common/distance_octree/BranchNode.h
@@ -1,15 +1,15 @@
 //======================================================================================================================
 //
-//  This file is part of waLBerla. waLBerla is free software: you can 
+//  This file is part of waLBerla. waLBerla 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.
-//  
-//  waLBerla 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 
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
@@ -42,40 +42,40 @@ template <typename MeshType>
 class BranchNode : public Node<MeshType>
 {
 public:
-   typedef typename Node<MeshType>::Point      Point;
-   typedef typename Node<MeshType>::Normal     Normal;
-   typedef typename Node<MeshType>::Scalar     Scalar;  
-   typedef typename Node<MeshType>::FaceHandle FaceHandle; 
-   typedef typename Node<MeshType>::AABB       AABB;
-   
+   using Point = typename Node<MeshType>::Point;
+   using Normal = typename Node<MeshType>::Normal;
+   using Scalar = typename Node<MeshType>::Scalar;
+   using FaceHandle = typename Node<MeshType>::FaceHandle;
+   using AABB = typename Node<MeshType>::AABB;
+
    template< typename InputIterator >
    BranchNode( const shared_ptr< TriangleDistance<MeshType> > & triDistance, InputIterator beginFh, InputIterator endFh,
                uint_t maxDepth, uint_t minNumTriangles );
 
-   virtual ~BranchNode() { for( int i = 0; i < 8; ++i ) delete children_[i]; }
+   ~BranchNode() override { for( uint_t i = 0; i < 8; ++i ) delete children_[i]; }
 
 
-   virtual Scalar sqSignedDistance( const Point & p ) const;
-   virtual Scalar sqSignedDistance( const Point & p, FaceHandle & closestTriangle ) const;
-   virtual Scalar sqSignedDistance( const Point & p, Point & closestPoint ) const ;
-   virtual Scalar sqSignedDistance( const Point & p, Point & closestPoint, Normal & normal ) const;
+   Scalar sqSignedDistance( const Point & p ) const override;
+   Scalar sqSignedDistance( const Point & p, FaceHandle & closestTriangle ) const override;
+   Scalar sqSignedDistance( const Point & p, Point & closestPoint ) const override ;
+   Scalar sqSignedDistance( const Point & p, Point & closestPoint, Normal & normal ) const override;
 
-   virtual Scalar sqDistance( const Point & p ) const;
-   virtual Scalar sqDistance( const Point & p, FaceHandle & closestTriangle ) const;
-   virtual Scalar sqDistance( const Point & p, Point & closestPoint ) const;
-   virtual Scalar sqDistance( const Point & p, Point & closestPoint, Normal & normal ) const;
-
-   virtual Scalar getRayDistanceToMeshObject(const Point & ray_origin, const Point & normalised_ray_direction) const override;
-
-   inline uint_t numTriangles() const;
-   void numTrianglesToStream( std::ostream & os, const uint_t level ) const;
-   inline virtual uint_t height() const;
-   virtual uint_t numChildren() const { return uint_t(8); };
-   virtual const Node<MeshType> * getChild( const uint_t idx ) const { WALBERLA_ASSERT_LESS( idx, 8 ); return children_[idx]; };
+   Scalar sqDistance( const Point & p ) const override;
+   Scalar sqDistance( const Point & p, FaceHandle & closestTriangle ) const override;
+   Scalar sqDistance( const Point & p, Point & closestPoint ) const override;
+   Scalar sqDistance( const Point & p, Point & closestPoint, Normal & normal ) const override;
 
+   Scalar getRayDistanceToMeshObject(const Point & ray_origin, const Point & normalised_ray_direction) const override;
+   
+   inline uint_t numTriangles() const override;
+   void numTrianglesToStream( std::ostream & os, const uint_t level ) const override;
+   inline uint_t height() const override;
+   uint_t numChildren() const override { return uint_t(8); };
+   const Node<MeshType> * getChild( const uint_t idx ) const override { WALBERLA_ASSERT_LESS( idx, 8 ); return children_[idx]; };
+
+   BranchNode( const BranchNode & other ) = delete;
+   BranchNode & operator=( const BranchNode & other ) = delete;
 private:
-   BranchNode( const BranchNode & other );
-   BranchNode & operator=( const BranchNode & other );
 
    struct ChildInfo
    {
@@ -139,7 +139,7 @@ private:
    };
 
 protected:
-   const Node<MeshType> * children_[8];
+   std::array<const Node<MeshType> *, 8> children_;
 };
 
 
@@ -157,7 +157,7 @@ template <typename MeshType>
 uint_t BranchNode<MeshType>::height() const
 {
    uint_t maxChildHeight = children_[0]->height();
-   for( int i = 1; i < 8; ++i )
+   for( uint_t i = 1; i < 8; ++i )
    {
       uint_t childHeight = children_[i]->height();
       if( childHeight > maxChildHeight )
@@ -174,14 +174,14 @@ BranchNode<MeshType>::BranchNode( const shared_ptr< TriangleDistance<MeshType> >
                                   uint_t maxDepth, uint_t minNumTriangles )
    : Node<MeshType>( triDistance->getMesh(), beginFh, endFh )
 {
-   for( int i = 0; i < 8; ++i )
+   for( uint_t i = 0; i < 8; ++i )
       children_[i] = nullptr;
 
    const auto &    min = this->aabb_.minCorner();
    const auto &    max = this->aabb_.maxCorner();
    const auto   center = this->aabb_.center();
 
-   AABB childAABBs[8] = {
+   std::array<AABB, 8> childAABBs = {
       AABB::createFromMinMaxCorner(    min[0],    min[1],    min[2], center[0], center[1], center[2] ),
       AABB::createFromMinMaxCorner(    min[0],    min[1], center[2], center[0], center[1],    max[2] ),
       AABB::createFromMinMaxCorner(    min[0], center[1],    min[2], center[0],    max[1], center[2] ),
@@ -194,8 +194,8 @@ BranchNode<MeshType>::BranchNode( const shared_ptr< TriangleDistance<MeshType> >
 
    uint_t theNumTriangles = uint_c( std::distance( beginFh, endFh ) );
 
-   std::vector<bool> triangleUsed( theNumTriangles, false );
-   std::vector<FaceHandle> childTriangles[8];
+   std::vector<bool> const triangleUsed( theNumTriangles, false );
+   std::array<std::vector<FaceHandle>, 8> childTriangles;
 
    for( auto fhIt = beginFh; fhIt != endFh; ++fhIt )
    {
@@ -228,16 +228,16 @@ BranchNode<MeshType>::BranchNode( const shared_ptr< TriangleDistance<MeshType> >
 template <typename MeshType>
 typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqSignedDistance( const Point & p ) const
 {
-   ChildInfo childinfos[8] = {
+   std::array<ChildInfo, 8> childinfos = {
       ChildInfo( children_[0], p ), ChildInfo( children_[1], p ),
       ChildInfo( children_[2], p ), ChildInfo( children_[3], p ),
       ChildInfo( children_[4], p ), ChildInfo( children_[5], p ),
       ChildInfo( children_[6], p ), ChildInfo( children_[7], p )
    };
-   std::sort( childinfos, childinfos + 8 );
+   std::sort( std::begin(childinfos), std::end(childinfos) );
 
    Scalar absMinSqSignedDistance = childinfos[0].child->sqSignedDistance( p );
-   for( int i = 1; i < 8; ++i )
+   for( uint_t i = 1; i < 8; ++i )
    {
       WALBERLA_ASSERT_NOT_NULLPTR( childinfos[i].child );
       if( std::fabs( absMinSqSignedDistance ) < childinfos[i].minSqBoxDist )
@@ -257,17 +257,17 @@ typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqSignedDistance( co
 template <typename MeshType>
 typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqSignedDistance( const Point & p, FaceHandle & closestTriangle ) const
 {
-   ChildInfo childinfos[8] = {
+   std::array<ChildInfo, 8> childinfos = {
       ChildInfo( children_[0], p ), ChildInfo( children_[1], p ),
       ChildInfo( children_[2], p ), ChildInfo( children_[3], p ),
       ChildInfo( children_[4], p ), ChildInfo( children_[5], p ),
       ChildInfo( children_[6], p ), ChildInfo( children_[7], p )
    };
-   std::sort( childinfos, childinfos + 8 );
+   std::sort( std::begin(childinfos), std::end(childinfos) );
 
    Scalar absMinSqSignedDistance = childinfos[0].child->sqSignedDistance( p, closestTriangle );
 
-   for( int i = 1; i < 8; ++i )
+   for( uint_t i = 1; i < 8; ++i )
    {
       WALBERLA_ASSERT_NOT_NULLPTR( childinfos[i].child );
       if( std::fabs( absMinSqSignedDistance ) < childinfos[i].minSqBoxDist )
@@ -290,17 +290,17 @@ typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqSignedDistance( co
 template <typename MeshType>
 typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqSignedDistance( const Point & p, Point & closestPoint ) const
 {
-   ChildInfo childinfos[8] = {
+   std::array<ChildInfo, 8> childinfos = {
       ChildInfo( children_[0], p ), ChildInfo( children_[1], p ),
       ChildInfo( children_[2], p ), ChildInfo( children_[3], p ),
       ChildInfo( children_[4], p ), ChildInfo( children_[5], p ),
       ChildInfo( children_[6], p ), ChildInfo( children_[7], p )
    };
-   std::sort( childinfos, childinfos + 8 );
+   std::sort( std::begin(childinfos), std::end(childinfos) );
 
    Scalar absMinSqSignedDistance = childinfos[0].child->sqSignedDistance( p, closestPoint );
 
-   for( int i = 1; i < 8; ++i )
+   for( uint_t i = 1; i < 8; ++i )
    {
       WALBERLA_ASSERT_NOT_NULLPTR( childinfos[i].child );
       if( std::fabs( absMinSqSignedDistance ) < childinfos[i].minSqBoxDist )
@@ -323,17 +323,17 @@ typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqSignedDistance( co
 template <typename MeshType>
 typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqSignedDistance( const Point & p, Point & closestPoint, Normal & normal ) const
 {
-   ChildInfo childinfos[8] = {
+   std::array<ChildInfo, 8> childinfos = {
       ChildInfo( children_[0], p ), ChildInfo( children_[1], p ),
       ChildInfo( children_[2], p ), ChildInfo( children_[3], p ),
       ChildInfo( children_[4], p ), ChildInfo( children_[5], p ),
       ChildInfo( children_[6], p ), ChildInfo( children_[7], p )
    };
-   std::sort( childinfos, childinfos + 8 );
+   std::sort( std::begin(childinfos), std::end(childinfos) );
 
    Scalar absMinSqSignedDistance = childinfos[0].child->sqSignedDistance( p, closestPoint, normal );
 
-   for( int i = 1; i < 8; ++i )
+   for( uint_t i = 1; i < 8; ++i )
    {
       WALBERLA_ASSERT_NOT_NULLPTR( childinfos[i].child );
       if( std::fabs( absMinSqSignedDistance ) < childinfos[i].minSqBoxDist )
@@ -361,16 +361,16 @@ typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqDistance( const Po
 {
    //WALBERLA_ASSERT( getAABB().contains( toWalberla( p ) ) );
 
-   ChildInfo childinfos[8] = {
+   std::array<ChildInfo, 8> childinfos = {
       ChildInfo( children_[0], p ), ChildInfo( children_[1], p ),
       ChildInfo( children_[2], p ), ChildInfo( children_[3], p ),
       ChildInfo( children_[4], p ), ChildInfo( children_[5], p ),
       ChildInfo( children_[6], p ), ChildInfo( children_[7], p )
    };
-   std::sort( childinfos, childinfos + 8 );
+   std::sort( std::begin(childinfos), std::end(childinfos) );
 
    Scalar absMinSqDistance = childinfos[0].child->sqDistance( p );
-   for(int i = 1; i < 8; ++i)
+   for(uint_t i = 1; i < 8; ++i)
    {
       WALBERLA_ASSERT_NOT_NULLPTR( childinfos[i].child );
       if( absMinSqDistance < childinfos[i].minSqBoxDist)
@@ -390,17 +390,17 @@ typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqDistance( const Po
 template <typename MeshType>
 typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqDistance( const Point & p, FaceHandle & closestTriangle ) const
 {
-   ChildInfo childinfos[8] = {
+   std::array<ChildInfo, 8> childinfos = {
       ChildInfo( children_[0], p ), ChildInfo( children_[1], p ),
       ChildInfo( children_[2], p ), ChildInfo( children_[3], p ),
       ChildInfo( children_[4], p ), ChildInfo( children_[5], p ),
       ChildInfo( children_[6], p ), ChildInfo( children_[7], p )
    };
-   std::sort( childinfos, childinfos + 8 );
+   std::sort( std::begin(childinfos), std::end(childinfos) );
 
    Scalar absMinSqDistance = childinfos[0].child->sqDistance( p, closestTriangle );
 
-   for(int i = 1; i < 8; ++i)
+   for(uint_t i = 1; i < 8; ++i)
    {
       WALBERLA_ASSERT_NOT_NULLPTR( childinfos[i].child );
       if( absMinSqDistance < childinfos[i].minSqBoxDist)
@@ -423,17 +423,17 @@ typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqDistance( const Po
 template <typename MeshType>
 typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqDistance( const Point & p, Point & closestPoint ) const
 {
-   ChildInfo childinfos[8] = {
+   std::array<ChildInfo, 8> childinfos = {
       ChildInfo( children_[0], p ), ChildInfo( children_[1], p ),
       ChildInfo( children_[2], p ), ChildInfo( children_[3], p ),
       ChildInfo( children_[4], p ), ChildInfo( children_[5], p ),
       ChildInfo( children_[6], p ), ChildInfo( children_[7], p )
    };
-   std::sort( childinfos, childinfos + 8 );
+   std::sort( std::begin(childinfos), std::end(childinfos) );
 
    Scalar absMinSqDistance = childinfos[0].child->sqDistance( p, closestPoint );
 
-   for(int i = 1; i < 8; ++i)
+   for(uint_t i = 1; i < 8; ++i)
    {
       WALBERLA_ASSERT_NOT_NULLPTR( childinfos[i].child );
       if( absMinSqDistance < childinfos[i].minSqBoxDist)
@@ -456,17 +456,17 @@ typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqDistance( const Po
 template <typename MeshType>
 typename BranchNode<MeshType>::Scalar BranchNode<MeshType>::sqDistance( const Point & p, Point & closestPoint, Normal & normal ) const
 {
-   ChildInfo childinfos[8] = {
+   std::array<ChildInfo, 8> childinfos = {
       ChildInfo( children_[0], p ), ChildInfo( children_[1], p ),
       ChildInfo( children_[2], p ), ChildInfo( children_[3], p ),
       ChildInfo( children_[4], p ), ChildInfo( children_[5], p ),
       ChildInfo( children_[6], p ), ChildInfo( children_[7], p )
    };
-   std::sort( childinfos, childinfos + 8 );
+   std::sort( std::begin(childinfos), std::end(childinfos) );
 
    Scalar absMinSqDistance = childinfos[0].child->sqDistance( p, closestPoint, normal );
 
-   for(int i = 1; i < 8; ++i)
+   for(uint_t i = 1; i < 8; ++i)
    {
       WALBERLA_ASSERT_NOT_NULLPTR( childinfos[i].child );
       if(absMinSqDistance < childinfos[i].minSqBoxDist)
@@ -525,7 +525,7 @@ void BranchNode<MeshType>::numTrianglesToStream( std::ostream & os, const uint_t
    for( uint_t i = 0; i < level; ++i )
       os << "   ";
    os << numTriangles() << "\n";
-   for( int i = 0; i < 8; ++i )
+   for( uint_t i = 0; i < 8; ++i )
       children_[i]->numTrianglesToStream(os, level + 1);
 
 }
diff --git a/src/mesh_common/distance_octree/DistanceOctree.h b/src/mesh_common/distance_octree/DistanceOctree.h
index 3041350827b3ca7a69af2c510c230cdc529ccc3c..dfe6ee36b032bb1f0d4c2bc085dbc3bdcbce9c18 100644
--- a/src/mesh_common/distance_octree/DistanceOctree.h
+++ b/src/mesh_common/distance_octree/DistanceOctree.h
@@ -48,11 +48,11 @@ template <typename MeshType>
 class DistanceOctree
 {
 public:
-   typedef typename MeshType::Point                    Point;
-   typedef typename MeshType::Normal                   Normal;
-   typedef typename MeshType::Scalar                   Scalar;  
-   typedef typename MeshType::FaceHandle               FaceHandle; 
-   typedef typename math::GenericAABB<Scalar> AABB;
+   using Point = typename MeshType::Point;
+   using Normal = typename MeshType::Normal;
+   using Scalar = typename MeshType::Scalar;  
+   using FaceHandle = typename MeshType::FaceHandle; 
+   using AABB = typename math::GenericAABB<Scalar>;
 
    DistanceOctree( const shared_ptr< TriangleDistance<MeshType> > & triDist, uint_t maxDepth = 20u, uint_t minNumTriangles = 25u )
    {
@@ -304,7 +304,7 @@ void DistanceOctree<MeshType>::writeVTKOutput( const std::string & filestem ) co
    while( !nodeQueue.empty() )
    {
       const Node<MeshType> * frontNode = nodeQueue.front();
-      uint8_t depth = depthQueue.front();
+      uint8_t const depth = depthQueue.front();
       nodeQueue.pop();
       depthQueue.pop();
 
diff --git a/src/mesh_common/distance_octree/LeafNode.h b/src/mesh_common/distance_octree/LeafNode.h
index 57833f39def62d7bab971ea526114258d9acb381..25147e202a04f3f57a18ed6486c6c7543381dd15 100644
--- a/src/mesh_common/distance_octree/LeafNode.h
+++ b/src/mesh_common/distance_octree/LeafNode.h
@@ -33,32 +33,32 @@ template <typename MeshType>
 class LeafNode : public Node<MeshType>
 {
 public:
-   typedef typename Node<MeshType>::Point      Point;
-   typedef typename Node<MeshType>::Normal     Normal;
-   typedef typename Node<MeshType>::Scalar     Scalar;
-   typedef typename Node<MeshType>::FaceHandle FaceHandle; 
-   typedef typename Node<MeshType>::AABB       AABB;
+   using Point = typename Node<MeshType>::Point;
+   using Normal = typename Node<MeshType>::Normal;
+   using Scalar = typename Node<MeshType>::Scalar;
+   using FaceHandle = typename Node<MeshType>::FaceHandle; 
+   using AABB = typename Node<MeshType>::AABB;
    
    LeafNode( const shared_ptr< TriangleDistance<MeshType> > & triDistance, const std::vector<FaceHandle> & triangles )
       : Node<MeshType>( triDistance->getMesh(), triangles.begin(), triangles.end() ), triangles_( triangles ), triDistance_( triDistance ) { }
 
-   virtual Scalar sqSignedDistance( const Point & p ) const;
-   virtual Scalar sqSignedDistance( const Point & p, FaceHandle & closestTriangle ) const;
-   virtual Scalar sqSignedDistance( const Point & p, Point & closestPoint ) const;
-   virtual Scalar sqSignedDistance( const Point & p, Point & closestPoint, Normal & normal ) const;
+   Scalar sqSignedDistance( const Point & p ) const override;
+   Scalar sqSignedDistance( const Point & p, FaceHandle & closestTriangle ) const override;
+   Scalar sqSignedDistance( const Point & p, Point & closestPoint ) const override;
+   Scalar sqSignedDistance( const Point & p, Point & closestPoint, Normal & normal ) const override;
 
-   virtual Scalar sqDistance( const Point & p ) const;
-   virtual Scalar sqDistance( const Point & p, FaceHandle & closestTriangle ) const;
-   virtual Scalar sqDistance( const Point & p, Point & closestPoint ) const;
-   virtual Scalar sqDistance( const Point & p, Point & closestPoint, Normal & normal ) const;
+   Scalar sqDistance( const Point & p ) const override;
+   Scalar sqDistance( const Point & p, FaceHandle & closestTriangle ) const override;
+   Scalar sqDistance( const Point & p, Point & closestPoint ) const override;
+   Scalar sqDistance( const Point & p, Point & closestPoint, Normal & normal ) const override;
 
-   virtual Scalar getRayDistanceToMeshObject(const Point & ray_origin, const Point & normalised_ray_direction) const override;
-
-   uint_t numTriangles() const { return uint_c( triangles_.size() ); }
-   void numTrianglesToStream( std::ostream & os, const uint_t level ) const;
-   virtual uint_t height() const { return 0; }
-   virtual uint_t numChildren() const { return 0; };
-   virtual const Node<MeshType> * getChild( const uint_t /*idx*/ ) const { WALBERLA_ABORT("DistanceOctree: You are requesting access to children of a Leaf Node!"); return 0; }
+   Scalar getRayDistanceToMeshObject(const Point & ray_origin, const Point & normalised_ray_direction) const override;
+   
+   uint_t numTriangles() const override { return uint_c( triangles_.size() ); }
+   void numTrianglesToStream( std::ostream & os, const uint_t level ) const override;
+   uint_t height() const override { return 0; }
+   uint_t numChildren() const override { return 0; };
+   const Node<MeshType> * getChild( const uint_t /*idx*/ ) const override { WALBERLA_ABORT("DistanceOctree: You are requesting access to children of a Leaf Node!"); return nullptr; }
    
 protected:
    std::vector<FaceHandle> triangles_;
diff --git a/src/mesh_common/distance_octree/Node.h b/src/mesh_common/distance_octree/Node.h
index 33cb317aee0a314cfa1be8772a8f1758a451abc1..3db2cdd49a27df227b343718f1420d3d02fb32ac 100644
--- a/src/mesh_common/distance_octree/Node.h
+++ b/src/mesh_common/distance_octree/Node.h
@@ -33,15 +33,15 @@ template <typename MeshType>
 class Node
 {
 public:
-   typedef typename MeshType::Point                    Point;
-   typedef typename MeshType::Normal                   Normal;
-   typedef typename MeshType::Scalar                   Scalar;  
-   typedef typename MeshType::FaceHandle               FaceHandle; 
-   typedef typename math::GenericAABB<Scalar>          AABB;
+   using Point = typename MeshType::Point;
+   using Normal = typename MeshType::Normal;
+   using Scalar = typename MeshType::Scalar;  
+   using FaceHandle = typename MeshType::FaceHandle; 
+   using AABB = typename math::GenericAABB<Scalar>;
 
    template< typename InputIterator >
    Node( const MeshType & mesh, InputIterator beginFh, InputIterator endFh ) : aabb_( computeAABBForFaces( mesh, beginFh, endFh ) ) {}
-   virtual ~Node() { }
+   virtual ~Node() = default;
 
    const AABB & getAABB() const { return aabb_; }
 
diff --git a/src/mesh_common/vtk/CommonDataSources.h b/src/mesh_common/vtk/CommonDataSources.h
index 304f425a94943e4946c5cad5c638f57a765a994f..ba6b51f811201486782a04ea5ea2db06ae5653b6 100644
--- a/src/mesh_common/vtk/CommonDataSources.h
+++ b/src/mesh_common/vtk/CommonDataSources.h
@@ -39,13 +39,13 @@ template< typename MeshType, typename OutputType = typename MeshType::Normal::va
 class NormalsVertexDataSource : public VTKMeshWriter<MeshType>::template VertexDataSource< OutputType >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Vertices Vertices;
-   typedef typename VTKMeshWriter<MeshType>::template VertexDataSource< OutputType >::value_type value_type;
+   using Vertices = typename VTKMeshWriter<MeshType>::Vertices;
+   using value_type = typename VTKMeshWriter<MeshType>::template VertexDataSource<OutputType>::value_type;
 
    NormalsVertexDataSource( const std::string & _name = "Normals" )
       : VTKMeshWriter<MeshType>::template VertexDataSource< OutputType >( _name ) { }
-   virtual uint_t numComponents() { return uint_t(3); }
-   virtual void   getData( const MeshType & mesh, const Vertices & vertices, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(3); }
+   void   getData( const MeshType & mesh, const Vertices & vertices, std::vector<value_type> & data ) override
    {
       WALBERLA_CHECK( mesh.has_vertex_normals(), "You are trying to write vertex normals of a mesh which does not have any!" );
 
@@ -68,13 +68,13 @@ template< typename MeshType, typename OutputType = typename MeshType::Normal::va
 class NormalsFaceDataSource : public VTKMeshWriter<MeshType>::template FaceDataSource< OutputType >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Faces Faces;
-   typedef typename VTKMeshWriter<MeshType>::template FaceDataSource< OutputType >::value_type value_type;
+   using Faces = typename VTKMeshWriter<MeshType>::Faces;
+   using value_type = typename VTKMeshWriter<MeshType>::template FaceDataSource<OutputType>::value_type;
 
    NormalsFaceDataSource( const std::string & _name = "Normals" )
       : VTKMeshWriter<MeshType>::template FaceDataSource< OutputType >( _name ) { }
-   virtual uint_t numComponents() { return uint_t(3); }
-   virtual void   getData( const MeshType & mesh, const Faces & faces, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(3); }
+   void   getData( const MeshType & mesh, const Faces & faces, std::vector<value_type> & data ) override
    {
       WALBERLA_CHECK( mesh.has_face_normals(), "You are trying to write face normals of a mesh which does not have any!" );
 
@@ -97,13 +97,13 @@ template< typename MeshType, typename OutputType = typename MeshType::Normal::va
 class AreaFaceDataSource : public VTKMeshWriter<MeshType>::template FaceDataSource< OutputType >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Faces Faces;
-   typedef typename VTKMeshWriter<MeshType>::template FaceDataSource< OutputType >::value_type value_type;
+   using Faces = typename VTKMeshWriter<MeshType>::Faces;
+   using value_type = typename VTKMeshWriter<MeshType>::template FaceDataSource<OutputType>::value_type;
 
    AreaFaceDataSource( const std::string & _name = "Area" )
       : VTKMeshWriter<MeshType>::template FaceDataSource< OutputType >( _name ) { }
-   virtual uint_t numComponents() { return uint_t(1); }
-   virtual void   getData( const MeshType & mesh, const Faces & faces, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(1); }
+   void   getData( const MeshType & mesh, const Faces & faces, std::vector<value_type> & data ) override
    {
       data.reserve( faces.size() );
 
@@ -123,13 +123,13 @@ template< typename MeshType >
 class StatusBitFaceDataSource : public VTKMeshWriter<MeshType>::template FaceDataSource< uint8_t >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Faces Faces;
-   typedef typename VTKMeshWriter<MeshType>::template FaceDataSource< uint8_t >::value_type value_type;
+   using Faces = typename VTKMeshWriter<MeshType>::Faces;
+   using value_type = typename VTKMeshWriter<MeshType>::template FaceDataSource<uint8_t>::value_type;
 
    StatusBitFaceDataSource( const OpenMesh::Attributes::StatusBits & bit, const std::string & _name )
       : VTKMeshWriter<MeshType>::template FaceDataSource< uint8_t >( _name ), bit_( bit ) {}
-   virtual uint_t numComponents() { return uint_t(1); }
-   virtual void   getData( const MeshType & mesh, const Faces & faces, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(1); }
+   void   getData( const MeshType & mesh, const Faces & faces, std::vector<value_type> & data ) override
    {
       WALBERLA_CHECK( mesh.has_face_status(), "Cannot write face status bits, because the faces do not have them!" );
 
@@ -150,13 +150,13 @@ template< typename MeshType >
 class StatusBitVertexDataSource : public VTKMeshWriter<MeshType>::template VertexDataSource< uint8_t >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Vertices Vertices;
-   typedef typename VTKMeshWriter<MeshType>::template VertexDataSource< uint8_t >::value_type value_type;
+   using Vertices = typename VTKMeshWriter<MeshType>::Vertices;
+   using value_type = typename VTKMeshWriter<MeshType>::template VertexDataSource<uint8_t>::value_type;
 
    StatusBitVertexDataSource( const OpenMesh::Attributes::StatusBits & bit, const std::string & _name )
       : VTKMeshWriter<MeshType>::template VertexDataSource< uint8_t >( _name ), bit_( bit ) {}
-   virtual uint_t numComponents() { return uint_t(1); }
-   virtual void   getData( const MeshType & mesh, const Vertices & vertices, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(1); }
+   void   getData( const MeshType & mesh, const Vertices & vertices, std::vector<value_type> & data ) override
    {
       WALBERLA_CHECK( mesh.has_vertex_status(), "Cannot write vertex status bits, because the vertices do not have them!" );
 
@@ -177,14 +177,14 @@ template< typename MeshType >
 class ColorFaceDataSource : public VTKMeshWriter<MeshType>::template FaceDataSource< uint8_t >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Faces Faces;
-   typedef typename VTKMeshWriter<MeshType>::template FaceDataSource< uint8_t >::value_type value_type;
+   using Faces = typename VTKMeshWriter<MeshType>::Faces;
+   using value_type = typename VTKMeshWriter<MeshType>::template FaceDataSource<uint8_t>::value_type;
 
    ColorFaceDataSource( const std::string & _name = "color" )
       : VTKMeshWriter<MeshType>::template FaceDataSource< uint8_t >( _name ) {}
 
-   virtual uint_t numComponents() { return uint_t(3); }
-   virtual void   getData( const MeshType & mesh, const Faces & faces, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(3); }
+   void   getData( const MeshType & mesh, const Faces & faces, std::vector<value_type> & data ) override
    {
       WALBERLA_CHECK( mesh.has_face_colors(), "Cannot write face colors, because the faces do not have them!" );
 
@@ -205,14 +205,14 @@ template< typename MeshType >
 class ColorVertexDataSource : public VTKMeshWriter<MeshType>::template VertexDataSource< uint8_t >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Vertices Vertices;
-   typedef typename VTKMeshWriter<MeshType>::template VertexDataSource< uint8_t >::value_type value_type;
+   using Vertices = typename VTKMeshWriter<MeshType>::Vertices;
+   using value_type = typename VTKMeshWriter<MeshType>::template VertexDataSource<uint8_t>::value_type;
 
    ColorVertexDataSource( const std::string & _name = "color" )
       : VTKMeshWriter<MeshType>::template VertexDataSource< uint8_t >( _name ) {}
 
-   virtual uint_t numComponents() { return uint_t(3); }
-   virtual void   getData( const MeshType & mesh, const Vertices & vertices, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(3); }
+   void   getData( const MeshType & mesh, const Vertices & vertices, std::vector<value_type> & data ) override
    {
       WALBERLA_CHECK( mesh.has_vertex_colors(), "Cannot write vertex colors, because the vertices do not have them!" );
 
@@ -231,14 +231,14 @@ template< typename MeshType >
 class IndexFaceDataSource : public VTKMeshWriter<MeshType>::template FaceDataSource< int32_t >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Faces Faces;
-   typedef typename VTKMeshWriter<MeshType>::template FaceDataSource< int32_t >::value_type value_type;
+   using Faces = typename VTKMeshWriter<MeshType>::Faces;
+   using value_type = typename VTKMeshWriter<MeshType>::template FaceDataSource<int32_t>::value_type;
 
    IndexFaceDataSource( const std::string & _name = "index" )
       : VTKMeshWriter<MeshType>::template FaceDataSource< int32_t >( _name ) {}
 
-   virtual uint_t numComponents() { return uint_t(1); }
-   virtual void   getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(1); }
+   void   getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data ) override
    {
       data.reserve( faces.size() );
       for( auto it = faces.begin(); it != faces.end(); ++it )
@@ -253,14 +253,14 @@ template< typename MeshType >
 class IndexVertexDataSource : public VTKMeshWriter<MeshType>::template VertexDataSource< int32_t >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Vertices Vertices;
-   typedef typename VTKMeshWriter<MeshType>::template VertexDataSource< int32_t >::value_type value_type;
+   using Vertices = typename VTKMeshWriter<MeshType>::Vertices;
+   using value_type = typename VTKMeshWriter<MeshType>::template VertexDataSource<int32_t>::value_type;
 
    IndexVertexDataSource( const std::string & _name = "index" )
       : VTKMeshWriter<MeshType>::template VertexDataSource< int32_t >( _name ) {}
 
-   virtual uint_t numComponents() { return uint_t(1); }
-   virtual void   getData( const MeshType & /*mesh*/, const Vertices & vertices, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(1); }
+   void   getData( const MeshType & /*mesh*/, const Vertices & vertices, std::vector<value_type> & data ) override
    {
       data.reserve( vertices.size() );
       for( auto it = vertices.begin(); it != vertices.end(); ++it )
@@ -275,14 +275,14 @@ template< typename MeshType >
 class RankFaceDataSource : public VTKMeshWriter<MeshType>::template FaceDataSource< int32_t >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Faces Faces;
-   typedef typename VTKMeshWriter<MeshType>::template FaceDataSource< int32_t >::value_type value_type;
+   using Faces = typename VTKMeshWriter<MeshType>::Faces;
+   using value_type = typename VTKMeshWriter<MeshType>::template FaceDataSource<int32_t>::value_type;
 
    RankFaceDataSource( const std::string & _name = "rank" )
       : VTKMeshWriter<MeshType>::template FaceDataSource< int32_t >( _name ) {}
 
-   virtual uint_t numComponents() { return uint_t(1); }
-   virtual void   getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(1); }
+   void   getData( const MeshType & /*mesh*/, const Faces & faces, std::vector<value_type> & data ) override
    {
       int32_t rank = MPIManager::instance()->rank();
       data.assign( faces.size(), rank );
@@ -294,14 +294,14 @@ template< typename MeshType >
 class RankVertexDataSource : public VTKMeshWriter<MeshType>::template VertexDataSource< int32_t >
 {
 public:
-   typedef typename VTKMeshWriter<MeshType>::Vertices Vertices;
-   typedef typename VTKMeshWriter<MeshType>::template VertexDataSource< int32_t >::value_type value_type;
+   using Vertices = typename VTKMeshWriter<MeshType>::Vertices;
+   using value_type = typename VTKMeshWriter<MeshType>::template VertexDataSource<int32_t>::value_type;
 
    RankVertexDataSource( const std::string & _name = "rank" )
       : VTKMeshWriter<MeshType>::template VertexDataSource< int32_t >( _name ) {}
 
-   virtual uint_t numComponents() { return uint_t(1); }
-   virtual void   getData( const MeshType & /*mesh*/, const Vertices & vertices, std::vector<value_type> & data )
+   uint_t numComponents() override { return uint_t(1); }
+   void   getData( const MeshType & /*mesh*/, const Vertices & vertices, std::vector<value_type> & data ) override
    {
       int32_t rank = MPIManager::instance()->rank();
       data.assign( vertices.size(), rank );
diff --git a/src/mesh_common/vtk/VTKMeshWriter.h b/src/mesh_common/vtk/VTKMeshWriter.h
index 5d6822c3908f6472a52a9d5094470a91fe8487c7..ce8ba7f328167fb0216a9241b881fab28be22939 100644
--- a/src/mesh_common/vtk/VTKMeshWriter.h
+++ b/src/mesh_common/vtk/VTKMeshWriter.h
@@ -42,10 +42,10 @@ namespace mesh {
 template< typename MeshType >
 class VTKMeshWriter {
 public:
-   typedef std::function<bool ( const MeshType &, const typename MeshType::FaceHandle & )> FaceFilterFunction;
+   using FaceFilterFunction = std::function<bool (const MeshType &, const typename MeshType::FaceHandle &)>;
 
-   typedef std::vector< typename MeshType::FaceHandle >   Faces;
-   typedef std::vector< typename MeshType::VertexHandle > Vertices;
+   using Faces = std::vector<typename MeshType::FaceHandle>;
+   using Vertices = std::vector<typename MeshType::VertexHandle>;
 
    template< typename T >
    class DataSource
@@ -53,7 +53,7 @@ public:
    public:
       DataSource( const std::string & _name ) : name_( _name ) { }
       virtual ~DataSource() = default;
-      typedef T value_type;
+      using value_type = T;
       virtual uint_t      numComponents() = 0;
       const std::string & name() { return name_; }
    protected:
@@ -64,11 +64,11 @@ public:
    class VertexDataSource : public DataSource<T>
    {
    public:
-      typedef typename DataSource<T>::value_type value_type;
-      typedef typename VTKMeshWriter::Vertices Vertices;
+      using value_type = typename DataSource<T>::value_type;
+      using Vertices = typename VTKMeshWriter::Vertices;
 
       VertexDataSource( const std::string & _name ) : DataSource<T>( _name ) { }
-      virtual ~VertexDataSource() = default;
+      ~VertexDataSource() override = default;
       virtual void getData( const MeshType &, const Vertices & vertices, std::vector<T> & ) = 0;
    };
 
@@ -76,11 +76,11 @@ public:
    class FaceDataSource : public DataSource<T>
    {
    public:
-      typedef typename DataSource<T>::value_type value_type;
-      typedef typename VTKMeshWriter::Faces Faces;
+      using value_type = typename DataSource<T>::value_type;
+      using Faces = typename VTKMeshWriter::Faces;
 
       FaceDataSource( const std::string & _name ) : DataSource<T>( _name ) { }
-      virtual ~FaceDataSource() = default;
+      ~FaceDataSource() override = default;
       virtual void getData( const MeshType &, const Faces & faces, std::vector<T> & ) = 0;
    };
 
@@ -128,7 +128,7 @@ protected:
    std::string identifier_;
    std::string baseFolder_;
 
-   uint_t      timestep_;
+   uint_t      timestep_{ 0 };
 
    FaceFilterFunction faceFilter_;
 
@@ -195,7 +195,7 @@ void VTKMeshWriter<MeshType>::writeFaceData( const T & faceDataSources, const Fa
 template< typename MeshType >
 VTKMeshWriter<MeshType>::VTKMeshWriter( const shared_ptr<const MeshType> & mesh, const std::string & identifier, const uint_t writeFrequency,
    const std::string & baseFolder )
-   : mesh_( mesh ), writeFrequency_( writeFrequency ), identifier_( identifier ), baseFolder_( baseFolder ), timestep_( 0 )
+   : mesh_( mesh ), writeFrequency_( writeFrequency ), identifier_( identifier ), baseFolder_( baseFolder )
 {
    WALBERLA_ROOT_SECTION()
    {
@@ -298,9 +298,9 @@ void VTKMeshWriter<MeshType>::writePiece( std::ostream & os ) const
 
    os << "        <DataArray type=\"Int32\" Name=\"offsets\" format=\"binary\">\n";
    os << "          ";
-   for( auto it = offsets.begin(); it != offsets.end(); ++it )
+   for(auto const& offset : offsets)
    {
-      b64 << *it;
+      b64 << offset;
    }
    b64.toStream( os );
 
@@ -367,10 +367,10 @@ void VTKMeshWriter<MeshType>::operator()()
       {
          std::ostringstream filePathVtp;
          filePathVtp << baseFolder_ << '/' << identifier_ << '/' << identifier_ << '_' << timestep_ << ".vtp";
-      
+
          std::ofstream ofsVtp;
          ofsVtp.open( filePathVtp.str().c_str() );
-  
+
          write( ofsVtp );
 
          std::ostringstream filePathPvd;
@@ -385,4 +385,4 @@ void VTKMeshWriter<MeshType>::operator()()
 
 
 } // namespace mesh
-} // namespace walberla
+} // namespace walberla
\ No newline at end of file
diff --git a/src/pde/ConditionalResidualNorm.h b/src/pde/ConditionalResidualNorm.h
index 68307defb076ad193ba3a850506452cb206d1eda..fc9aa20e26d3cc1e29a55ae3353a06f9f65ea804 100644
--- a/src/pde/ConditionalResidualNorm.h
+++ b/src/pde/ConditionalResidualNorm.h
@@ -40,7 +40,7 @@ class ConditionalResidualNorm
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 > Field_T;
+   using Field_T = GhostLayerField<real_t, 1>;
 
    ConditionalResidualNorm( const BlockStorage & blocks, const ConstBlockDataID & uId, const ConstBlockDataID & fId,
                             const ConstBlockDataID & flagFieldId, const Set< FlagUID > & domainMask,
@@ -69,7 +69,7 @@ protected:
    ConstBlockDataID flagFieldId_;
    Set< FlagUID > domainMask_;
 
-   real_t weights_[ Stencil_T::Size ];
+   std::array<real_t, Stencil_T::Size> weights_;
 
    Set<SUID> requiredSelectors_;
    Set<SUID> incompatibleSelectors_;
diff --git a/src/pde/ResidualNorm.h b/src/pde/ResidualNorm.h
index bd58cad727849d06474f8a65d47aa7ddf211759b..56808bce7fa0f47a464f8a4a5c15aae25c5f046a 100644
--- a/src/pde/ResidualNorm.h
+++ b/src/pde/ResidualNorm.h
@@ -38,7 +38,7 @@ class ResidualNorm
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 > Field_T;
+   using Field_T = GhostLayerField<real_t, 1>;
    
    ResidualNorm( const BlockStorage & blocks, const ConstBlockDataID & uId, const ConstBlockDataID & fId, const std::vector< real_t > & weights,
                  const Set<SUID> & requiredSelectors     = Set<SUID>::emptySet(),
@@ -67,7 +67,7 @@ protected:
    ConstBlockDataID uId_;
    ConstBlockDataID fId_;
    
-   real_t weights_[ Stencil_T::Size ];
+   std::array<real_t, Stencil_T::Size> weights_;
    
    real_t cells_;
    
diff --git a/src/pde/ResidualNormStencilField.h b/src/pde/ResidualNormStencilField.h
index 166caf76e69ef5dcd20e7edacd34c6ec0203463d..bfda69d6e01243fbe68c1862a1d7c0943255bfbd 100644
--- a/src/pde/ResidualNormStencilField.h
+++ b/src/pde/ResidualNormStencilField.h
@@ -38,8 +38,8 @@ class ResidualNormStencilField
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 > Field_T;
-   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+   using Field_T = GhostLayerField<real_t, 1>;
+   using StencilField_T = GhostLayerField<real_t, Stencil_T::Size>;
    
    ResidualNormStencilField( const BlockStorage & blocks, const ConstBlockDataID & uId, const ConstBlockDataID & fId, const BlockDataID & stencilId,
                  const Set<SUID> & requiredSelectors     = Set<SUID>::emptySet(),
diff --git a/src/pde/boundary/Dirichlet.h b/src/pde/boundary/Dirichlet.h
index 929d2b5ba39517a84cccae6329271dc5f2dbf756..00614f3866db36947fa21596a59ce5b33951147c 100644
--- a/src/pde/boundary/Dirichlet.h
+++ b/src/pde/boundary/Dirichlet.h
@@ -62,8 +62,8 @@ template< typename Stencil_T, typename flag_t >
 class Dirichlet : public Boundary< flag_t >
 {
 
-   typedef GhostLayerField< real_t, 1 > Field_T;
-   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+   using Field_T = GhostLayerField<real_t, 1>;
+   using StencilField_T = GhostLayerField<real_t, Stencil_T::Size>;
 
 public:
 
diff --git a/src/pde/boundary/Neumann.h b/src/pde/boundary/Neumann.h
index 76988b2d47d5759d70b04d465eedb2f349bc65c8..45b19521ffbbe657e6b29afd8ba1bb0371e97f22 100644
--- a/src/pde/boundary/Neumann.h
+++ b/src/pde/boundary/Neumann.h
@@ -104,11 +104,11 @@ protected:
    StructuredBlockStorage & blocks_;
    BlockDataID fieldId_;
 
-   bool includeBoundary_[ stencil::D3Q6::Size ];
-   uint_t order_[ stencil::D3Q6::Size ];
+   std::array<bool, stencil::D3Q6::Size> includeBoundary_;
+   std::array<uint_t, stencil::D3Q6::Size> order_;
 
-   real_t value_[ stencil::D3Q6::Size ];
-   real_t dx_[ stencil::D3Q6::Size ];
+   std::array<real_t, stencil::D3Q6::Size> value_;
+   std::array<real_t, stencil::D3Q6::Size> dx_;
 
 }; // class NeumannDomainBoundary
 
@@ -242,8 +242,8 @@ template< typename Stencil_T, typename flag_t >
 class Neumann : public Boundary< flag_t >
 {
 
-   typedef GhostLayerField< real_t, 1 > Field_T;
-   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+   using Field_T = GhostLayerField<real_t, 1>;
+   using StencilField_T = GhostLayerField<real_t, Stencil_T::Size>;
 
 public:
 
diff --git a/src/pde/iterations/CGFixedStencilIteration.h b/src/pde/iterations/CGFixedStencilIteration.h
index 145fa37c80515a9745265d9b12a652abbf733d19..8a0829d4cfc64d96749cd3ec063d577b826d1c9b 100644
--- a/src/pde/iterations/CGFixedStencilIteration.h
+++ b/src/pde/iterations/CGFixedStencilIteration.h
@@ -45,7 +45,7 @@ class CGFixedStencilIteration
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 > Field_T;
+   using Field_T = GhostLayerField<real_t, 1>;
 
    CGFixedStencilIteration( BlockStorage & blocks,
                             const BlockDataID & uId, const BlockDataID & rId, const BlockDataID & dId, const BlockDataID & zId,
@@ -83,7 +83,7 @@ protected:
    
    real_t cells_;
 
-   real_t w_[ Stencil_T::Size ];
+   std::array<real_t, Stencil_T::Size> w_;
 
    uint_t iterations_;
    real_t residualNormThreshold_;
diff --git a/src/pde/iterations/CGIteration.h b/src/pde/iterations/CGIteration.h
index d3339759bb7b2998a22eb6e281704ef583a98715..de326da1a146aeef5bae5552d473541f89911e7a 100644
--- a/src/pde/iterations/CGIteration.h
+++ b/src/pde/iterations/CGIteration.h
@@ -45,8 +45,8 @@ class CGIteration
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 >                Field_T;
-   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+   using Field_T = GhostLayerField<real_t, 1>;
+   using StencilField_T = GhostLayerField<real_t, Stencil_T::Size>;
 
    CGIteration( BlockStorage & blocks,
                             const BlockDataID & uId, const BlockDataID & rId, const BlockDataID & dId, const BlockDataID & zId,
diff --git a/src/pde/iterations/RBGSIteration.h b/src/pde/iterations/RBGSIteration.h
index 9f4ee04e7e9f3aa7f4584263e6d6603716d14b32..7ecc689637294d67823c89d299d3b7c4c9afe752 100644
--- a/src/pde/iterations/RBGSIteration.h
+++ b/src/pde/iterations/RBGSIteration.h
@@ -48,7 +48,7 @@ public:
                   const Set<SUID> & incompatibleSelectors = Set<SUID>::emptySet() ) :
       blocks_( blocks ), iterations_( iterations ),
       residualNormThreshold_( residualNormThreshold ), residualCheckFrequency_( residualCheckFrequency ),
-      iterationsPerformed_( uint_t(0) ), thresholdReached_( false ),
+      iterationsPerformed_( uint_t(0) ),
       communication_( communication ), redUpdate_( redUpdate ), blackUpdate_( blackUpdate ), residualNorm_( residualNorm ),
       requiredSelectors_( requiredSelectors ), incompatibleSelectors_( incompatibleSelectors )
    {}
@@ -69,7 +69,7 @@ protected:
    uint_t residualCheckFrequency_;
    
    uint_t iterationsPerformed_;
-   bool thresholdReached_;
+   bool thresholdReached_{ false };
 
    std::function< void () >            boundary_;
    std::function< void () >            communication_;
diff --git a/src/pde/iterations/VCycles.h b/src/pde/iterations/VCycles.h
index 1d6f12fa61b1d5225cbd053584d9830139a819a2..7b0b5136b2131c2ae51f254dd34b0089bce54094 100644
--- a/src/pde/iterations/VCycles.h
+++ b/src/pde/iterations/VCycles.h
@@ -61,9 +61,9 @@ class VCycles
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 > PdeField_T;
-   typedef std::vector< real_t  > Weight_T;
-   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+   using PdeField_T = GhostLayerField<real_t, 1>;
+   using Weight_T = std::vector<real_t>;
+   using StencilField_T = GhostLayerField<real_t, Stencil_T::Size>;
 
    //*******************************************************************************************************************
    /*! Creates a multigrid V-cycle with a fixed stencil
diff --git a/src/pde/iterations/VCycles.impl.h b/src/pde/iterations/VCycles.impl.h
index 2555b7071208e72004b421cdd2ffaa8b62a4ded9..09825b7699b65938ada8b3fc17a9c7d279797013 100644
--- a/src/pde/iterations/VCycles.impl.h
+++ b/src/pde/iterations/VCycles.impl.h
@@ -55,7 +55,7 @@ VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::
    requiredSelectors_( requiredSelectors ), incompatibleSelectors_( incompatibleSelectors )
 {
 
-   static_assert(std::is_same<OperatorCoarsening_T, CoarsenStencilFieldsDCA<Stencil_T>>::value, "Use of weight requires DCA, use constructor with stencil field if you want to employ GCA");
+   static_assert(std::is_same_v<OperatorCoarsening_T, CoarsenStencilFieldsDCA<Stencil_T>>, "Use of weight requires DCA, use constructor with stencil field if you want to employ GCA");
 
    // Set up fields for finest level
    uId_.push_back( uFieldId );
@@ -90,7 +90,8 @@ VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::
    // Set up fields for coarser levels
    for ( uint_t lvl = 1; lvl < numLvl; ++lvl )
    {
-      auto getSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, lvl, std::placeholders::_1, std::placeholders::_2);
+      auto getSize = [lvl](const shared_ptr< StructuredBlockStorage > & bs, IBlock * const b) {
+         return VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel(lvl, bs, b); };
       uId_.push_back( field::addToStorage< PdeField_T >( blocks, "u_"+std::to_string(lvl), getSize, real_t(0), field::fzyx, uint_t(1) ) );
       fId_.push_back( field::addToStorage< PdeField_T >( blocks, "f_"+std::to_string(lvl), getSize, real_t(0), field::fzyx, uint_t(1) ) );
       rId_.push_back( field::addToStorage< PdeField_T >( blocks, "r_"+std::to_string(lvl), getSize, real_t(0), field::fzyx, uint_t(1) ) );
@@ -103,7 +104,8 @@ VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::
    }
 
    // Set up fields for CG on coarsest level
-   auto getFineSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, numLvl-1, std::placeholders::_1, std::placeholders::_2);
+   auto getFineSize = [finestLvl = numLvl-1](const shared_ptr< StructuredBlockStorage > & bs, IBlock * const b) {
+      return VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel(finestLvl, bs, b); };
    dId_ = field::addToStorage< PdeField_T >( blocks, "d", getFineSize, real_t(0), field::fzyx, uint_t(1) );
    zId_ = field::addToStorage< PdeField_T >( blocks, "z", getFineSize, real_t(0), field::fzyx, uint_t(1) );
 
@@ -126,7 +128,7 @@ VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::
    for ( uint_t lvl = 0; lvl < numLvl-1; ++lvl )
    {
       RBGSFixedSweeps_.push_back( walberla::make_shared<RBGSFixedStencil< Stencil_T > >( blocks, uId_[lvl], fId_[lvl], weights_[lvl] ) );
-      RBGSIteration_.push_back( RBGSIteration(blocks->getBlockStorage(), preSmoothingIters_, communication_[lvl],
+      RBGSIteration_.emplace_back(RBGSIteration(blocks->getBlockStorage(), preSmoothingIters_, communication_[lvl],
                                 RBGSFixedSweeps_.back()->getRedSweep(), RBGSFixedSweeps_.back()->getBlackSweep(), [](){ return real_t(1.0); }, 0, 1,
                                 requiredSelectors, incompatibleSelectors ) );
    }
@@ -136,7 +138,7 @@ VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::
    {
       computeResidual_.push_back( ComputeResidualFixedStencil< Stencil_T >( blocks, uId_[lvl], fId_[lvl], weights_[lvl], rId_[lvl] ) );
       restrict_.push_back( Restrict_T(blocks, rId_[lvl], fId_[lvl+1] ) );
-      zeroize_.push_back( Zeroize(blocks, uId_[lvl+1]) );
+      zeroize_.emplace_back(Zeroize(blocks, uId_[lvl+1]) );
       prolongateAndCorrect_.push_back( ProlongateAndCorrect_T(blocks, uId_[lvl+1], uId_[lvl]) );
    }
 
@@ -196,7 +198,8 @@ VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::
    // Set up fields for coarser levels
    for ( uint_t lvl = 1; lvl < numLvl; ++lvl )
    {
-      auto getSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, lvl, std::placeholders::_1, std::placeholders::_2);
+      auto getSize = [lvl](const shared_ptr< StructuredBlockStorage > & bs, IBlock * const b) {
+         return VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel(lvl, bs, b); };
       uId_.push_back( field::addToStorage< PdeField_T >( blocks, "u_"+std::to_string(lvl), getSize, real_t(0), field::fzyx, uint_t(1) ) );
       fId_.push_back( field::addToStorage< PdeField_T >( blocks, "f_"+std::to_string(lvl), getSize, real_t(0), field::fzyx, uint_t(1) ) );
       rId_.push_back( field::addToStorage< PdeField_T >( blocks, "r_"+std::to_string(lvl), getSize, real_t(0), field::fzyx, uint_t(1) ) );
@@ -208,7 +211,9 @@ VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::
    operatorCoarsening(stencilId_);
 
    // Set up fields for CG on coarsest level
-   auto getFineSize = std::bind(VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel, numLvl-1, std::placeholders::_1, std::placeholders::_2);
+   auto getFineSize = [finestLvl = numLvl-1](const shared_ptr< StructuredBlockStorage > & bs, IBlock * const b) {
+      return VCycles<Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T>::getSizeForLevel(finestLvl, bs, b);
+   };
    dId_ = field::addToStorage< PdeField_T >( blocks, "d", getFineSize, real_t(0), field::fzyx, uint_t(1) );
    zId_ = field::addToStorage< PdeField_T >( blocks, "z", getFineSize, real_t(0), field::fzyx, uint_t(1) );
 
@@ -231,7 +236,7 @@ VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::
    for ( uint_t lvl = 0; lvl < numLvl-1; ++lvl )
    {
       RBGSSweeps_.push_back( walberla::make_shared<RBGS< Stencil_T > >( blocks, uId_[lvl], fId_[lvl], stencilId_[lvl] ) );
-      RBGSIteration_.push_back( RBGSIteration(blocks->getBlockStorage(), preSmoothingIters_, communication_[lvl],
+      RBGSIteration_.emplace_back(RBGSIteration(blocks->getBlockStorage(), preSmoothingIters_, communication_[lvl],
                                 RBGSSweeps_.back()->getRedSweep(), RBGSSweeps_.back()->getBlackSweep(), [](){ return real_t(1.0); }, 0, 1,
                                 requiredSelectors, incompatibleSelectors ) );
    }
@@ -241,7 +246,7 @@ VCycles< Stencil_T, OperatorCoarsening_T, Restrict_T, ProlongateAndCorrect_T >::
    {
       computeResidual_.push_back( ComputeResidual< Stencil_T >( blocks, uId_[lvl], fId_[lvl], stencilId_[lvl], rId_[lvl] ) );
       restrict_.push_back( Restrict_T(blocks, rId_[lvl], fId_[lvl+1] ) );
-      zeroize_.push_back( Zeroize(blocks, uId_[lvl+1]) );
+      zeroize_.emplace_back(Zeroize(blocks, uId_[lvl+1]) );
       prolongateAndCorrect_.push_back( ProlongateAndCorrect_T(blocks, uId_[lvl+1], uId_[lvl]) );
    }
 
diff --git a/src/pde/sweeps/Jacobi.h b/src/pde/sweeps/Jacobi.h
index 9f8b4e714d2f94be4038ffbe36d38d6ab6c3172c..c13f92ccde225f602c2b66f1c9023405811a4f00 100644
--- a/src/pde/sweeps/Jacobi.h
+++ b/src/pde/sweeps/Jacobi.h
@@ -36,8 +36,8 @@ class Jacobi : public StencilFieldSweepBase< Stencil_T >
 {
 public:
 
-   typedef typename StencilFieldSweepBase< Stencil_T >::Field_T         Field_T;
-   typedef typename StencilFieldSweepBase< Stencil_T >::StencilField_T  StencilField_T;
+   using Field_T = typename StencilFieldSweepBase<Stencil_T>::Field_T;
+   using StencilField_T = typename StencilFieldSweepBase<Stencil_T>::StencilField_T;
 
    // block has NO dst u field
    Jacobi( const BlockDataID & uFieldId, const BlockDataID & fFieldId, const BlockDataID & stencilFieldId ) :
diff --git a/src/pde/sweeps/JacobiFixedStencil.h b/src/pde/sweeps/JacobiFixedStencil.h
index 4efc6fc5e8c9b7726ee5adae50c2207873648410..75d3066aa294c0de6badf4364b07294df9990ab1 100644
--- a/src/pde/sweeps/JacobiFixedStencil.h
+++ b/src/pde/sweeps/JacobiFixedStencil.h
@@ -37,7 +37,7 @@ class JacobiFixedStencil : public StencilSweepBase< Stencil_T >
 {
 public:
 
-   typedef typename StencilSweepBase< Stencil_T >::Field_T Field_T;
+   using Field_T = typename StencilSweepBase<Stencil_T>::Field_T;
 
    // block has NO dst u field
    JacobiFixedStencil( const BlockDataID & uFieldId, const BlockDataID & fFieldId, const std::vector< real_t > & weights ) :
@@ -63,7 +63,7 @@ void JacobiFixedStencil< Stencil_T >::operator()( IBlock * const block )
    WALBERLA_ASSERT_GREATER_EQUAL( sf->nrOfGhostLayers(), 1 );
 
    // stencil weights
-   real_t weights[ Stencil_T::Size ];
+   std::array<real_t, Stencil_T::Size> weights;
    for( auto dir = Stencil_T::beginNoCenter(); dir != Stencil_T::end(); ++dir )
       weights[ dir.toIdx() ] = this->w( dir.toIdx() );
    weights[ Stencil_T::idx[ stencil::C ] ] = real_t(1) / this->w( Stencil_T::idx[ stencil::C ] ); // center already inverted here!
diff --git a/src/pde/sweeps/Multigrid.h b/src/pde/sweeps/Multigrid.h
index 58d4d8f031afa649526cc3814b1115e9b8d6992b..d8612abd324d3583e08dcb6f644059c7a984aac4 100644
--- a/src/pde/sweeps/Multigrid.h
+++ b/src/pde/sweeps/Multigrid.h
@@ -43,7 +43,7 @@ class Restrict
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 > Field_T;
+   using Field_T = GhostLayerField<real_t, 1>;
 
    //*******************************************************************************************************************
    /* \param blocks the block storage where the fields are stored
@@ -77,7 +77,7 @@ class ProlongateAndCorrect
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 > Field_T;
+   using Field_T = GhostLayerField<real_t, 1>;
 
    //*******************************************************************************************************************
    /* \param blocks the block storage where the fields are stored
@@ -111,8 +111,8 @@ class ComputeResidual
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 >                Field_T;
-   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+   using Field_T = GhostLayerField<real_t, 1>;
+   using StencilField_T = GhostLayerField<real_t, Stencil_T::Size>;
 
    //*******************************************************************************************************************
    /* \param blocks the block storage where the fields are stored
@@ -151,8 +151,8 @@ class ComputeResidualFixedStencil
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 > Field_T;
-   typedef std::vector< real_t  > Weight_T;
+   using Field_T = GhostLayerField<real_t, 1>;
+   using Weight_T = std::vector<real_t>;
 
    //*******************************************************************************************************************
    /* \param blocks the block storage where the fields are stored
@@ -188,7 +188,7 @@ class Zeroize
 {
 public:
 
-   typedef GhostLayerField< real_t, 1 > Field_T;
+   using Field_T = GhostLayerField<real_t, 1>;
 
    //*******************************************************************************************************************
    /* \param blocks the block storage where the field is stored
@@ -223,7 +223,7 @@ class CoarsenStencilFieldsDCA
 {
 public:
 
-   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+   using StencilField_T = GhostLayerField<real_t, Stencil_T::Size>;
 
    //*******************************************************************************************************************
    /* \param blocks the block storage where the fields are stored
@@ -269,7 +269,7 @@ class CoarsenStencilFieldsGCA
 {
 public:
 
-   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+   using StencilField_T = GhostLayerField<real_t, Stencil_T::Size>;
 
    //*******************************************************************************************************************
    /* \param blocks the block storage where the fields are stored
diff --git a/src/pde/sweeps/Multigrid.impl.h b/src/pde/sweeps/Multigrid.impl.h
index 47080ea6385542720405ff4ab257dc2331bce38e..4815239ffe462fa69e2f86a2dea30f8b17c58dab 100644
--- a/src/pde/sweeps/Multigrid.impl.h
+++ b/src/pde/sweeps/Multigrid.impl.h
@@ -184,8 +184,8 @@ inline void CoarsenStencilFieldsGCA< stencil::D3Q7 >::operator()( const std::vec
          StencilField_T * coarse = block->getData< StencilField_T >( stencilFieldId[lvl] );
 
 
-         typedef std::array<std::array<std::array<real_t,7>,7>,7> Array3D_7;
-         typedef std::array<std::array<std::array<real_t,2>,2>,2> Array3D_2;
+         using Array3D_7 = std::array<std::array<std::array<real_t, 7>, 7>, 7>;
+         using Array3D_2 = std::array<std::array<std::array<real_t, 2>, 2>, 2>;
 
          Array3D_2 r;
          Array3D_7 p;
diff --git a/src/pde/sweeps/RBGS.h b/src/pde/sweeps/RBGS.h
index e8d800aa5fcad9a6181ac4fa1f01b60115bbe4d1..be46333bdf197ae713f1e22f8ef8ea12f4806680 100644
--- a/src/pde/sweeps/RBGS.h
+++ b/src/pde/sweeps/RBGS.h
@@ -39,14 +39,14 @@ class RBGS : public StencilFieldSweepBase< Stencil_T >
 {
 public:
 
-   typedef typename StencilFieldSweepBase< Stencil_T >::Field_T         Field_T;
-   typedef typename StencilFieldSweepBase< Stencil_T >::StencilField_T  StencilField_T;
+   using Field_T = typename StencilFieldSweepBase<Stencil_T>::Field_T;
+   using StencilField_T = typename StencilFieldSweepBase<Stencil_T>::StencilField_T;
    
    RBGS( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks,
                      const BlockDataID & uFieldId, const BlockDataID & fFieldId, const BlockDataID & stencilFieldId ) :
       StencilFieldSweepBase< Stencil_T >( uFieldId, fFieldId, stencilFieldId ), blocks_( blocks ) {}
 
-   void operator()( IBlock * const block ) const { WALBERLA_ABORT( "You are not allowed to use class 'RBGS' as a standard sweep!\n"
+   void operator()( IBlock * const /*block*/ ) const { WALBERLA_ABORT( "You are not allowed to use class 'RBGS' as a standard sweep!\n"
                                                                    "Use the member functions 'getRedSweep' and 'getBlackSweep' instead." ); }
 
    void update( IBlock * const block, const bool rb );
diff --git a/src/pde/sweeps/RBGSFixedStencil.h b/src/pde/sweeps/RBGSFixedStencil.h
index 5b57cc351de611f8046f9b3edf82aab084b5f5be..bce7f30fe2195c302caefaca77c184f396887cc5 100644
--- a/src/pde/sweeps/RBGSFixedStencil.h
+++ b/src/pde/sweeps/RBGSFixedStencil.h
@@ -39,13 +39,13 @@ class RBGSFixedStencil : public StencilSweepBase< Stencil_T >
 {
 public:
 
-   typedef typename StencilSweepBase< Stencil_T >::Field_T Field_T;
+   using Field_T = typename StencilSweepBase<Stencil_T>::Field_T;
    
    RBGSFixedStencil( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks,
                      const BlockDataID & uFieldId, const BlockDataID & fFieldId, const std::vector< real_t > & weights ) :
       StencilSweepBase< Stencil_T >( uFieldId, fFieldId, weights ), blocks_( blocks ) {}
 
-   void operator()( IBlock * const block ) const { WALBERLA_ABORT( "You are not allowed to use class 'RBGSFixedStencil' as a standard sweep!\n"
+   void operator()( IBlock * const /*block*/ ) const { WALBERLA_ABORT( "You are not allowed to use class 'RBGSFixedStencil' as a standard sweep!\n"
                                                                    "Use the member functions 'getRedSweep' and 'getBlackSweep' instead." ); }
 
    void update( IBlock * const block, const bool rb );
@@ -83,7 +83,7 @@ void RBGSFixedStencil< Stencil_T >::update( IBlock * const block, const bool rb
    WALBERLA_ASSERT_GREATER_EQUAL( uf->nrOfGhostLayers(), 1 );
 
    // stencil weights
-   real_t weights[ Stencil_T::Size ];
+   std::array<real_t, Stencil_T::Size> weights;
    for( auto dir = Stencil_T::beginNoCenter(); dir != Stencil_T::end(); ++dir )
       weights[ dir.toIdx() ] = this->w( dir.toIdx() );
    weights[ Stencil_T::idx[ stencil::C ] ] = real_t(1) / this->w( Stencil_T::idx[ stencil::C ] ); // center already inverted here!
diff --git a/src/pde/sweeps/SOR.h b/src/pde/sweeps/SOR.h
index 48a0b56e35561d06f5112fad685e12600da6a586..d1993fb702667e1bba7ffd27d56d0a670b17560c 100644
--- a/src/pde/sweeps/SOR.h
+++ b/src/pde/sweeps/SOR.h
@@ -39,14 +39,14 @@ class SOR : public StencilFieldSweepBase< Stencil_T >
 {
 public:
 
-   typedef typename StencilFieldSweepBase< Stencil_T >::Field_T         Field_T;
-   typedef typename StencilFieldSweepBase< Stencil_T >::StencilField_T  StencilField_T;
+   using Field_T = typename StencilFieldSweepBase<Stencil_T>::Field_T;
+   using StencilField_T = typename StencilFieldSweepBase<Stencil_T>::StencilField_T;
 
    SOR( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks,
                     const BlockDataID & uFieldId, const BlockDataID & fFieldId, const BlockDataID & stencilFieldId, const real_t omega ) :
       StencilFieldSweepBase< Stencil_T >( uFieldId, fFieldId, stencilFieldId ), blocks_( blocks ), omega_( omega ) {}
 
-   void operator()( IBlock * const block ) const { WALBERLA_ABORT( "You are not allowed to use class 'SOR' as a standard sweep!\n"
+   void operator()( IBlock * const /*block*/ ) const { WALBERLA_ABORT( "You are not allowed to use class 'SOR' as a standard sweep!\n"
                                                                    "Use the member functions 'getRedSweep' and 'getBlackSweep' instead." ); }
 
    void update( IBlock * const block, const bool rb );
diff --git a/src/pde/sweeps/SORFixedStencil.h b/src/pde/sweeps/SORFixedStencil.h
index 0e9387309fe0e7009aabd9b21d87347f9b0a9254..0f1cd8af290d2812020ce16db172ffc18dc5149f 100644
--- a/src/pde/sweeps/SORFixedStencil.h
+++ b/src/pde/sweeps/SORFixedStencil.h
@@ -39,13 +39,13 @@ class SORFixedStencil : public StencilSweepBase< Stencil_T >
 {
 public:
 
-   typedef typename StencilSweepBase< Stencil_T >::Field_T Field_T;
+   using Field_T = typename StencilSweepBase<Stencil_T>::Field_T;
 
    SORFixedStencil( const shared_ptr< domain_decomposition::StructuredBlockStorage > & blocks,
                     const BlockDataID & uFieldId, const BlockDataID & fFieldId, const std::vector< real_t > & weights, const real_t omega ) :
       StencilSweepBase< Stencil_T >( uFieldId, fFieldId, weights ), blocks_( blocks ), omega_( omega ) {}
 
-   void operator()( IBlock * const block ) const { WALBERLA_ABORT( "You are not allowed to use class 'SORFixedStencil' as a standard sweep!\n"
+   void operator()( IBlock * const /*block*/ ) const { WALBERLA_ABORT( "You are not allowed to use class 'SORFixedStencil' as a standard sweep!\n"
                                                                    "Use the member functions 'getRedSweep' and 'getBlackSweep' instead." ); }
 
    void update( IBlock * const block, const bool rb );
@@ -83,7 +83,7 @@ void SORFixedStencil< Stencil_T >::update( IBlock * const block, const bool rb )
    WALBERLA_ASSERT_GREATER_EQUAL( uf->nrOfGhostLayers(), 1 );
 
    // stencil weights
-   real_t weights[ Stencil_T::Size ];
+   std::array<real_t, Stencil_T::Size> weights;
    for( auto dir = Stencil_T::beginNoCenter(); dir != Stencil_T::end(); ++dir )
       weights[ dir.toIdx() ] = this->w( dir.toIdx() );
    weights[ Stencil_T::idx[ stencil::C ] ] = real_t(1) / this->w( Stencil_T::idx[ stencil::C ] ); // center already inverted here!
diff --git a/src/pde/sweeps/StencilFieldSweepBase.h b/src/pde/sweeps/StencilFieldSweepBase.h
index ca37c945ce24b3a23727762d1ef6883e66585bc4..7d10268ea8e83370c42349df0aca9a6da710222a 100644
--- a/src/pde/sweeps/StencilFieldSweepBase.h
+++ b/src/pde/sweeps/StencilFieldSweepBase.h
@@ -37,8 +37,8 @@ class StencilFieldSweepBase : public SweepBase
 {
 public:
 
-   typedef SweepBase::Field_T                                 Field_T;
-   typedef GhostLayerField< real_t, Stencil_T::Size >  StencilField_T;
+   using Field_T = SweepBase::Field_T;
+   using StencilField_T = GhostLayerField<real_t, Stencil_T::Size>;
 
    // block has NO dst u field
    StencilFieldSweepBase( const BlockDataID & uFieldId, const BlockDataID & fFieldId, const BlockDataID & stencilFieldId ) :
diff --git a/src/pde/sweeps/StencilSweepBase.h b/src/pde/sweeps/StencilSweepBase.h
index 5c2f88cebc61d1845ba031b915a559f87a2fd732..d10e29df0dffbbe4840ad6c924bfe5487273fb68 100644
--- a/src/pde/sweeps/StencilSweepBase.h
+++ b/src/pde/sweeps/StencilSweepBase.h
@@ -37,7 +37,7 @@ class StencilSweepBase : public SweepBase
 {
 public:
 
-   typedef SweepBase::Field_T Field_T;
+   using Field_T = SweepBase::Field_T;
 
    // block has NO dst u field
    StencilSweepBase( const BlockDataID & uFieldId, const BlockDataID & fFieldId, const std::vector< real_t > & weights ) :
@@ -63,7 +63,7 @@ protected:
 
 
 
-   real_t w_[ Stencil_T::Size ];
+   std::array<real_t, Stencil_T::Size> w_;
 };
 
 
diff --git a/src/pde/sweeps/SweepBase.h b/src/pde/sweeps/SweepBase.h
index e8fe9fb43509ef9af54080146f6fcc310955cc03..261e2c0714e36847e2e412027ce9af9d6908fa1c 100644
--- a/src/pde/sweeps/SweepBase.h
+++ b/src/pde/sweeps/SweepBase.h
@@ -49,7 +49,7 @@ public:
    SweepBase( const BlockDataID & src, const BlockDataID & dst, const BlockDataID & fFieldId ) :
       src_( src ), f_( fFieldId ), dstFromBlockData_( true ), dst_( dst ) {}
 
-   virtual ~SweepBase() { for( auto field = dstFields_.begin(); field != dstFields_.end(); ++field ) delete *field; }
+   virtual ~SweepBase() { for(auto dstField : dstFields_) delete dstField; }
 
 protected:
 
diff --git a/src/pe/Materials.cpp b/src/pe/Materials.cpp
index baa82126a69ca992cfccea9804b9d04be3d0ea95..98f5984e96a4c07db9252284db34704d321c514b 100644
--- a/src/pe/Materials.cpp
+++ b/src/pe/Materials.cpp
@@ -71,36 +71,51 @@ bool Material::activateMaterials()
    materials_.push_back( Fir()     );
 
    // Initializing the coefficients of restitution
-   //                       | Iron                   | Copper                 | Granite                | Oak                    | Fir                     |
-   const real_t cor[5][5] = {
-                            { static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25) },  // Iron
-                            { static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25) },  // Copper
-                            { static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25) },  // Granite
-                            { static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25) },  // Oak
-                            { static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25), static_cast<real_t>(0.25) }   // Fir
-                          };
+   //                                                    | Iron                   | Copper                 | Granite                | Oak                    | Fir                     |
+   const std::array< std::array< real_t, 5 >, 5 > cor = { {
+      { { static_cast< real_t >(0.25), static_cast< real_t >(0.25), static_cast< real_t >(0.25),
+          static_cast< real_t >(0.25), static_cast< real_t >(0.25) } }, // Iron
+      { { static_cast< real_t >(0.25), static_cast< real_t >(0.25), static_cast< real_t >(0.25),
+          static_cast< real_t >(0.25), static_cast< real_t >(0.25) } }, // Copper
+      { { static_cast< real_t >(0.25), static_cast< real_t >(0.25), static_cast< real_t >(0.25),
+          static_cast< real_t >(0.25), static_cast< real_t >(0.25) } }, // Granite
+      { { static_cast< real_t >(0.25), static_cast< real_t >(0.25), static_cast< real_t >(0.25),
+          static_cast< real_t >(0.25), static_cast< real_t >(0.25) } }, // Oak
+      { { static_cast< real_t >(0.25), static_cast< real_t >(0.25), static_cast< real_t >(0.25),
+          static_cast< real_t >(0.25), static_cast< real_t >(0.25) } } // Fir
+   } };
    corTable_ = cor;
 
    // Initializing the coefficients of static friction
    //                       | Iron                   | Copper                 | Granite                | Oak                    | Fir                     |
-   const real_t csf[5][5] = {
-                            { static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20) },  // Iron
-                            { static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20) },  // Copper
-                            { static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20) },  // Granite
-                            { static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20) },  // Oak
-                            { static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20) }   // Fir
-                          };
+   const std::array< std::array< real_t, 5 >, 5 > csf = { {
+      { { static_cast< real_t >(0.20), static_cast< real_t >(0.20), static_cast< real_t >(0.20),
+          static_cast< real_t >(0.20), static_cast< real_t >(0.20) } }, // Iron
+      { { static_cast< real_t >(0.20), static_cast< real_t >(0.20), static_cast< real_t >(0.20),
+          static_cast< real_t >(0.20), static_cast< real_t >(0.20) } }, // Copper
+      { { static_cast< real_t >(0.20), static_cast< real_t >(0.20), static_cast< real_t >(0.20),
+          static_cast< real_t >(0.20), static_cast< real_t >(0.20) } }, // Granite
+      { { static_cast< real_t >(0.20), static_cast< real_t >(0.20), static_cast< real_t >(0.20),
+          static_cast< real_t >(0.20), static_cast< real_t >(0.20) } }, // Oak
+      { { static_cast< real_t >(0.20), static_cast< real_t >(0.20), static_cast< real_t >(0.20),
+          static_cast< real_t >(0.20), static_cast< real_t >(0.20) } } // Fir
+   } };
    csfTable_ = csf;
 
    // Initializing the coefficients of dynamic friction
    //                       | Iron                   | Copper                 | Granite                | Oak                    | Fir                     |
-   const real_t cdf[5][5] = {
-                            { static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20) },  // Iron
-                            { static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20) },  // Copper
-                            { static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20) },  // Granite
-                            { static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20) },  // Oak
-                            { static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20), static_cast<real_t>(0.20) }   // Fir
-                          };
+   const std::array< std::array< real_t, 5 >, 5 > cdf = { {
+      { { static_cast< real_t >(0.20), static_cast< real_t >(0.20), static_cast< real_t >(0.20),
+          static_cast< real_t >(0.20), static_cast< real_t >(0.20) } }, // Iron
+      { { static_cast< real_t >(0.20), static_cast< real_t >(0.20), static_cast< real_t >(0.20),
+          static_cast< real_t >(0.20), static_cast< real_t >(0.20) } }, // Copper
+      { { static_cast< real_t >(0.20), static_cast< real_t >(0.20), static_cast< real_t >(0.20),
+          static_cast< real_t >(0.20), static_cast< real_t >(0.20) } }, // Granite
+      { { static_cast< real_t >(0.20), static_cast< real_t >(0.20), static_cast< real_t >(0.20),
+          static_cast< real_t >(0.20), static_cast< real_t >(0.20) } }, // Oak
+      { { static_cast< real_t >(0.20), static_cast< real_t >(0.20), static_cast< real_t >(0.20),
+          static_cast< real_t >(0.20), static_cast< real_t >(0.20) } } // Fir
+   } };
    cdfTable_ = cdf;
 
    return true;
diff --git a/src/pe/raytracing/Ray.h b/src/pe/raytracing/Ray.h
index 052ee87bf4cd11398d9e3229808068600741eb24..1555545db22c970c3f53a110f97d84ff2846c614 100644
--- a/src/pe/raytracing/Ray.h
+++ b/src/pe/raytracing/Ray.h
@@ -27,7 +27,7 @@
 namespace walberla {
 namespace pe {
 namespace raytracing {
-   
+
 class Ray {
 public:
    /*!\name Constructors */
@@ -37,7 +37,7 @@ public:
    Ray () {
       Ray (Vec3(0,0,0), Vec3(1,0,0));
    }
-   
+
    /*!\brief Instantiation constructor for the Raytracer class.
     * \param origin Origin of the ray. ()
     * \param direction Normalized direction of the ray.
@@ -68,38 +68,38 @@ public:
    inline const Vec3& getOrigin () const {
       return origin_;
    }
-   
+
    /*!\brief Returns the normalized direction vector of the ray.
     */
    inline const Vec3& getDirection () const {
       return direction_;
    }
-   
+
    /*!\brief Returns the normalized direction vector of the ray for a given axis.
     */
    inline real_t getDirection (size_t axis) const {
       WALBERLA_ASSERT(axis <= 2, "No valid axis index passed.");
       return direction_[axis];
    }
-   
+
    /*!\brief Returns the x component of the ray direction.
     */
    inline real_t xDir () const {
       return direction_[0];
    }
-   
+
    /*!\brief Returns the y component of the ray direction.
     */
    inline real_t yDir () const {
       return direction_[1];
    }
-   
+
    /*!\brief Returns the z component of the ray direction.
     */
    inline real_t zDir () const {
       return direction_[2];
    }
-   
+
    /*!\brief Returns the inverse of the direction vector of the ray.
     */
    inline const Vec3& getInvDirection () const {
@@ -112,25 +112,25 @@ public:
       WALBERLA_ASSERT(axis <= 2, "No valid axis index passed.");
       return inv_direction_[axis];
    }
-   
+
    /*!\brief Returns the x component of the inverse ray direction.
     */
    inline real_t xInvDir () const {
       return inv_direction_[0];
    }
-   
+
    /*!\brief Returns the y component of the inverse ray direction.
     */
    inline real_t yInvDir () const {
       return inv_direction_[1];
    }
-   
+
    /*!\brief Returns the z component of the inverse ray direction.
     */
    inline real_t zInvDir () const {
       return inv_direction_[2];
    }
-   
+
    /*!\brief Returns the signs of the inverted direction vector of the ray.
     *
     * Returns the signs of the inverted direction vector of the ray as required for the ray-box intersection algorithm.
@@ -138,7 +138,7 @@ public:
    inline const Vector3<int8_t>& getInvDirectionSigns () const {
       return sign_;
    }
-   
+
    /*!\brief Returns the X value of the pixel coordinate this ray intersects.
     *
     * \return X value of pixel coordinate.
@@ -146,7 +146,7 @@ public:
    inline size_t getImageX () const {
       return imageX_;
    }
-   
+
    /*!\brief Returns the Y value of the pixel coordinate this ray intersects.
     *
     * \return Y value of pixel coordinate.
@@ -164,7 +164,7 @@ public:
    inline void setOrigin (const Vec3& origin) {
       origin_ = origin;
    }
-   
+
    /*!\brief Set the _normalized_ direction vector of the ray.
     * \param direction Normalized direction vector
     */
@@ -174,7 +174,7 @@ public:
       direction_ = direction;
       calcInvDirection();
    }
-   
+
    /*!\brief Sets the X and Y values of the image pixel coordinate this ray intersects.
     * \param x X value of the pixel coordinate
     * \param y Y value of the pixel coordinate
@@ -183,14 +183,14 @@ public:
       imageX_ = x;
       imageY_ = y;
    }
-   
+
    /*!\brief Sets the X value of the image pixel coordinate this ray intersects.
     * \param x X value of the pixel coordinate
     */
    inline void setImageX (size_t x) {
       imageX_ = x;
    }
-   
+
    /*!\brief Sets the Y value of the image pixel coordinate this ray intersects.
     * \param y Y value of the pixel coordinate
     */
@@ -209,12 +209,12 @@ public:
       sign_[1] = (inv_direction_[1] < 0) ? int8_t(1) : int8_t(0);
       sign_[2] = (inv_direction_[2] < 0) ? int8_t(1) : int8_t(0);
    }
-   
+
    /*!\brief Transforms the ray to the body frame.
     *
     * \return Ray transformed to the body frame.
     */
-   inline Ray transformedToBF(const BodyID body) const {
+   inline Ray transformedToBF(ConstBodyID body) const {
       return Ray(body->pointFromWFtoBF(getOrigin()), body->vectorFromWFtoBF(getDirection()));
    }
    //@}
@@ -222,4 +222,4 @@ public:
 
 } //namespace raytracing
 } //namespace pe
-} //namespace walberla
+} //namespace walberla
\ No newline at end of file
diff --git a/src/postprocessing/FieldToSurfaceMesh.cpp b/src/postprocessing/FieldToSurfaceMesh.cpp
index 94ab735c48bc582ba9831223e57c402900c3251d..97de86d82ae3271f633c4d6d505a638cb91f0cb8 100644
--- a/src/postprocessing/FieldToSurfaceMesh.cpp
+++ b/src/postprocessing/FieldToSurfaceMesh.cpp
@@ -88,7 +88,7 @@ shared_ptr<TriangleMesh> gatherMesh( const shared_ptr<TriangleMesh> & mesh, bool
       return mesh;
    }
    else
-      return shared_ptr<geometry::TriangleMesh>();
+      return {};
 }
 
 
diff --git a/src/postprocessing/FieldToSurfaceMesh.h b/src/postprocessing/FieldToSurfaceMesh.h
index 5fe433dd1566a6c03043e15345c82fbc51a8dc47..32771e3f42497ec095707847ebde64ea3170a7bd 100644
--- a/src/postprocessing/FieldToSurfaceMesh.h
+++ b/src/postprocessing/FieldToSurfaceMesh.h
@@ -58,7 +58,7 @@ namespace postprocessing {
                                                               bool calcNormals = false,
                                                               int targetRank = 0, MPI_Comm comm = MPI_COMM_WORLD )
    {
-      static_assert( std::is_unsigned<typename Field_T::value_type>::value, "Works only for FlagFields" );
+      static_assert( std::is_unsigned_v<typename Field_T::value_type>, "Works only for FlagFields" );
       static_assert( Field_T::F_SIZE == 1, "Works only for FlagFields" );
 
 
@@ -120,7 +120,7 @@ namespace postprocessing {
                                                               uint_t fCoord = 0, bool calcNormals = false,
                                                               int targetRank = 0, MPI_Comm comm = MPI_COMM_WORLD )
    {
-      static_assert( (std::is_same< typename Field_T::value_type, real_t >::value), "Function works only for fields of real" );
+      static_assert( (std::is_same_v< typename Field_T::value_type, real_t >), "Function works only for fields of real" );
 
       auto mesh = make_shared<geometry::TriangleMesh> ();
 
diff --git a/src/postprocessing/MarchingCubes.impl.h b/src/postprocessing/MarchingCubes.impl.h
index 2ac3bfd2500f6779d5a60d66ce819b455e0456ce..0e059b4f43827d67657f1d6129fa495c45fd9435 100644
--- a/src/postprocessing/MarchingCubes.impl.h
+++ b/src/postprocessing/MarchingCubes.impl.h
@@ -67,7 +67,7 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
                                   uint_t fCoord, const Vector3<real_t> & posOffset,
                                   const CellInterval & cellInterval )
 {
-   static_assert( (std::is_same<typename Field_T::value_type, real_t>::value ), "Currently only real valued fields are supported" );
+   static_assert( (std::is_same_v<typename Field_T::value_type, real_t> ), "Currently only real valued fields are supported" );
 
    CellInterval targetInterval = cellInterval;
    if ( targetInterval.empty() )
@@ -82,7 +82,7 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
     * which of the 8 vertices of the cube lies under the threshold.
     * The returned bitmask indicates which edges are intersected.
     */
-   static const short mcEdgeTable[256]={
+   static const std::array<short, 256> mcEdgeTable={
       0x0  , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
       0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
       0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
@@ -117,7 +117,7 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
       0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0   };
 
 
-   static const short mcTriTable[256][16] = {
+   static const std::array< std::array< short, 16 >, 256 > mcTriTable = {{
       {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
       {0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
       {0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
@@ -374,7 +374,7 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
       {0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
       {0, 3, 8, -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, -1, -1}
-   };
+   }};
 
 
 
@@ -389,22 +389,22 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
    RealVec3 ey (0,dx[1],0);
    RealVec3 ez (0,0,dx[2]);
 
-   int cubeIndex;      // index entry of the cube
+   uint_t cubeIndex;      // index entry of the cube
 
    // edges between which points?
-   const int mcEdges[24] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0,
+   const std::array< int, 24 > mcEdges = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0,
                              4, 1, 5, 2, 6, 3, 7 };
 
-   const int cubieOffsetX[8] = { 0, 1, 1, 0, 0, 1, 1, 0 };
-   const int cubieOffsetY[8] = { 0, 0, 1, 1, 0, 0, 1, 1 };
-   const int cubieOffsetZ[8] = { 0, 0, 0, 0, 1, 1, 1, 1 };
+   const std::array< int, 8 > cubieOffsetX = { 0, 1, 1, 0, 0, 1, 1, 0 };
+   const std::array< int, 8 > cubieOffsetY = { 0, 0, 1, 1, 0, 0, 1, 1 };
+   const std::array< int, 8 > cubieOffsetZ = { 0, 0, 0, 0, 1, 1, 1, 1 };
 
    for( auto i = f.beginSliceXYZ(targetInterval); i != f.end(); ++i )
    {
       const RealVec3 offset (- real_t(0.5)*dx[0],-real_t(0.5)*dx[1],-real_t(0.5)*dx[2]);
       RealVec3 curPos = offset + i.x() * ex +  i.y() * ey + i.z() * ez;
 
-      real_t value [8];
+      std::array< real_t, 8 > value;
       value[0] = real_c( i.getF( fCoord )              );
       value[1] = real_c( i.neighbor( 1, 0, 0, fCoord ) );
       value[2] = real_c( i.neighbor( 1, 1, 0, fCoord ) );
@@ -415,7 +415,7 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
       value[7] = real_c( i.neighbor( 0, 1, 1, fCoord ) );
 
       cubeIndex = 0;
-      for(int j=0; j< 8; ++j)
+      for(uint_t j=0; j< 8; ++j)
          if(value[j] < threshold)
             cubeIndex |= 1 << j;
 
@@ -425,7 +425,7 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
       }
 
       // where to look up if this point already exists
-      int * eVert[12];
+      std::array < int*, 12 > eVert;
       eVert[0] = &edgeVerticesField.get(i.x()  ,i.y()  ,i.z()  ,0);
       eVert[1] = &edgeVerticesField.get(i.x()+1,i.y()  ,i.z()  ,1);
       eVert[2] = &edgeVerticesField.get(i.x()  ,i.y()+1,i.z()  ,0);
@@ -442,7 +442,7 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
       eVert[11]= &edgeVerticesField.get(i.x()  , i.y()+1, i.z(), 2);
 
       // grid positions
-      RealVec3 pos[8];
+      std::array< RealVec3, 8 > pos;
       pos[0] = curPos;
       pos[1] = curPos + ex;
       pos[2] = curPos + ex + ey;
@@ -453,7 +453,7 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
       pos[7] = curPos + ey + ez;
 
 
-      TriangleMesh::index_t triIndices[12]; // vertex indices (intersection point for each edge)
+      std::array< TriangleMesh::index_t, 12 > triIndices; // vertex indices (intersection point for each edge)
 
       // check all edges
       for ( uint_t e = 0; e < 12; e++ ) // for all edges
@@ -468,10 +468,10 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
             // not pre-computed, then interpolate edge
             const int e1 = mcEdges[e * 2];
             const int e2 = mcEdges[e * 2 + 1];
-            const RealVec3 p1 = pos[e1];    // scalar field pos 1
-            const RealVec3 p2 = pos[e2];    // scalar field pos 2
-            const real_t valp1 = value[e1]; // scalar field val 1
-            const real_t valp2 = value[e2]; // scalar field val 2
+            const RealVec3 p1 = pos[uint_t(e1)];    // scalar field pos 1
+            const RealVec3 p2 = pos[uint_t(e2)];    // scalar field pos 2
+            const real_t valp1 = value[uint_t(e1)]; // scalar field val 1
+            const real_t valp2 = value[uint_t(e2)]; // scalar field val 2
             const real_t mu = (threshold - valp1) / (valp2 - valp1);
             TriangleMesh::vertex_t position  = p1 + (p2 - p1) * mu + posOffset;
 
@@ -479,12 +479,12 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
 
             if ( calcNormals )
             {
-               TriangleMesh::normal_t normal    = calcNormal(f, i.x() + cubieOffsetX[e1],
-                                                                i.y() + cubieOffsetY[e1],
-                                                                i.z() + cubieOffsetZ[e1], fCoord ) * (real_t(1) - mu)
-                                                + calcNormal(f, i.x() + cubieOffsetX[e2],
-                                                                i.y() + cubieOffsetY[e2],
-                                                                i.z() + cubieOffsetZ[e2], fCoord) * (mu);
+               TriangleMesh::normal_t normal    = calcNormal(f, i.x() + cubieOffsetX[uint_c(e1)],
+                                                                i.y() + cubieOffsetY[uint_c(e1)],
+                                                                i.z() + cubieOffsetZ[uint_c(e1)], fCoord ) * (real_t(1) - mu)
+                                                + calcNormal(f, i.x() + cubieOffsetX[uint_c(e2)],
+                                                                i.y() + cubieOffsetY[uint_c(e2)],
+                                                                i.z() + cubieOffsetZ[uint_c(e2)], fCoord) * (mu);
 
                if (normal.sqrLength() > 1e-8 )
                   normalize(normal);
@@ -498,22 +498,22 @@ void generateIsoSurface_internal( const Field_T & f, real_t threshold,
       }// for all edges
 
       // Create the triangles...
-      for (int e = 0; mcTriTable[cubeIndex][e] != -1; e += 3)
+      for (uint_t e = 0; mcTriTable[cubeIndex][e] != -1; e += 3)
       {
          if ( calcNormals )
          {
-            mesh.addTriangle(triIndices[mcTriTable[cubeIndex][e + 0]],
-                             triIndices[mcTriTable[cubeIndex][e + 1]],
-                             triIndices[mcTriTable[cubeIndex][e + 2]],
-                             triIndices[mcTriTable[cubeIndex][e + 0]],
-                             triIndices[mcTriTable[cubeIndex][e + 1]],
-                             triIndices[mcTriTable[cubeIndex][e + 2]]);
+            mesh.addTriangle(triIndices[uint_t(mcTriTable[cubeIndex][e + 0])],
+                             triIndices[uint_t(mcTriTable[cubeIndex][e + 1])],
+                             triIndices[uint_t(mcTriTable[cubeIndex][e + 2])],
+                             triIndices[uint_t(mcTriTable[cubeIndex][e + 0])],
+                             triIndices[uint_t(mcTriTable[cubeIndex][e + 1])],
+                             triIndices[uint_t(mcTriTable[cubeIndex][e + 2])]);
          }
          else
          {
-            mesh.addTriangle(triIndices[mcTriTable[cubeIndex][e + 0]],
-                             triIndices[mcTriTable[cubeIndex][e + 1]],
-                             triIndices[mcTriTable[cubeIndex][e + 2]] );
+            mesh.addTriangle(triIndices[uint_t(mcTriTable[cubeIndex][e + 0])],
+                             triIndices[uint_t(mcTriTable[cubeIndex][e + 1])],
+                             triIndices[uint_t(mcTriTable[cubeIndex][e + 2])] );
          }
       }
    }
diff --git a/src/sqlite/SQLite.cpp b/src/sqlite/SQLite.cpp
index 2670a5c483e52573e0b300312084589b8bb5127c..09a88d2ab41002e11e961914c2ddc1da7a9777f8 100644
--- a/src/sqlite/SQLite.cpp
+++ b/src/sqlite/SQLite.cpp
@@ -34,7 +34,7 @@ namespace sqlite {
 
 
 SQLiteDB::SQLiteDB( const string & dbFile, const int busyTimeout )
-   : valid_(true), dbHandle_(nullptr), file_( dbFile )
+   : file_( dbFile )
 {
    static const char * CREATE_RUN_TABLE =
          "CREATE TABLE IF NOT EXISTS runs ("
@@ -43,7 +43,7 @@ SQLiteDB::SQLiteDB( const string & dbFile, const int busyTimeout )
          " uuid      STRING );" ;
 
    // Create tables if it does not exist
-   int retVal = sqlite3_open( file_.c_str(), &dbHandle_ );
+   int const retVal = sqlite3_open( file_.c_str(), &dbHandle_ );
    if ( retVal != SQLITE_OK ) {
       WALBERLA_LOG_WARNING( "Failed to open sqlite3 file." << dbFile );
       valid_ = false;
@@ -101,16 +101,16 @@ uint_t storeRunImpl( sqlite3 * dbHandle, std::string & filename,
    {
       insertRunCommand += "," + i->first;
       values  << ", " << i->second;
-      string command = "ALTER TABLE runs ADD COLUMN " + i->first + " INTEGER ";
+      string const command = "ALTER TABLE runs ADD COLUMN " + i->first + " INTEGER ";
       sqlite3_exec ( dbHandle, command.c_str(), nullptr,nullptr,nullptr ); // ignore errors (column can exist already)
    }
 
    // Add columns for string properties
-   for ( auto i = stringProperties.begin(); i != stringProperties.end(); ++i )
+   for (const auto & stringPropertie : stringProperties)
    {
-      insertRunCommand += "," + i->first;
-      values << ", " << "\"" << i->second << "\"";
-      string command = "ALTER TABLE runs ADD COLUMN " + i->first + " TEXT ";
+      insertRunCommand += "," + stringPropertie.first;
+      values << ", " << "\"" << stringPropertie.second << "\"";
+      string const command = "ALTER TABLE runs ADD COLUMN " + stringPropertie.first + " TEXT ";
       sqlite3_exec ( dbHandle, command.c_str(), nullptr,nullptr,nullptr ); // ignore errors (column can exist already)
 
    }
@@ -122,7 +122,7 @@ uint_t storeRunImpl( sqlite3 * dbHandle, std::string & filename,
       {
          insertRunCommand += "," + i->first;
          values << ", " << i->second;
-         string command = "ALTER TABLE runs ADD COLUMN " + i->first + " DOUBLE ";
+         string const command = "ALTER TABLE runs ADD COLUMN " + i->first + " DOUBLE ";
          sqlite3_exec( dbHandle, command.c_str(), nullptr, nullptr, nullptr ); // ignore errors (column can exist already)
       }
       else
@@ -133,12 +133,12 @@ uint_t storeRunImpl( sqlite3 * dbHandle, std::string & filename,
    }
 
    // Add columns for global state selectors
-   for( auto i = uid::globalState().begin(); i != uid::globalState().end(); ++i )
+   for(auto i : uid::globalState())
    {
-      insertRunCommand += "," + i->getIdentifier();
+      insertRunCommand += "," + i.getIdentifier();
       values << " ,1";
       // no boolean in sqlite3, use integer instead
-      string command = "ALTER TABLE runs ADD COLUMN " + i->getIdentifier() + " INTEGER ";
+      string const command = "ALTER TABLE runs ADD COLUMN " + i.getIdentifier() + " INTEGER ";
       sqlite3_exec ( dbHandle, command.c_str(), nullptr,nullptr,nullptr ); // ignore errors (column can exist already)
    }
 
@@ -146,11 +146,11 @@ uint_t storeRunImpl( sqlite3 * dbHandle, std::string & filename,
    values << "); ";
    insertRunCommand += values.str();
 
-   int ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), nullptr, nullptr, nullptr );
+   int const ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), nullptr, nullptr, nullptr );
    if ( ret != SQLITE_OK) {
       WALBERLA_LOG_WARNING( "Failed to insert a row into run table of sqlite3 database: " << sqlite3_errmsg(dbHandle) << "\n sql command: " << insertRunCommand.c_str() );
    }
-   uint_t generatedPrimaryKey = uint_c ( sqlite3_last_insert_rowid( dbHandle ) );
+   uint_t const generatedPrimaryKey = uint_c ( sqlite3_last_insert_rowid( dbHandle ) );
 
    sqlite3_exec( dbHandle, "END TRANSACTION;",nullptr,nullptr,nullptr );
 
@@ -175,7 +175,7 @@ void storeAdditionalRunInfoImpl( sqlite3 * dbHandle,
                                  const map<string, double > & realProperties )
 {
    sqlite3_exec( dbHandle, "BEGIN;",nullptr,nullptr,nullptr );
-   std::string CREATE_TABLE =
+   std::string const CREATE_TABLE =
          "CREATE TABLE IF NOT EXISTS " + tableName +
          " (runId     INTEGER, "
          " FOREIGN KEY (runId) REFERENCES runs(runId) "
@@ -191,26 +191,26 @@ void storeAdditionalRunInfoImpl( sqlite3 * dbHandle,
    {
       insertRunCommand += "," + i->first;
       values  << ", " << i->second;
-      string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " INTEGER ";
+      string const command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " INTEGER ";
       sqlite3_exec ( dbHandle, command.c_str(), nullptr,nullptr,nullptr ); // ignore errors (column can exist already)
    }
 
    // Add columns for string properties
-   for ( auto i = stringProperties.begin(); i != stringProperties.end(); ++i )
+   for (const auto & stringPropertie : stringProperties)
    {
-      insertRunCommand += "," + i->first;
-      values << ", " << "\"" << i->second << "\"";
-      string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " TEXT ";
+      insertRunCommand += "," + stringPropertie.first;
+      values << ", " << "\"" << stringPropertie.second << "\"";
+      string const command = "ALTER TABLE " + tableName + " ADD COLUMN " + stringPropertie.first + " TEXT ";
       sqlite3_exec ( dbHandle, command.c_str(), nullptr,nullptr,nullptr ); // ignore errors (column can exist already)
 
    }
 
    // Add columns for real_t properties
-   for ( auto i = realProperties.begin(); i != realProperties.end(); ++i )
+   for (const auto & realPropertie : realProperties)
    {
-      insertRunCommand += "," + i->first;
-      values << ", " << i->second ;
-      string command = "ALTER TABLE " + tableName + " ADD COLUMN " + i->first + " DOUBLE ";
+      insertRunCommand += "," + realPropertie.first;
+      values << ", " << realPropertie.second ;
+      string const command = "ALTER TABLE " + tableName + " ADD COLUMN " + realPropertie.first + " DOUBLE ";
       sqlite3_exec ( dbHandle, command.c_str(), nullptr,nullptr,nullptr ); // ignore errors (column can exist already)
    }
 
@@ -218,7 +218,7 @@ void storeAdditionalRunInfoImpl( sqlite3 * dbHandle,
    values << "); ";
    insertRunCommand += values.str();
 
-   int ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), nullptr, nullptr, nullptr );
+   int const ret = sqlite3_exec ( dbHandle, insertRunCommand.c_str(), nullptr, nullptr, nullptr );
    if ( ret != SQLITE_OK) {
       WALBERLA_LOG_WARNING( "Failed to insert a row into run table of sqlite3 database: " << sqlite3_errmsg(dbHandle) << "\n sql command: " << insertRunCommand.c_str() );
    }
@@ -297,7 +297,7 @@ void SQLiteDB::storeTimingPool ( uint_t runId,
 {
    sqlite3_exec( dbHandle_, "BEGIN;",nullptr,nullptr,nullptr );
 
-   assert ( timingPoolName.length() > 0 && timingPoolName.length() < 255 );
+   assert ( !timingPoolName.empty() && timingPoolName.length() < 255 );
 
    static const char * CREATE_TIMINGPOOL_TABLE =
          "CREATE TABLE IF NOT EXISTS timingPool ("
@@ -329,21 +329,21 @@ void SQLiteDB::storeTimingPool ( uint_t runId,
 
 
    double totalTime = 0;
-   for ( auto i = tp.begin(); i != tp.end(); ++i )
-      totalTime += i->second.total();
+   for (const auto & i : tp)
+      totalTime += i.second.total();
 
 
-   for ( auto i = tp.begin(); i != tp.end(); ++i )
+   for (const auto & i : tp)
    {
       sqlite3_bind_int64 ( stmt, 1, int64_c(runId) );
       sqlite3_bind_text  ( stmt, 2, timingPoolName.c_str() , -1, SQLITE_STATIC );
-      sqlite3_bind_text  ( stmt, 3, i->first.c_str() , -1, SQLITE_STATIC );
-      sqlite3_bind_double( stmt, 4, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.average() ) ) );
-      sqlite3_bind_double( stmt, 5, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.min() ) ) );
-      sqlite3_bind_double( stmt, 6, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.max() ) ) );
-      sqlite3_bind_int64 ( stmt, 7, int64_c   ( i->second.getCounter() ));
-      sqlite3_bind_double( stmt, 8, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.variance() ) ) );
-      sqlite3_bind_double( stmt, 9, ( ( i->second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i->second.total() / totalTime ) ) );
+      sqlite3_bind_text  ( stmt, 3, i.first.c_str() , -1, SQLITE_STATIC );
+      sqlite3_bind_double( stmt, 4, ( ( i.second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i.second.average() ) ) );
+      sqlite3_bind_double( stmt, 5, ( ( i.second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i.second.min() ) ) );
+      sqlite3_bind_double( stmt, 6, ( ( i.second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i.second.max() ) ) );
+      sqlite3_bind_int64 ( stmt, 7, int64_c   ( i.second.getCounter() ));
+      sqlite3_bind_double( stmt, 8, ( ( i.second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i.second.variance() ) ) );
+      sqlite3_bind_double( stmt, 9, ( ( i.second.getCounter() == uint_t(0) ) ? 0.0 : double_c( i.second.total() / totalTime ) ) );
 
       sqlite3_step ( stmt );  // execute statement
       sqlite3_reset ( stmt ); // undo binding
@@ -369,7 +369,7 @@ void SQLiteDB::storeTimingTree ( uint_t runId,
 {
    sqlite3_exec( dbHandle_, "BEGIN;",nullptr,nullptr,nullptr );
 
-   assert ( timingTreeName.length() > 0 && timingTreeName.length() < 255 );
+   assert ( !timingTreeName.empty() && timingTreeName.length() < 255 );
 
    static const char * CREATE_TIMINGTREE_TABLE =
          "CREATE TABLE IF NOT EXISTS timingTree ("
@@ -390,9 +390,9 @@ void SQLiteDB::storeTimingTree ( uint_t runId,
    sqlite3_exec( dbHandle_, CREATE_TIMINGTREE_TABLE, nullptr,nullptr,nullptr );
 
    double totalTime = 0.0;
-   for (auto it = tt.getRawData().tree_.begin(); it != tt.getRawData().tree_.end(); ++it)
+   for (const auto & it : tt.getRawData().tree_)
    {
-      totalTime += it->second.timer_.total();
+      totalTime += it.second.timer_.total();
    }
 
    storeTimingNode(runId, std::numeric_limits<int>::max(), tt.getRawData(), timingTreeName, "Total", totalTime);
@@ -442,11 +442,11 @@ void SQLiteDB::storeTimingNode ( const uint_t runId,
    sqlite3_reset ( stmt ); // undo binding
    sqlite3_finalize( stmt ); // free prepared statement
 
-   int currentId = int_c( sqlite3_last_insert_rowid( dbHandle_ ) );
+   int const currentId = int_c( sqlite3_last_insert_rowid( dbHandle_ ) );
 
-   for ( auto i = tn.tree_.begin(); i != tn.tree_.end(); ++i )
+   for (const auto & i : tn.tree_)
    {
-      storeTimingNode( runId, currentId, i->second, timingTreeName, i->first, totalTime);
+      storeTimingNode( runId, currentId, i.second, timingTreeName, i.first, totalTime);
    }
 }
 
diff --git a/src/sqlite/SQLite.h b/src/sqlite/SQLite.h
index 84ba2746643d120f41fc8e363f3cdd32c4bde118..0d6c94cdc5233297c44ebab0590b08655e123bd9 100644
--- a/src/sqlite/SQLite.h
+++ b/src/sqlite/SQLite.h
@@ -83,8 +83,8 @@ private:
                           const std::string & sweep,
                           const double totalTime );
 
-   bool valid_;
-   sqlite3 * dbHandle_;
+   bool valid_{true};
+   sqlite3 * dbHandle_{nullptr};
    std::string file_;
 };
 
diff --git a/src/stencil/D2CornerStencil.h b/src/stencil/D2CornerStencil.h
index 5888bad3047a336dd2aafba3ca2cf93e607b956d..a6e1e76285286d796171aa9bf89c44faf499f570 100644
--- a/src/stencil/D2CornerStencil.h
+++ b/src/stencil/D2CornerStencil.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = false;
          static const uint_t noCenterFirstIdx = 0;
 
-         static const Direction dir           [4];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][4/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 4 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 4/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D2CornerStencil<Dummy>::dir[4] = { NW,NE,SW,SE };
+      const std::array< Direction, 4 > D2CornerStencil<Dummy>::dir{ NW,NE,SW,SE };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D2CornerStencil<Dummy>::dir_pos[POS_Q] = { NE,SE };
+      const std::array< Direction, D2CornerStencil<Dummy>::POS_Q > D2CornerStencil<Dummy>::dir_pos{ NE,SE };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D2CornerStencil<Dummy>::idx[NR_OF_DIRECTIONS] = { INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,0,1,2,3,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D2CornerStencil<Dummy>::idx{ INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,0,1,2,3,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D2CornerStencil<Dummy>::d_per_d[NR_OF_DIRECTIONS][4/2] = { {},
+      const std::array< std::array< Direction, 4/2 >, NR_OF_DIRECTIONS > D2CornerStencil<Dummy>::d_per_d{ { {},
 								{NW,NE},
 								{SW,SE},
 								{NW,SW},
@@ -180,7 +180,7 @@ namespace stencil {
 								{},
 								{},
 								{},
-								{} };
+								{} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D2CornerStencil<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 0,2,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D2CornerStencil<Dummy>::d_per_d_length{ 0,2,2,2,2,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D2CornerStencil<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {NW,NE,SW,SE},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D2CornerStencil<Dummy>::dir_neighbors{ { {NW,NE,SW,SE},
 								{W,E},
 								{W,E},
 								{N,S},
@@ -227,7 +227,7 @@ namespace stencil {
 								{B},
 								{B},
 								{B},
-								{B} };
+								{B} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D2CornerStencil<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 4,2,2,2,2,4,4,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D2CornerStencil<Dummy>::dir_neighbors_length{ 4,2,2,2,2,4,4,1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 };
 
    } // namespace internal
 
diff --git a/src/stencil/D2Q4.h b/src/stencil/D2Q4.h
index 294f3551220fe8ddd3e21b72e276e46254cffa10..80f4f0e73ededa7ff29b5c504df68fa169ec9883 100644
--- a/src/stencil/D2Q4.h
+++ b/src/stencil/D2Q4.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = false;
          static const uint_t noCenterFirstIdx = 0;
 
-         static const Direction dir           [4];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][4/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 4 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 4/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D2Q4<Dummy>::dir[4] = { N,S,W,E };
+      const std::array< Direction, 4 > D2Q4<Dummy>::dir{ N,S,W,E };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D2Q4<Dummy>::dir_pos[POS_Q] = { N,E };
+      const std::array< Direction, D2Q4<Dummy>::POS_Q > D2Q4<Dummy>::dir_pos{ N,E };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D2Q4<Dummy>::idx[NR_OF_DIRECTIONS] = { INVALID_DIR,0,1,2,3,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D2Q4<Dummy>::idx{ INVALID_DIR,0,1,2,3,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D2Q4<Dummy>::d_per_d[NR_OF_DIRECTIONS][4/2] = { {},
+      const std::array< std::array< Direction, 4/2 >, NR_OF_DIRECTIONS > D2Q4<Dummy>::d_per_d{ { {},
 								{N},
 								{S},
 								{W},
@@ -180,7 +180,7 @@ namespace stencil {
 								{},
 								{},
 								{},
-								{} };
+								{} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D2Q4<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D2Q4<Dummy>::d_per_d_length{ 0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D2Q4<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {N,S,W,E},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D2Q4<Dummy>::dir_neighbors{ { {N,S,W,E},
 								{C,NW,NE},
 								{C,SW,SE},
 								{C,NW,SW},
@@ -227,7 +227,7 @@ namespace stencil {
 								{BN,BE},
 								{BN,BW},
 								{BS,BE},
-								{BS,BW} };
+								{BS,BW} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D2Q4<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 4,3,3,3,3,4,4,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D2Q4<Dummy>::dir_neighbors_length{ 4,3,3,3,3,4,4,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2 };
 
    } // namespace internal
 
diff --git a/src/stencil/D2Q5.h b/src/stencil/D2Q5.h
index a09f40cdc1dcdb25be2cc79fde4484fa2cb6c1df..361e4db4d706032bef01a3180deb9f3eefe71d61 100644
--- a/src/stencil/D2Q5.h
+++ b/src/stencil/D2Q5.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = true;
          static const uint_t noCenterFirstIdx = 1;
 
-         static const Direction dir           [5];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][5/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 5 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 5/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D2Q5<Dummy>::dir[5] = { C,N,S,W,E };
+      const std::array< Direction, 5 > D2Q5<Dummy>::dir{ C,N,S,W,E };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D2Q5<Dummy>::dir_pos[POS_Q] = { N,E };
+      const std::array< Direction, D2Q5<Dummy>::POS_Q > D2Q5<Dummy>::dir_pos{ N,E };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D2Q5<Dummy>::idx[NR_OF_DIRECTIONS] = { 0,1,2,3,4,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D2Q5<Dummy>::idx{ 0,1,2,3,4,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D2Q5<Dummy>::d_per_d[NR_OF_DIRECTIONS][5/2] = { {C},
+      const std::array< std::array< Direction, 5/2 >, NR_OF_DIRECTIONS > D2Q5<Dummy>::d_per_d{ { {C},
 								{N},
 								{S},
 								{W},
@@ -180,7 +180,7 @@ namespace stencil {
 								{},
 								{},
 								{},
-								{} };
+								{} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D2Q5<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D2Q5<Dummy>::d_per_d_length{ 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D2Q5<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {N,S,W,E},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D2Q5<Dummy>::dir_neighbors{ { {N,S,W,E},
 								{C,NW,NE},
 								{C,SW,SE},
 								{C,NW,SW},
@@ -227,7 +227,7 @@ namespace stencil {
 								{BN,BE},
 								{BN,BW},
 								{BS,BE},
-								{BS,BW} };
+								{BS,BW} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D2Q5<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 4,3,3,3,3,4,4,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D2Q5<Dummy>::dir_neighbors_length{ 4,3,3,3,3,4,4,2,2,2,2,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2 };
 
    } // namespace internal
 
diff --git a/src/stencil/D2Q9.h b/src/stencil/D2Q9.h
index 5d55c7fe89b21b6f571faa1920ea476d16ba70c8..87c59e7567b68218d2605d4d23eb372c177627e8 100644
--- a/src/stencil/D2Q9.h
+++ b/src/stencil/D2Q9.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = true;
          static const uint_t noCenterFirstIdx = 1;
 
-         static const Direction dir           [9];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][9/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 9 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 9/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D2Q9<Dummy>::dir[9] = { C,N,S,W,E,NW,NE,SW,SE };
+      const std::array< Direction, 9 > D2Q9<Dummy>::dir{ C,N,S,W,E,NW,NE,SW,SE };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D2Q9<Dummy>::dir_pos[POS_Q] = { N,E,NE,SE };
+      const std::array< Direction, D2Q9<Dummy>::POS_Q > D2Q9<Dummy>::dir_pos{ N,E,NE,SE };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D2Q9<Dummy>::idx[NR_OF_DIRECTIONS] = { 0,1,2,3,4,INVALID_DIR,INVALID_DIR,5,6,7,8,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D2Q9<Dummy>::idx{ 0,1,2,3,4,INVALID_DIR,INVALID_DIR,5,6,7,8,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D2Q9<Dummy>::d_per_d[NR_OF_DIRECTIONS][9/2] = { {C},
+      const std::array< std::array< Direction, 9/2 >, NR_OF_DIRECTIONS > D2Q9<Dummy>::d_per_d{ { {C},
 								{N,NW,NE},
 								{S,SW,SE},
 								{W,NW,SW},
@@ -180,7 +180,7 @@ namespace stencil {
 								{},
 								{},
 								{},
-								{} };
+								{} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D2Q9<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 1,3,3,3,3,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D2Q9<Dummy>::d_per_d_length{ 1,3,3,3,3,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D2Q9<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {N,S,W,E,NW,NE,SW,SE},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D2Q9<Dummy>::dir_neighbors{ { {N,S,W,E,NW,NE,SW,SE},
 								{C,W,E,NW,NE},
 								{C,W,E,SW,SE},
 								{C,N,S,NW,SW},
@@ -227,7 +227,7 @@ namespace stencil {
 								{B,BN,BE},
 								{B,BN,BW},
 								{B,BS,BE},
-								{B,BS,BW} };
+								{B,BS,BW} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D2Q9<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 8,5,5,5,5,8,8,3,3,3,3,5,5,5,5,5,5,5,5,3,3,3,3,3,3,3,3 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D2Q9<Dummy>::dir_neighbors_length{ 8,5,5,5,5,8,8,3,3,3,3,5,5,5,5,5,5,5,5,3,3,3,3,3,3,3,3 };
 
    } // namespace internal
 
diff --git a/src/stencil/D3CornerStencil.h b/src/stencil/D3CornerStencil.h
index 5df290d22b164f08858ed455ed0678f0654e4b17..746879f36ecf2921d68bf721870cf5ec6bee2786 100644
--- a/src/stencil/D3CornerStencil.h
+++ b/src/stencil/D3CornerStencil.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = false;
          static const uint_t noCenterFirstIdx = 0;
 
-         static const Direction dir           [8];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][8/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 8 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 8/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D3CornerStencil<Dummy>::dir[8] = { TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW };
+      const std::array< Direction, 8 > D3CornerStencil<Dummy>::dir{ TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D3CornerStencil<Dummy>::dir_pos[POS_Q] = { TNE,TSE,BNE,BSE };
+      const std::array< Direction, D3CornerStencil<Dummy>::POS_Q > D3CornerStencil<Dummy>::dir_pos{ TNE,TSE,BNE,BSE };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D3CornerStencil<Dummy>::idx[NR_OF_DIRECTIONS] = { INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,0,1,2,3,4,5,6,7 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3CornerStencil<Dummy>::idx{ INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,0,1,2,3,4,5,6,7 };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D3CornerStencil<Dummy>::d_per_d[NR_OF_DIRECTIONS][8/2] = { {},
+      const std::array< std::array< Direction, 8/2 >, NR_OF_DIRECTIONS > D3CornerStencil<Dummy>::d_per_d{ { {},
 								{TNE,TNW,BNE,BNW},
 								{TSE,TSW,BSE,BSW},
 								{TNW,TSW,BNW,BSW},
@@ -180,7 +180,7 @@ namespace stencil {
 								{BNE},
 								{BNW},
 								{BSE},
-								{BSW} };
+								{BSW} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D3CornerStencil<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 0,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3CornerStencil<Dummy>::d_per_d_length{ 0,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D3CornerStencil<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D3CornerStencil<Dummy>::dir_neighbors{ { {TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW},
 								{TW,TE,BW,BE},
 								{TW,TE,BW,BE},
 								{TN,TS,BN,BS},
@@ -227,7 +227,7 @@ namespace stencil {
 								{C},
 								{C},
 								{C},
-								{C} };
+								{C} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D3CornerStencil<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 8,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D3CornerStencil<Dummy>::dir_neighbors_length{ 8,4,4,4,4,4,4,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 };
 
    } // namespace internal
 
diff --git a/src/stencil/D3EdgeCornerStencil.h b/src/stencil/D3EdgeCornerStencil.h
index 318752ead018b307f59f2fc01f3a6827b6e99284..f71f62677aebad53ce2861bbea8252ef10742592 100644
--- a/src/stencil/D3EdgeCornerStencil.h
+++ b/src/stencil/D3EdgeCornerStencil.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = false;
          static const uint_t noCenterFirstIdx = 0;
 
-         static const Direction dir           [20];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][20/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 20 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 20/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D3EdgeCornerStencil<Dummy>::dir[20] = { NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW };
+      const std::array< Direction, 20 > D3EdgeCornerStencil<Dummy>::dir{ NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D3EdgeCornerStencil<Dummy>::dir_pos[POS_Q] = { NE,SE,TN,TE,BN,BE,TNE,TSE,BNE,BSE };
+      const std::array< Direction, D3EdgeCornerStencil<Dummy>::POS_Q > D3EdgeCornerStencil<Dummy>::dir_pos{ NE,SE,TN,TE,BN,BE,TNE,TSE,BNE,BSE };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D3EdgeCornerStencil<Dummy>::idx[NR_OF_DIRECTIONS] = { INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3EdgeCornerStencil<Dummy>::idx{ INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D3EdgeCornerStencil<Dummy>::d_per_d[NR_OF_DIRECTIONS][20/2] = { {},
+      const std::array< std::array< Direction, 20/2 >, NR_OF_DIRECTIONS > D3EdgeCornerStencil<Dummy>::d_per_d{ { {},
 								{NW,NE,TN,BN,TNE,TNW,BNE,BNW},
 								{SW,SE,TS,BS,TSE,TSW,BSE,BSW},
 								{NW,SW,TW,BW,TNW,TSW,BNW,BSW},
@@ -180,7 +180,7 @@ namespace stencil {
 								{BNE},
 								{BNW},
 								{BSE},
-								{BSW} };
+								{BSW} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D3EdgeCornerStencil<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 0,8,8,8,8,8,8,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3EdgeCornerStencil<Dummy>::d_per_d_length{ 0,8,8,8,8,8,8,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D3EdgeCornerStencil<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D3EdgeCornerStencil<Dummy>::dir_neighbors{ { {NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW},
 								{W,E,T,B,TW,TE,BW,BE,TNE,TNW,BNE,BNW},
 								{W,E,T,B,TW,TE,BW,BE,TSE,TSW,BSE,BSW},
 								{N,S,T,B,TN,TS,BN,BS,TNW,TSW,BNW,BSW},
@@ -227,7 +227,7 @@ namespace stencil {
 								{C,N,E,B},
 								{C,N,W,B},
 								{C,S,E,B},
-								{C,S,W,B} };
+								{C,S,W,B} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D3EdgeCornerStencil<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 20,12,12,12,12,12,12,7,7,7,7,7,7,7,7,7,7,7,7,4,4,4,4,4,4,4,4 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D3EdgeCornerStencil<Dummy>::dir_neighbors_length{ 20,12,12,12,12,12,12,7,7,7,7,7,7,7,7,7,7,7,7,4,4,4,4,4,4,4,4 };
 
    } // namespace internal
 
diff --git a/src/stencil/D3Q15.h b/src/stencil/D3Q15.h
index 32dab37b9eba8182d69d8d5873f5c4ecfd1d46e3..6ce85a15865341b7d566fec3a46d9eecdc017c45 100644
--- a/src/stencil/D3Q15.h
+++ b/src/stencil/D3Q15.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = true;
          static const uint_t noCenterFirstIdx = 1;
 
-         static const Direction dir           [15];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][15/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 15 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 15/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D3Q15<Dummy>::dir[15] = { C,N,S,W,E,T,B,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW };
+      const std::array< Direction, 15 > D3Q15<Dummy>::dir{ C,N,S,W,E,T,B,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D3Q15<Dummy>::dir_pos[POS_Q] = { N,E,T,TNE,TSE,BNE,BSE };
+      const std::array< Direction, D3Q15<Dummy>::POS_Q > D3Q15<Dummy>::dir_pos{ N,E,T,TNE,TSE,BNE,BSE };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D3Q15<Dummy>::idx[NR_OF_DIRECTIONS] = { 0,1,2,3,4,5,6,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,7,8,9,10,11,12,13,14 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3Q15<Dummy>::idx{ 0,1,2,3,4,5,6,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,7,8,9,10,11,12,13,14 };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D3Q15<Dummy>::d_per_d[NR_OF_DIRECTIONS][15/2] = { {C},
+      const std::array< std::array< Direction, 15/2 >, NR_OF_DIRECTIONS > D3Q15<Dummy>::d_per_d{ { {C},
 								{N,TNE,TNW,BNE,BNW},
 								{S,TSE,TSW,BSE,BSW},
 								{W,TNW,TSW,BNW,BSW},
@@ -180,7 +180,7 @@ namespace stencil {
 								{BNE},
 								{BNW},
 								{BSE},
-								{BSW} };
+								{BSW} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D3Q15<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 1,5,5,5,5,5,5,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3Q15<Dummy>::d_per_d_length{ 1,5,5,5,5,5,5,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D3Q15<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {N,S,W,E,T,B,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D3Q15<Dummy>::dir_neighbors{ { {N,S,W,E,T,B,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW},
 								{C,NW,NE,TN,TW,TE,BN,BW,BE},
 								{C,SW,SE,TS,TW,TE,BS,BW,BE},
 								{C,NW,SW,TN,TS,TW,BN,BS,BW},
@@ -227,7 +227,7 @@ namespace stencil {
 								{C,NE,BN,BE},
 								{C,NW,BN,BW},
 								{C,SE,BS,BE},
-								{C,SW,BS,BW} };
+								{C,SW,BS,BW} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D3Q15<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 14,9,9,9,9,9,9,6,6,6,6,6,6,6,6,6,6,6,6,4,4,4,4,4,4,4,4 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D3Q15<Dummy>::dir_neighbors_length{ 14,9,9,9,9,9,9,6,6,6,6,6,6,6,6,6,6,6,6,4,4,4,4,4,4,4,4 };
 
    } // namespace internal
 
diff --git a/src/stencil/D3Q19.h b/src/stencil/D3Q19.h
index 6077893823241858a2bb90bec3743825869e6f05..437f51d0a5fea744bf9d5f786c869f7da8680640 100644
--- a/src/stencil/D3Q19.h
+++ b/src/stencil/D3Q19.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = true;
          static const uint_t noCenterFirstIdx = 1;
 
-         static const Direction dir           [19];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][19/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 19 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 19/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D3Q19<Dummy>::dir[19] = { C,N,S,W,E,T,B,NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE };
+      const std::array< Direction, 19 > D3Q19<Dummy>::dir{ C,N,S,W,E,T,B,NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D3Q19<Dummy>::dir_pos[POS_Q] = { N,E,T,NE,SE,TN,TE,BN,BE };
+      const std::array< Direction, D3Q19<Dummy>::POS_Q > D3Q19<Dummy>::dir_pos{ N,E,T,NE,SE,TN,TE,BN,BE };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D3Q19<Dummy>::idx[NR_OF_DIRECTIONS] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3Q19<Dummy>::idx{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D3Q19<Dummy>::d_per_d[NR_OF_DIRECTIONS][19/2] = { {C},
+      const std::array< std::array< Direction, 19/2 >, NR_OF_DIRECTIONS > D3Q19<Dummy>::d_per_d{ { {C},
 								{N,NW,NE,TN,BN},
 								{S,SW,SE,TS,BS},
 								{W,NW,SW,TW,BW},
@@ -180,7 +180,7 @@ namespace stencil {
 								{},
 								{},
 								{},
-								{} };
+								{} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D3Q19<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 1,5,5,5,5,5,5,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3Q19<Dummy>::d_per_d_length{ 1,5,5,5,5,5,5,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D3Q19<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {N,S,W,E,T,B,NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D3Q19<Dummy>::dir_neighbors{ { {N,S,W,E,T,B,NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE},
 								{C,W,E,T,B,NW,NE,TN,BN,TNE,TNW,BNE,BNW},
 								{C,W,E,T,B,SW,SE,TS,BS,TSE,TSW,BSE,BSW},
 								{C,N,S,T,B,NW,SW,TW,BW,TNW,TSW,BNW,BSW},
@@ -227,7 +227,7 @@ namespace stencil {
 								{N,E,B,NE,BN,BE},
 								{N,W,B,NW,BN,BW},
 								{S,E,B,SE,BS,BE},
-								{S,W,B,SW,BS,BW} };
+								{S,W,B,SW,BS,BW} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D3Q19<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 18,13,13,13,13,13,13,9,9,9,9,9,9,9,9,9,9,9,9,6,6,6,6,6,6,6,6 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D3Q19<Dummy>::dir_neighbors_length{ 18,13,13,13,13,13,13,9,9,9,9,9,9,9,9,9,9,9,9,6,6,6,6,6,6,6,6 };
 
    } // namespace internal
 
diff --git a/src/stencil/D3Q27.h b/src/stencil/D3Q27.h
index 74b986f4a2ea9fcefdda55a87cf014aef0e9cd4e..e181804b0c74f71d3b60705646178812a0171c47 100644
--- a/src/stencil/D3Q27.h
+++ b/src/stencil/D3Q27.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = true;
          static const uint_t noCenterFirstIdx = 1;
 
-         static const Direction dir           [27];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][27/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 27 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 27/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D3Q27<Dummy>::dir[27] = { C,N,S,W,E,T,B,NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW };
+      const std::array< Direction, 27 > D3Q27<Dummy>::dir{ C,N,S,W,E,T,B,NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D3Q27<Dummy>::dir_pos[POS_Q] = { N,E,T,NE,SE,TN,TE,BN,BE,TNE,TSE,BNE,BSE };
+      const std::array< Direction, D3Q27<Dummy>::POS_Q > D3Q27<Dummy>::dir_pos{ N,E,T,NE,SE,TN,TE,BN,BE,TNE,TSE,BNE,BSE };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D3Q27<Dummy>::idx[NR_OF_DIRECTIONS] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3Q27<Dummy>::idx{ 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D3Q27<Dummy>::d_per_d[NR_OF_DIRECTIONS][27/2] = { {C},
+      const std::array< std::array< Direction, 27/2 >, NR_OF_DIRECTIONS > D3Q27<Dummy>::d_per_d{ { {C},
 								{N,NW,NE,TN,BN,TNE,TNW,BNE,BNW},
 								{S,SW,SE,TS,BS,TSE,TSW,BSE,BSW},
 								{W,NW,SW,TW,BW,TNW,TSW,BNW,BSW},
@@ -180,7 +180,7 @@ namespace stencil {
 								{BNE},
 								{BNW},
 								{BSE},
-								{BSW} };
+								{BSW} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D3Q27<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 1,9,9,9,9,9,9,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3Q27<Dummy>::d_per_d_length{ 1,9,9,9,9,9,9,3,3,3,3,3,3,3,3,3,3,3,3,1,1,1,1,1,1,1,1 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D3Q27<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {N,S,W,E,T,B,NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D3Q27<Dummy>::dir_neighbors{ { {N,S,W,E,T,B,NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE,TNE,TNW,TSE,TSW,BNE,BNW,BSE,BSW},
 								{C,W,E,T,B,NW,NE,TN,TW,TE,BN,BW,BE,TNE,TNW,BNE,BNW},
 								{C,W,E,T,B,SW,SE,TS,TW,TE,BS,BW,BE,TSE,TSW,BSE,BSW},
 								{C,N,S,T,B,NW,SW,TN,TS,TW,BN,BS,BW,TNW,TSW,BNW,BSW},
@@ -227,7 +227,7 @@ namespace stencil {
 								{C,N,E,B,NE,BN,BE},
 								{C,N,W,B,NW,BN,BW},
 								{C,S,E,B,SE,BS,BE},
-								{C,S,W,B,SW,BS,BW} };
+								{C,S,W,B,SW,BS,BW} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D3Q27<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 26,17,17,17,17,17,17,11,11,11,11,11,11,11,11,11,11,11,11,7,7,7,7,7,7,7,7 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D3Q27<Dummy>::dir_neighbors_length{ 26,17,17,17,17,17,17,11,11,11,11,11,11,11,11,11,11,11,11,7,7,7,7,7,7,7,7 };
 
    } // namespace internal
 
diff --git a/src/stencil/D3Q6.h b/src/stencil/D3Q6.h
index 249b4dc5427d9232a9673928be5c1f8c6ea1efc6..7bd6f0b50edd7774720ac90343f82754438e2215 100644
--- a/src/stencil/D3Q6.h
+++ b/src/stencil/D3Q6.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = false;
          static const uint_t noCenterFirstIdx = 0;
 
-         static const Direction dir           [6];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][6/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 6 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 6/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D3Q6<Dummy>::dir[6] = { N,S,W,E,T,B };
+      const std::array< Direction, 6 > D3Q6<Dummy>::dir{ N,S,W,E,T,B };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D3Q6<Dummy>::dir_pos[POS_Q] = { N,E,T };
+      const std::array< Direction, D3Q6<Dummy>::POS_Q > D3Q6<Dummy>::dir_pos{ N,E,T };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D3Q6<Dummy>::idx[NR_OF_DIRECTIONS] = { INVALID_DIR,0,1,2,3,4,5,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3Q6<Dummy>::idx{ INVALID_DIR,0,1,2,3,4,5,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D3Q6<Dummy>::d_per_d[NR_OF_DIRECTIONS][6/2] = { {},
+      const std::array< std::array< Direction, 6/2 >, NR_OF_DIRECTIONS > D3Q6<Dummy>::d_per_d{ { {},
 								{N},
 								{S},
 								{W},
@@ -180,7 +180,7 @@ namespace stencil {
 								{},
 								{},
 								{},
-								{} };
+								{} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D3Q6<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3Q6<Dummy>::d_per_d_length{ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D3Q6<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {N,S,W,E,T,B},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D3Q6<Dummy>::dir_neighbors{ { {N,S,W,E,T,B},
 								{C,NW,NE,TN,BN},
 								{C,SW,SE,TS,BS},
 								{C,NW,SW,TW,BW},
@@ -227,7 +227,7 @@ namespace stencil {
 								{NE,BN,BE},
 								{NW,BN,BW},
 								{SE,BS,BE},
-								{SW,BS,BW} };
+								{SW,BS,BW} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D3Q6<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D3Q6<Dummy>::dir_neighbors_length{ 6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3 };
 
    } // namespace internal
 
diff --git a/src/stencil/D3Q7.h b/src/stencil/D3Q7.h
index 33ecb5b14eb63661ec7bded54da25779ed9a60f6..948e1304f9a745aef7d390734b30226223c66cef 100644
--- a/src/stencil/D3Q7.h
+++ b/src/stencil/D3Q7.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = true;
          static const uint_t noCenterFirstIdx = 1;
 
-         static const Direction dir           [7];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][7/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 7 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 7/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction D3Q7<Dummy>::dir[7] = { C,N,S,W,E,T,B };
+      const std::array< Direction, 7 > D3Q7<Dummy>::dir{ C,N,S,W,E,T,B };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction D3Q7<Dummy>::dir_pos[POS_Q] = { N,E,T };
+      const std::array< Direction, D3Q7<Dummy>::POS_Q > D3Q7<Dummy>::dir_pos{ N,E,T };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t D3Q7<Dummy>::idx[NR_OF_DIRECTIONS] = { 0,1,2,3,4,5,6,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3Q7<Dummy>::idx{ 0,1,2,3,4,5,6,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction D3Q7<Dummy>::d_per_d[NR_OF_DIRECTIONS][7/2] = { {C},
+      const std::array< std::array< Direction, 7/2 >, NR_OF_DIRECTIONS > D3Q7<Dummy>::d_per_d{ { {C},
 								{N},
 								{S},
 								{W},
@@ -180,7 +180,7 @@ namespace stencil {
 								{},
 								{},
 								{},
-								{} };
+								{} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t D3Q7<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > D3Q7<Dummy>::d_per_d_length{ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction D3Q7<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {N,S,W,E,T,B},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > D3Q7<Dummy>::dir_neighbors{ { {N,S,W,E,T,B},
 								{C,NW,NE,TN,BN},
 								{C,SW,SE,TS,BS},
 								{C,NW,SW,TW,BW},
@@ -227,7 +227,7 @@ namespace stencil {
 								{NE,BN,BE},
 								{NW,BN,BW},
 								{SE,BS,BE},
-								{SW,BS,BW} };
+								{SW,BS,BW} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t D3Q7<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> D3Q7<Dummy>::dir_neighbors_length{ 6,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3 };
 
    } // namespace internal
 
diff --git a/src/stencil/Directions.h b/src/stencil/Directions.h
index 9071405a2604c49980a3734ba592b3427f70fb90..3144fd227546e5fc457756d527db532a87e4b47c 100644
--- a/src/stencil/Directions.h
+++ b/src/stencil/Directions.h
@@ -105,25 +105,25 @@ namespace stencil {
    };
 
    /// The x component for each direction  \ingroup stencil
-   const int cx[NR_OF_DIRECTIONS] =  {
+   const std::array< int, NR_OF_DIRECTIONS > cx  {
    // C   N   S   W   E   T   B  NW  NE  SW  SE  TN  TS  TW  TE  BN  BS  BW  BE TNE TNW TSE TSW BNE BNW BSE BSW
       0,  0,  0, -1,  1,  0,  0, -1,  1, -1,  1,  0,  0, -1,  1,  0,  0, -1,  1,  1, -1,  1, -1,  1, -1,  1, -1
    };
 
    /// The y component for each direction \ingroup stencil
-   const int cy[NR_OF_DIRECTIONS] =  {
+   const std::array< int, NR_OF_DIRECTIONS > cy  {
    // C   N   S   W   E   T   B  NW  NE  SW  SE  TN  TS  TW  TE  BN  BS  BW  BE TNE TNW TSE TSW BNE BNW BSE BSW
       0,  1, -1,  0,  0,  0,  0,  1,  1, -1, -1,  1, -1,  0,  0,  1, -1,  0,  0,  1,  1, -1, -1,  1,  1, -1, -1
    };
 
    /// The z component for each direction \ingroup stencil
-   const int cz[NR_OF_DIRECTIONS] =  {
+   const std::array< int, NR_OF_DIRECTIONS > cz  {
    // C   N   S   W   E   T   B  NW  NE  SW  SE  TN  TS  TW  TE  BN  BS  BW  BE TNE TNW TSE TSW BNE BNW BSE BSW
       0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  1,  1,  1,  1, -1, -1, -1, -1,  1,  1,  1,  1, -1, -1, -1, -1
    };
 
    /// The x,y,z component for each direction \ingroup stencil
-   const int c[3][NR_OF_DIRECTIONS] = {
+   const std::array< std::array< int, NR_OF_DIRECTIONS >, 3 > c { {
       {
    // C   N   S   W   E   T   B  NW  NE  SW  SE  TN  TS  TW  TE  BN  BS  BW  BE TNE TNW TSE TSW BNE BNW BSE BSW
       0,  0,  0, -1,  1,  0,  0, -1,  1, -1,  1,  0,  0, -1,  1,  0,  0, -1,  1,  1, -1,  1, -1,  1, -1,  1, -1
@@ -134,30 +134,30 @@ namespace stencil {
    // C   N   S   W   E   T   B  NW  NE  SW  SE  TN  TS  TW  TE  BN  BS  BW  BE TNE TNW TSE TSW BNE BNW BSE BSW
       0,  0,  0,  0,  0,  1, -1,  0,  0,  0,  0,  1,  1,  1,  1, -1, -1, -1, -1,  1,  1,  1,  1, -1, -1, -1, -1
       }
-   };
+   } };
 
 
    /// Maps a (x,y,z) direction vector to its direction \ingroup stencil
    inline Direction vectorToDirection(cell_idx_t x, cell_idx_t y, cell_idx_t z){
-      static const Direction vecToDirArr[3][3][3] = {
-         {  // x = -1
+      static const std::array< std::array< std::array< Direction, 3 >, 3 >, 3 > vecToDirArr {{
+         {{  // x = -1
             {BSW, SW, TSW},   // y = -1
             {BW, W, TW},      // y = 0
             {BNW, NW, TNW}    // y = 1
-         },
-         {  // x = 0
+         }},
+         {{  // x = 0
             {BS, S, TS},      // y = -1
             {B, C, T},        // y = 0
             {BN, N, TN}       // y = 1
-         },
-         {  // x = 1
+         }},
+         {{  // x = 1
             {BSE, SE, TSE},   // y = -1
             {BE, E, TE},      // y = 0
             {BNE, NE, TNE}    // y = 1
-         }
-      };
+         }}
+      }};
 
-      return vecToDirArr[x + 1][y + 1][z + 1];
+      return vecToDirArr[uint32_c(x + 1)][uint32_c(y + 1)][uint32_c(z + 1)];
    }
 
    inline Direction vectorToDirection(Vector3< cell_idx_t > vec){
@@ -170,7 +170,7 @@ namespace stencil {
 
 
    /// The x,y,z component for each normalized direction \ingroup stencil
-   const real_t cNorm[3][NR_OF_DIRECTIONS] = {
+   const std::array< std::array< real_t, NR_OF_DIRECTIONS >, 3 > cNorm { {
       {
          real_t(0), real_t(0), real_t(0), real_t(-1), real_t(1), real_t(0), real_t(0), real_t(-1) / std::sqrt( real_t(2) ),
          real_t(1) / std::sqrt( real_t(2) ), real_t(-1) / std::sqrt( real_t(2) ), real_t(1) / std::sqrt( real_t(2) ), real_t(0), real_t(0),
@@ -194,31 +194,31 @@ namespace stencil {
          real_t(-1) / std::sqrt( real_t(3) ), real_t(-1) / std::sqrt( real_t(3) ), real_t(-1) / std::sqrt( real_t(3) ),
          real_t(-1) / std::sqrt( real_t(3) )
       }
-   };
+   } };
 
    /// String representation for each direction \ingroup stencil
-   const std::string dirToString[NR_OF_DIRECTIONS] =  {
+   const std::array< std::string, NR_OF_DIRECTIONS > dirToString {
       "C", "N", "S", "W", "E", "T", "B",
       "NW", "NE", "SW", "SE", "TN", "TS", "TW", "TE", "BN", "BS", "BW","BE",
       "TNE", "TNW", "TSE", "TSW", "BNE", "BNW", "BSE", "BSW",
    };
 
    /// Binary encoded direction for each direction \ingroup stencil
-   const BinaryDirection dirToBinary[27] = {
+   const std::array< BinaryDirection, NR_OF_DIRECTIONS > dirToBinary {
       Bin_C, Bin_N, Bin_S, Bin_W, Bin_E, Bin_T, Bin_B,
       Bin_NW, Bin_NE, Bin_SW, Bin_SE, Bin_TN, Bin_TS, Bin_TW, Bin_TE, Bin_BN, Bin_BS, Bin_BW, Bin_BE,
       Bin_TNE, Bin_TNW, Bin_TSE, Bin_TSW, Bin_BNE, Bin_BNW, Bin_BSE, Bin_BSW,
    };
 
    /// Inverse directions  \ingroup stencil
-   const Direction inverseDir[NR_OF_DIRECTIONS] = {
+   const std::array< Direction, NR_OF_DIRECTIONS > inverseDir {
       C, S, N, E, W, B, T,
       SE, SW, NE, NW, BS, BN, BE, BW, TS, TN, TE, TW,
       BSW, BSE, BNW, BNE, TSW, TSE, TNW, TNE
    };
 
    /// Length for each direction \ingroup stencil
-   const real_t dirLength [NR_OF_DIRECTIONS] = {
+   const std::array< real_t, NR_OF_DIRECTIONS > dirLength {
         real_t(0), real_t(1), real_t(1), real_t(1), real_t(1), real_t(1), real_t(1),
         std::sqrt( real_t(2) ), std::sqrt( real_t(2) ), std::sqrt( real_t(2) ), std::sqrt( real_t(2) ), 
         std::sqrt( real_t(2) ), std::sqrt( real_t(2) ), std::sqrt( real_t(2) ), std::sqrt( real_t(2) ),
@@ -228,9 +228,7 @@ namespace stencil {
    };
 
 
-   const real_t gaussianWeights [NR_OF_DIRECTIONS] =
-   {
-      //C  N   S   W   E   T   B   NW  NE  SW  SE  TN  TS  TW  TE  BN  BS  BW  BE  TNE TNW TSE TSW BNE BNW BSE BSW
+   const std::array< real_t, NR_OF_DIRECTIONS > gaussianWeights {
       real_t(8) / real_t(64),
       real_t(4) / real_t(64), real_t(4) / real_t(64), real_t(4) / real_t(64), real_t(4) / real_t(64),
       real_t(4) / real_t(64), real_t(4) / real_t(64),
@@ -242,9 +240,7 @@ namespace stencil {
    };
 
 
-   const uint_t gaussianMultipliers [NR_OF_DIRECTIONS] =
-   {
-      //C  N   S   W   E   T   B   NW  NE  SW  SE  TN  TS  TW  TE  BN  BS  BW  BE  TNE TNW TSE TSW BNE BNW BSE BSW
+   const std::array< uint_t, NR_OF_DIRECTIONS > gaussianMultipliers {
       uint_t(8u),
       uint_t(4u), uint_t(4u), uint_t(4u), uint_t(4u) ,
       uint_t(4u), uint_t(4u),
@@ -257,21 +253,21 @@ namespace stencil {
 
 
    /// The mirrored directions (flip W-E)  \ingroup stencil
-   const Direction mirrorX[NR_OF_DIRECTIONS] = {
+   const std::array< Direction, NR_OF_DIRECTIONS > mirrorX {
       C, N, S, E, W, T, B,
       NE, NW, SE, SW, TN, TS, TE, TW, BN, BS, BE, BW,
       TNW, TNE, TSW, TSE, BNW, BNE, BSW, BSE
    };
 
    /// The mirrored directions (flip N-S) \ingroup stencil
-   const Direction mirrorY[NR_OF_DIRECTIONS] = {
+   const std::array< Direction, NR_OF_DIRECTIONS > mirrorY {
       C, S, N, W, E, T, B,
       SW, SE, NW, NE, TS, TN, TW, TE, BS, BN, BW, BE,
       TSE, TSW, TNE, TNW, BSE, BSW, BNE, BNW
    };
 
    /// The mirrored directions (flip T-B) \ingroup stencil
-   const Direction mirrorZ[NR_OF_DIRECTIONS] = {
+   const std::array< Direction, NR_OF_DIRECTIONS > mirrorZ {
       C, N, S, W, E, B, T,
       NW, NE, SW, SE, BN, BS, BW, BE, TN, TS, TW, TE,
       BNE, BNW, BSE, BSW, TNE, TNW, TSE, TSW
@@ -288,7 +284,7 @@ namespace stencil {
             cout << pdfField.get(x,y,z, D3Q19::idx[ map2Dto3D[0][*i] ] ) << endl;
        \endcode
    */
-   const Direction map2Dto3D[3][NR_OF_DIRECTIONS] =
+   const std::array< std::array< Direction, NR_OF_DIRECTIONS >, 3 > map2Dto3D {
    {
             { C, T, B, S, N, INVALID_DIR, INVALID_DIR, TS, TN, BS, BN,
               INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR,
@@ -301,7 +297,7 @@ namespace stencil {
             { C, N, S, W, E, INVALID_DIR, INVALID_DIR, NW, NE, SW, SE,
               INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR,
               INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR, INVALID_DIR }
-   };
+   } };
 
    /// Maps (direction,axis) pair to direction
    /// \param axis     0,1 or 2 standing for x,y,z
@@ -343,7 +339,7 @@ namespace stencil {
    /// \param d      direction pointing towards the computed neighbor
    inline Cell operator+( const Cell & cell, const Direction d )
    {
-      return Cell( cell.x() + cx[d], cell.y() + cy[d], cell.z() + cz[d] );
+      return { cell.x() + cx[d], cell.y() + cy[d], cell.z() + cz[d] };
    }
 
 
@@ -353,7 +349,7 @@ namespace stencil {
    /// \param d      direction pointing away from the computed neighbor
    inline Cell operator-( const Cell & cell, const Direction d )
    {
-      return Cell( cell.x() - cx[d], cell.y() - cy[d], cell.z() - cz[d] );
+      return { cell.x() - cx[d], cell.y() - cy[d], cell.z() - cz[d] };
    }
 
 
diff --git a/src/stencil/EdgeStencil.h b/src/stencil/EdgeStencil.h
index e045795309850e97671edbe79a5b0ae3ebc899b9..45920d12a1f95f40b554e17f0d16d755dd2759e9 100644
--- a/src/stencil/EdgeStencil.h
+++ b/src/stencil/EdgeStencil.h
@@ -69,14 +69,14 @@ namespace stencil {
          static const bool   containsCenter   = false;
          static const uint_t noCenterFirstIdx = 0;
 
-         static const Direction dir           [12];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][12/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, 12 > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, 12/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -111,7 +111,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction EdgeStencil<Dummy>::dir[12] = { NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE };
+      const std::array< Direction, 12 > EdgeStencil<Dummy>::dir{ NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE };
 
 
       /**
@@ -121,7 +121,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction EdgeStencil<Dummy>::dir_pos[POS_Q] = { NE,SE,TN,TE,BN,BE };
+      const std::array< Direction, EdgeStencil<Dummy>::POS_Q > EdgeStencil<Dummy>::dir_pos{ NE,SE,TN,TE,BN,BE };
 
 
       /**
@@ -134,7 +134,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t EdgeStencil<Dummy>::idx[NR_OF_DIRECTIONS] = { INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,0,1,2,3,4,5,6,7,8,9,10,11,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
+      const std::array< uint_t, NR_OF_DIRECTIONS > EdgeStencil<Dummy>::idx{ INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,0,1,2,3,4,5,6,7,8,9,10,11,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR,INVALID_DIR };
 
 
       /**
@@ -154,7 +154,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction EdgeStencil<Dummy>::d_per_d[NR_OF_DIRECTIONS][12/2] = { {},
+      const std::array< std::array< Direction, 12/2 >, NR_OF_DIRECTIONS > EdgeStencil<Dummy>::d_per_d{ { {},
 								{NW,NE,TN,BN},
 								{SW,SE,TS,BS},
 								{NW,SW,TW,BW},
@@ -180,7 +180,7 @@ namespace stencil {
 								{},
 								{},
 								{},
-								{} };
+								{} } };
 
 
       /**
@@ -188,7 +188,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t EdgeStencil<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { 0,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 };
+      const std::array< uint_t, NR_OF_DIRECTIONS > EdgeStencil<Dummy>::d_per_d_length{ 0,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0 };
 
 
       /**
@@ -201,7 +201,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction EdgeStencil<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { {NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE},
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > EdgeStencil<Dummy>::dir_neighbors{ { {NW,NE,SW,SE,TN,TS,TW,TE,BN,BS,BW,BE},
 								{W,E,T,B,TNE,TNW,BNE,BNW},
 								{W,E,T,B,TSE,TSW,BSE,BSW},
 								{N,S,T,B,TNW,TSW,BNW,BSW},
@@ -227,7 +227,7 @@ namespace stencil {
 								{N,E,B},
 								{N,W,B},
 								{S,E,B},
-								{S,W,B} };
+								{S,W,B} } };
 
 
       /**
@@ -235,7 +235,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t EdgeStencil<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { 12,8,8,8,8,8,8,5,5,5,5,5,5,5,5,5,5,5,5,3,3,3,3,3,3,3,3 };
+      const std::array<uint_t, NR_OF_DIRECTIONS> EdgeStencil<Dummy>::dir_neighbors_length{ 12,8,8,8,8,8,8,5,5,5,5,5,5,5,5,5,5,5,5,3,3,3,3,3,3,3,3 };
 
    } // namespace internal
 
diff --git a/src/stencil/Stencil.in.h b/src/stencil/Stencil.in.h
index 4443d823585c4b2413dff0d233a040f1b36aa1a7..13f04ea224e237b45680e416a4f49c349fc03cea 100644
--- a/src/stencil/Stencil.in.h
+++ b/src/stencil/Stencil.in.h
@@ -62,14 +62,14 @@ namespace stencil {
          static const bool   containsCenter   = $containsCenter;
          static const uint_t noCenterFirstIdx = $noCenterFirstIndex;
 
-         static const Direction dir           [$Q];
-         static const Direction dir_pos       [POS_Q];
-         static const uint_t    idx           [NR_OF_DIRECTIONS];
-         static const Direction d_per_d       [NR_OF_DIRECTIONS][$Q/2];
-         static const uint_t    d_per_d_length[NR_OF_DIRECTIONS];
+         static const std::array< Direction, $Q > dir;
+         static const std::array< Direction, POS_Q > dir_pos;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > idx;
+         static const std::array< std::array<Direction, $Q/2>, NR_OF_DIRECTIONS> d_per_d;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > d_per_d_length;
 
-         static const Direction dir_neighbors        [NR_OF_DIRECTIONS][NR_OF_DIRECTIONS];
-         static const uint_t    dir_neighbors_length [NR_OF_DIRECTIONS];
+         static const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > dir_neighbors;
+         static const std::array< uint_t, NR_OF_DIRECTIONS > dir_neighbors_length;
 
          static bool   containsDir(Direction d) { return idx[d] < NR_OF_DIRECTIONS; }
          static uint_t invDirIdx  (Direction d) { return idx[stencil::inverseDir[d]]; }
@@ -104,7 +104,7 @@ namespace stencil {
 
       /// Subset of directions. Defines the stencil
       template<typename Dummy>
-      const Direction $name<Dummy>::dir[$Q] = { $dirs };
+      const std::array< Direction, $Q > $name<Dummy>::dir{ $dirs };
 
 
       /**
@@ -114,7 +114,7 @@ namespace stencil {
        * the direction together with its inverse direction.
        */
       template<typename Dummy>
-      const Direction $name<Dummy>::dir_pos[POS_Q] = { $dir_pos };
+      const std::array< Direction, $name<Dummy>::POS_Q > $name<Dummy>::dir_pos{ $dir_pos };
 
 
       /**
@@ -127,7 +127,7 @@ namespace stencil {
        *  So a stencil class is needed to map back from direction to field index
        */
       template<typename Dummy>
-      const uint_t $name<Dummy>::idx[NR_OF_DIRECTIONS] = { $indexFromDir };
+      const std::array< uint_t, NR_OF_DIRECTIONS > $name<Dummy>::idx{ $indexFromDir };
 
 
       /**
@@ -147,7 +147,7 @@ namespace stencil {
        *
        */
       template<typename Dummy>
-      const Direction $name<Dummy>::d_per_d[NR_OF_DIRECTIONS][$Q/2] = { $d_per_d };
+      const std::array< std::array< Direction, $Q/2 >, NR_OF_DIRECTIONS > $name<Dummy>::d_per_d{ { $d_per_d } };
 
 
       /**
@@ -155,7 +155,7 @@ namespace stencil {
        * For usage see documentation of d_per_d
        */
       template<typename Dummy>
-      const uint_t $name<Dummy>::d_per_d_length [NR_OF_DIRECTIONS] = { $d_per_d_length };
+      const std::array< uint_t, NR_OF_DIRECTIONS > $name<Dummy>::d_per_d_length{ $d_per_d_length };
 
 
       /**
@@ -168,7 +168,7 @@ namespace stencil {
        * By definition, the neighbors of C are identical to the dir[] array without C itself.
        */
       template<typename Dummy>
-      const Direction $name<Dummy>::dir_neighbors[NR_OF_DIRECTIONS][NR_OF_DIRECTIONS] = { $dir_neighbors };
+      const std::array< std::array< Direction, NR_OF_DIRECTIONS >, NR_OF_DIRECTIONS > $name<Dummy>::dir_neighbors{ { $dir_neighbors } };
 
 
       /**
@@ -176,7 +176,7 @@ namespace stencil {
        * For usage see documentation of dir_neighbors
        */
       template<typename Dummy>
-      const uint_t $name<Dummy>::dir_neighbors_length[NR_OF_DIRECTIONS] = { $dir_neighbors_length };
+      const std::array<uint_t, NR_OF_DIRECTIONS> $name<Dummy>::dir_neighbors_length{ $dir_neighbors_length };
 
    } // namespace internal
 
diff --git a/src/stencil/generate.py b/src/stencil/generate.py
index 263d7077d2fb56022a20811ae277a025fcbe2abd..c92161da4f393bc206c7c975763ce701a63d45b5 100755
--- a/src/stencil/generate.py
+++ b/src/stencil/generate.py
@@ -221,7 +221,7 @@ tmpl = tmplFile.read().replace("{", "{{")
 tmpl = tmpl.replace("}", "}}")
 
 # Then we replace all "$var" constructs by "{var}"
-tmpl = re.sub("\$[A-Za-z_]*", (lambda x: "{" + x.group(0)[1:] + "}"), tmpl)  # noqa: W605
+tmpl = re.sub("\\$[A-Za-z_]*", (lambda x: "{" + x.group(0)[1:] + "}"), tmpl)  # noqa: W605
 
 """Reads stencil dict and generates header files"""
 for stencil in stencils:
diff --git a/src/timeloop/PerformanceMeter.cpp b/src/timeloop/PerformanceMeter.cpp
index 98a6fc350569c876ce9440ef205d90e35be3819c..809e4b7ad175d9ec0da00b288ee97fef0e81ed5a 100644
--- a/src/timeloop/PerformanceMeter.cpp
+++ b/src/timeloop/PerformanceMeter.cpp
@@ -39,7 +39,7 @@ namespace timeloop {
     * \param blockStorage block storage is needed to retrieve the FlagField for cell counting
     *******************************************************************************************************************/
    PerformanceMeter::PerformanceMeter( StructuredBlockStorage & blockStorage)
-      : blockStorage_ ( blockStorage ), firstTimingStartStopCall_( true )
+      : blockStorage_ ( blockStorage )
    {
    }
 
@@ -53,7 +53,7 @@ namespace timeloop {
     *******************************************************************************************************************/
    std::function<void () > PerformanceMeter::getBeforeFunction()
    {
-      return std::bind ( &PerformanceMeter::timingStart, this );
+      return [this] { timingStart(); };
    }
 
 
@@ -66,7 +66,7 @@ namespace timeloop {
     *******************************************************************************************************************/
    std::function<void () > PerformanceMeter::getAfterFunction()
    {
-      return std::bind ( &PerformanceMeter::timingEnd, this );
+      return [this] { timingEnd(); };
    }
 
 
@@ -266,19 +266,19 @@ namespace timeloop {
 
       uint_t ts = timer_.getCounter();
 
-      for( auto measureIt = measurements_.begin(); measureIt != measurements_.end(); ++measureIt )
+      for(auto & measurement : measurements_)
       {
-         if( measureIt->countingFreq > 0 &&  ts % measureIt->countingFreq == 0 )
+         if( measurement.countingFreq > 0 &&  ts % measurement.countingFreq == 0 )
          {
             uint_t cells = 0;
             for( auto block = blockStorage_.begin(); block != blockStorage_.end(); ++block )
-               cells += measureIt->countFunction( *block );
+               cells += measurement.countFunction( *block );
 
             real_t cellsLastTimeStep = real_c ( cells );
 
-            measureIt->counts += 1;
-            real_t rCounts = real_c( measureIt->counts );
-            measureIt->avgCellsPerTimeStep = (rCounts - real_t(1.0) ) / rCounts * measureIt->avgCellsPerTimeStep +
+            measurement.counts += 1;
+            real_t rCounts = real_c( measurement.counts );
+            measurement.avgCellsPerTimeStep = (rCounts - real_t(1.0) ) / rCounts * measurement.avgCellsPerTimeStep +
                                                         real_t(1.0)   / rCounts * cellsLastTimeStep;
          }
       }
@@ -298,8 +298,8 @@ namespace timeloop {
          return;
 
       reduced.clear();
-      for( auto cellType = measurements_.begin(); cellType != measurements_.end(); ++cellType )
-         reduced.push_back ( cellType->avgCellsPerTimeStep );
+      for(auto & measurement : measurements_)
+         reduced.push_back ( measurement.avgCellsPerTimeStep );
 
       WALBERLA_NON_MPI_SECTION() {
          return;
diff --git a/src/timeloop/PerformanceMeter.h b/src/timeloop/PerformanceMeter.h
index e5ccee05930623e27b390692df8f8606da2b4c35..fc6fad41a38e9360c34b7b06cc0130d8191d9498 100644
--- a/src/timeloop/PerformanceMeter.h
+++ b/src/timeloop/PerformanceMeter.h
@@ -124,15 +124,15 @@ namespace timeloop {
       struct Measurement
       {
          Measurement ( CountFunction cf, const std::string & n, real_t sc, uint_t countFreq )
-            : countFunction ( cf), name(n), scaling(sc), countingFreq(countFreq), counts(0), avgCellsPerTimeStep(0)
+            : countFunction ( cf), name(n), scaling(sc), countingFreq(countFreq)
          {}
 
          CountFunction countFunction;
          std::string   name;                 //!< name of the measured performance number
          real_t        scaling;              //!< scaling factor, usually power of ten, for (M)FLUPS
          uint_t        countingFreq;         //!< every n'th timestep cells are counted, if 0 cells are counted only once
-         uint_t        counts;               //!< how often was the number of cells counted until now
-         real_t        avgCellsPerTimeStep;  //!< the average number of cells per timestep
+         uint_t        counts{0};               //!< how often was the number of cells counted until now
+         real_t        avgCellsPerTimeStep{0};  //!< the average number of cells per timestep
       };
 
       void   timingStartStop();
@@ -147,7 +147,7 @@ namespace timeloop {
       std::vector<Measurement> measurements_;
 
       /// Used for operator() to indicate if called the first time
-      bool firstTimingStartStopCall_;
+      bool firstTimingStartStopCall_{true};
    };
 
 
diff --git a/src/timeloop/SweepTimeloop.h b/src/timeloop/SweepTimeloop.h
index 19e9344a68e30b1efb2c090f4d8a588509cd9b8d..cf5a33d22dcbbcf3648b2715ee44fa3e343b6129 100644
--- a/src/timeloop/SweepTimeloop.h
+++ b/src/timeloop/SweepTimeloop.h
@@ -132,8 +132,8 @@ namespace timeloop {
 
       ~SweepTimeloop() override
       {
-         for ( auto i = sweeps_.begin(); i != sweeps_.end(); ++i )
-            delete i->second;
+         for (auto & sweep : sweeps_)
+            delete sweep.second;
       }
 
       //@}
@@ -163,8 +163,8 @@ namespace timeloop {
 
       void removeForDeletionMarkedSweeps()
       {
-         for( auto it = sweepsToDelete_.begin(); it != sweepsToDelete_.end(); ++it )
-            sweeps_.erase( *it );
+         for(unsigned long & it : sweepsToDelete_)
+            sweeps_.erase( it );
       }
 
       void doTimeStep(const Set<SUID> &selectors) override;
diff --git a/src/timeloop/SweepTimeloop.impl.h b/src/timeloop/SweepTimeloop.impl.h
index 481ddbacad80e5d167bcd6d2925c51d6d48db400..362c0f4327e28ed74b7eecd0ff7da07819c01d31 100644
--- a/src/timeloop/SweepTimeloop.impl.h
+++ b/src/timeloop/SweepTimeloop.impl.h
@@ -42,8 +42,8 @@ void SweepTimeloop<TP>::doTimeStep(const Set<SUID> &selectors)
       SweepAdder & s = * ( sweepIt->second );
 
       //select and execute before functions
-      for( size_t j=0; j < s.beforeFuncs.size(); ++j )
-         this->executeSelectable(s.beforeFuncs[j].selectableFunc_, selectors, "Pre-Sweep Function");
+      for(auto & beforeFunc : s.beforeFuncs)
+         this->executeSelectable(beforeFunc.selectableFunc_, selectors, "Pre-Sweep Function");
 
       // Loop over all blocks
       for( BlockStorage::iterator bi = blockStorage_.begin(); bi != blockStorage_.end(); ++bi )
@@ -80,8 +80,8 @@ void SweepTimeloop<TP>::doTimeStep(const Set<SUID> &selectors)
       }
 
       // select and execute after functions
-      for( size_t j=0; j < s.afterFuncs.size(); ++j )
-         this->executeSelectable(s.afterFuncs[j].selectableFunc_, selectors, "Post-Sweep Function");
+      for(auto & afterFunc : s.afterFuncs)
+         this->executeSelectable(afterFunc.selectableFunc_, selectors, "Post-Sweep Function");
    }
 }
 
@@ -96,9 +96,9 @@ void SweepTimeloop<TP>::doTimeStep(const Set<SUID> &selectors, timing::TimingPoo
    if ( firstRun_ || timing.empty() )
    {
 
-      for( auto sweepIt = sweeps_.begin(); sweepIt != sweeps_.end(); ++sweepIt )
+      for(auto & sweep : sweeps_)
       {
-         SweepAdder & s = * ( sweepIt->second );
+         SweepAdder & s = * ( sweep.second );
          // loop over all possibilities in selectable object
          for( auto it = s.sweep.begin(); it != s.sweep.end(); ++it )
             timing.registerTimer( it.identifier() );
@@ -113,8 +113,8 @@ void SweepTimeloop<TP>::doTimeStep(const Set<SUID> &selectors, timing::TimingPoo
       SweepAdder & s = * ( sweepIt->second );
 
       //select and execute before functions
-      for( size_t j=0; j < s.beforeFuncs.size(); ++j )
-         this->executeSelectable( s.beforeFuncs[j].selectableFunc_, selectors, "Pre-Sweep Function", timing );
+      for(auto & beforeFunc : s.beforeFuncs)
+         this->executeSelectable( beforeFunc.selectableFunc_, selectors, "Pre-Sweep Function", timing );
 
       for( BlockStorage::iterator bi = blockStorage_.begin(); bi != blockStorage_.end(); ++bi )
       {
@@ -149,8 +149,8 @@ void SweepTimeloop<TP>::doTimeStep(const Set<SUID> &selectors, timing::TimingPoo
       }
 
       // select and execute after functions
-      for( size_t j=0; j < s.afterFuncs.size(); ++j )
-         this->executeSelectable(s.afterFuncs[j].selectableFunc_,selectors,"Post-Sweep Function", timing );
+      for(auto & afterFunc : s.afterFuncs)
+         this->executeSelectable(afterFunc.selectableFunc_,selectors,"Post-Sweep Function", timing );
    }
 }
 
diff --git a/src/timeloop/Timeloop.h b/src/timeloop/Timeloop.h
index faed83b06baf774c34247cd4ee6483510b3d4a78..f6d0adbd097d2ad95e10b91ebd537573fd1c83cd 100644
--- a/src/timeloop/Timeloop.h
+++ b/src/timeloop/Timeloop.h
@@ -112,9 +112,8 @@ public:
    /*! \name Construction & Destruction */
    //@{
    Timeloop( uint_t nrOfTimeSteps )
-      : curTimeStep_(0), nrOfTimeSteps_(nrOfTimeSteps), stop_( false )
-   {
-   }
+      : nrOfTimeSteps_(nrOfTimeSteps)
+   {}
 
    ~Timeloop() override = default;
    //@}
@@ -163,7 +162,7 @@ public:
     FctHandle addFuncAfterTimeStep (const VoidFctNoArguments & f,
                                     const std::string & identifier     = std::string(),
                                     const Set<SUID> & require          = Set<SUID>::emptySet(),
-                                    const Set<SUID> & exludingSelector = Set<SUID>::emptySet() );
+                                    const Set<SUID> & excludingSelector = Set<SUID>::emptySet() );
 
     void      addFuncAfterTimeStep (const FctHandle & fctToBindTo,
                                     const VoidFctNoArguments & f,
@@ -200,14 +199,14 @@ protected:
                           timing::TimingPool<TP> & tp);
 
 
-   uint_t curTimeStep_;   ///< current time step
+   uint_t curTimeStep_{0};   ///< current time step
    uint_t nrOfTimeSteps_; ///< total number of time steps
 
    using SelectableFunc = selectable::SetSelectableObject<VoidFctNoArguments, SUID>;
    std::vector<SelectableFunc> beforeFunctions_;
    std::vector<SelectableFunc> afterFunctions_;
 
-   bool stop_;
+   bool stop_{ false };
 };
 
 
diff --git a/src/timeloop/Timeloop.impl.h b/src/timeloop/Timeloop.impl.h
index 832f1c7adcdfdb8d9483508898e2b7e6b22a38fb..03d15779648def1282f994896f4c4732024287d7 100644
--- a/src/timeloop/Timeloop.impl.h
+++ b/src/timeloop/Timeloop.impl.h
@@ -99,13 +99,13 @@ void Timeloop<TP>::singleStep( const bool logTimeStep )
 
    WALBERLA_LOG_PROGRESS( "Running time step " << curTimeStep_ )
 
-   for(size_t i=0; i<beforeFunctions_.size(); ++i )
-      executeSelectable( beforeFunctions_[i], uid::globalState(), "Pre-Timestep Function" );
+   for(auto & beforeFunction : beforeFunctions_)
+      executeSelectable( beforeFunction, uid::globalState(), "Pre-Timestep Function" );
 
    doTimeStep(uid::globalState());
 
-   for(size_t i=0; i<afterFunctions_.size(); ++i )
-      executeSelectable( afterFunctions_[i], uid::globalState(),"Post-Timestep Function" );
+   for(auto & afterFunction : afterFunctions_)
+      executeSelectable( afterFunction, uid::globalState(),"Post-Timestep Function" );
 
    ++curTimeStep_;
 }
@@ -117,13 +117,13 @@ void Timeloop<TP>::singleStep( timing::TimingPool<TP> & tp, const bool logTimeSt
 
    WALBERLA_LOG_PROGRESS( "Running time step " << curTimeStep_ )
 
-   for(size_t i=0; i<beforeFunctions_.size(); ++i )
-      executeSelectable( beforeFunctions_[i], uid::globalState(), "Pre-Timestep Function", tp );
+   for(auto & beforeFunction : beforeFunctions_)
+      executeSelectable( beforeFunction, uid::globalState(), "Pre-Timestep Function", tp );
 
    doTimeStep(uid::globalState(), tp);
 
-   for(size_t i=0; i<afterFunctions_.size(); ++i )
-      executeSelectable( afterFunctions_[i], uid::globalState(),"Post-Timestep Function", tp );
+   for(auto & afterFunction : afterFunctions_)
+      executeSelectable( afterFunction, uid::globalState(),"Post-Timestep Function", tp );
 
    ++curTimeStep_;
 }
diff --git a/src/vtk/Base64Writer.cpp b/src/vtk/Base64Writer.cpp
index 18f969c547077492963d2eacce815687cf78f522..1405bad494e32bcf4986ae2c505ed6ad374a65d2 100644
--- a/src/vtk/Base64Writer.cpp
+++ b/src/vtk/Base64Writer.cpp
@@ -38,8 +38,8 @@ namespace vtk {
 //**********************************************************************************************************************
 void Base64Writer::toStream( std::ostream& os )
 {
-   unsigned char input[3];
-   unsigned char output[4];
+   std::array< unsigned char, 3 > input;
+   std::array< unsigned char, 4 > output;
 
    const uint32_t bytes = uint32_c( buffer_.size() );
 
diff --git a/src/vtk/Base64Writer.h b/src/vtk/Base64Writer.h
index c9af5528e15ecef564e64419de622745e57228c6..1445da4a6c6068346e8956c6d42223e2ae662021 100644
--- a/src/vtk/Base64Writer.h
+++ b/src/vtk/Base64Writer.h
@@ -23,6 +23,7 @@
 
 #include <ostream>
 #include <vector>
+#include <array>
 
 
 namespace walberla {
@@ -74,29 +75,28 @@ public:
    void toStream( std::ostream& os );
 
 private:
-
-   void encodeblock( unsigned char const in[3], unsigned char out[4], int len )
+   void encodeblock( const std::array< unsigned char, 3 > in,  std::array< unsigned char, 4 > out, int len )
    {
-      static const unsigned char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+      std::array< unsigned char, 65 > cb64 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" };
 
       switch( len )
       {
       case 1:
          out[0] = cb64[ in[0] >> 2 ];
-         out[1] = cb64[ ((in[0] & 0x03) << 4) ];
+         out[1] = cb64[ ((in[0] & 0x03u) << 4) ];
          out[2] = '=';
          out[3] = '=';
          break;
       case 2:
          out[0] = cb64[ in[0] >> 2 ];
-         out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
-         out[2] = cb64[ ((in[1] & 0x0f) << 2) ];
+         out[1] = cb64[ ((in[0] & 0x03u) << 4) | ((in[1] & 0xf0u) >> 4) ];
+         out[2] = cb64[ ((in[1] & 0x0fu) << 2) ];
          out[3] = '=';
          break;
       default:
          out[0] = cb64[ in[0] >> 2 ];
-         out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
-         out[2] = cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ];
+         out[1] = cb64[ ((in[0] & 0x03u) << 4) | ((in[1] & 0xf0u) >> 4) ];
+         out[2] = cb64[ ((in[1] & 0x0fu) << 2) | ((in[2] & 0xc0u) >> 6) ];
          out[3] = cb64[ in[2] & 0x3f ];
       }
    }
diff --git a/src/vtk/Initialization.cpp b/src/vtk/Initialization.cpp
index 4d88f1b21a8f989432a41d352661c7ae0c6936f7..42d2b7ed4d91fc2308b271bca75deb281767c177 100644
--- a/src/vtk/Initialization.cpp
+++ b/src/vtk/Initialization.cpp
@@ -72,8 +72,8 @@ static void addStates( Set<SUID>& set, const std::string& string )
    states = string_split( string, ", \t" );
    states.erase( std::remove_if( states.begin(), states.end(), [](auto &s){ return s.empty(); } ), states.end() );
 
-   for( auto it = states.begin(); it != states.end(); ++it )
-      set += SUID( *it );
+   for(auto & state : states)
+      set += SUID( state );
 }
 
 
@@ -109,12 +109,12 @@ void initializeVTKOutput( std::map< std::string, SelectableOutputFunction > & ou
    std::map< std::string, VTKOutput::CellFilter,                      CaseInsensitiveCompare > globalFilters;
    std::map< std::string, VTKOutput::BeforeFunction,                  CaseInsensitiveCompare > beforeFunctions;
 
-   for( auto writer = _writers.begin(); writer != _writers.end(); ++writer )
+   for(const auto & _writer : _writers)
    {
-      if( writers.find( (*writer)->identifier() ) != writers.end() )
-         WALBERLA_ABORT( "There are at least two block data writers with identifier \"" << (*writer)->identifier() <<
+      if( writers.find( _writer->identifier() ) != writers.end() )
+         WALBERLA_ABORT( "There are at least two block data writers with identifier \"" << _writer->identifier() <<
                          "\" (test is case insensitive!).\nEvery writer must have a unique identifier!" );
-      writers[ (*writer)->identifier() ] = *writer;
+      writers[ _writer->identifier() ] = _writer;
    }
 
    for( auto filter = _filters.begin(); filter != _filters.end(); ++filter )
@@ -141,29 +141,29 @@ void initializeVTKOutput( std::map< std::string, SelectableOutputFunction > & ou
    Config::Blocks blocks;
    vtkBlock.getBlocks( blocks );
 
-   for( auto block = blocks.begin(); block != blocks.end(); ++block )
+   for(auto & block : blocks)
    {
       Config::Blocks subBlocks;
-      block->getBlocks( subBlocks );
+      block.getBlocks( subBlocks );
 
-      const std::string identifier( block->getKey() );
+      const std::string identifier( block.getKey() );
 
-      const int    simultaneousIOOperations = block->getParameter< int >( "simultaneousIOOperations", 0 );
-      const uint_t writeFrequency           = block->getParameter< uint_t >( "writeFrequency", uint_c(1) );
-      const uint_t initialExecutionCount    = block->getParameter< uint_t >( "initialExecutionCount", uint_c(0) );
-      const bool   forcePVTU                = block->getParameter< bool >( "forcePVTU", false );
-      const uint_t ghostLayers              = block->getParameter< uint_t >( "ghostLayers", uint_c(0) );
+      const int    simultaneousIOOperations = block.getParameter< int >( "simultaneousIOOperations", 0 );
+      const uint_t writeFrequency           = block.getParameter< uint_t >( "writeFrequency", uint_c(1) );
+      const uint_t initialExecutionCount    = block.getParameter< uint_t >( "initialExecutionCount", uint_c(0) );
+      const bool   forcePVTU                = block.getParameter< bool >( "forcePVTU", false );
+      const uint_t ghostLayers              = block.getParameter< uint_t >( "ghostLayers", uint_c(0) );
 
-      std::string baseFolder( block->getParameter< std::string >( "baseFolder", std::string( "vtk_out" ) ) );
-      std::string executionFolder( block->getParameter< std::string >( "executionFolder", std::string( "simulation_step" ) ) );
+      std::string baseFolder( block.getParameter< std::string >( "baseFolder", std::string( "vtk_out" ) ) );
+      std::string executionFolder( block.getParameter< std::string >( "executionFolder", std::string( "simulation_step" ) ) );
 
-      const bool outputDomainDecomposition = block->getParameter< bool >( "outputDomainDecomposition", false );
-      const bool continuousNumbering       = block->getParameter< bool >( "continuousNumbering", false );
-      const bool binary                    = block->getParameter< bool >( "binary", true );
-      const bool littleEndian              = block->getParameter< bool >( "littleEndian", true );
-      const bool useMPIIO                  = block->getParameter< bool >( "useMPIIO", true );
+      const bool outputDomainDecomposition = block.getParameter< bool >( "outputDomainDecomposition", false );
+      const bool continuousNumbering       = block.getParameter< bool >( "continuousNumbering", false );
+      const bool binary                    = block.getParameter< bool >( "binary", true );
+      const bool littleEndian              = block.getParameter< bool >( "littleEndian", true );
+      const bool useMPIIO                  = block.getParameter< bool >( "useMPIIO", true );
 
-      Config::BlockHandle writersBlock = block->getBlock( "writers" );
+      Config::BlockHandle writersBlock = block.getBlock( "writers" );
 
       if( !writersBlock && !outputDomainDecomposition )
          WALBERLA_ABORT( "You declared a VTK output instance [\"" << identifier << "\"] without a \"writers\" block. "
@@ -201,23 +201,23 @@ void initializeVTKOutput( std::map< std::string, SelectableOutputFunction > & ou
          vtkOutput = createVTKOutput_BlockData( *storage, identifier, writeFrequency, ghostLayers, forcePVTU,
                                                 baseFolder, executionFolder, continuousNumbering, binary, littleEndian, useMPIIO, initialExecutionCount );
 
-      const uint_t initialWriteCallsToSkip = block->getParameter< uint_t >( "initialWriteCallsToSkip", uint_t(0) );
+      const uint_t initialWriteCallsToSkip = block.getParameter< uint_t >( "initialWriteCallsToSkip", uint_t(0) );
       if( initialWriteCallsToSkip > uint_t(0) )
          vtkOutput->setInitialWriteCallsToSkip( initialWriteCallsToSkip );
 
-      const real_t samplingResolution = block->getParameter< real_t >( "samplingResolution", real_c(-1) );
+      const real_t samplingResolution = block.getParameter< real_t >( "samplingResolution", real_c(-1) );
       vtkOutput->setSamplingResolution( samplingResolution );
 
-      if( block->isDefined( "samplingDx" ) )
+      if( block.isDefined( "samplingDx" ) )
       {
-         const real_t samplingDx = block->getParameter< real_t >( "samplingDx", real_c(-1) );
-         const real_t samplingDy = block->getParameter< real_t >( "samplingDy", real_c(-1) );
-         const real_t samplingDz = block->getParameter< real_t >( "samplingDz", real_c(-1) );
+         const real_t samplingDx = block.getParameter< real_t >( "samplingDx", real_c(-1) );
+         const real_t samplingDy = block.getParameter< real_t >( "samplingDy", real_c(-1) );
+         const real_t samplingDz = block.getParameter< real_t >( "samplingDz", real_c(-1) );
 
          vtkOutput->setSamplingResolution( samplingDx, samplingDy, samplingDz );
       }
 
-      Config::BlockHandle beforeFunctionsBlock = block->getBlock( "before_functions" );
+      Config::BlockHandle beforeFunctionsBlock = block.getBlock( "before_functions" );
       if( beforeFunctionsBlock )
       {
          for( auto beforeFunctionId = beforeFunctionsBlock.begin(); beforeFunctionId != beforeFunctionsBlock.end(); ++beforeFunctionId )
@@ -234,13 +234,13 @@ void initializeVTKOutput( std::map< std::string, SelectableOutputFunction > & ou
       Config::Blocks aabbBlocks;
       Config::Blocks cellBBBlocks;
 
-      for( auto subBlock = subBlocks.begin(); subBlock != subBlocks.end(); ++subBlock )
+      for(auto & subBlock : subBlocks)
       {
-         if( string_icompare( std::string( subBlock->getKey(), 0, 11 ), std::string("AABB_filter") ) == 0 )
-            aabbBlocks.push_back( *subBlock );
+         if( string_icompare( std::string( subBlock.getKey(), 0, 11 ), std::string("AABB_filter") ) == 0 )
+            aabbBlocks.push_back( subBlock );
 
-         if( string_icompare( std::string( subBlock->getKey(), 0, 13 ), std::string("CellBB_filter") ) == 0 )
-            cellBBBlocks.push_back( *subBlock );
+         if( string_icompare( std::string( subBlock.getKey(), 0, 13 ), std::string("CellBB_filter") ) == 0 )
+            cellBBBlocks.push_back( subBlock );
       }
 
       for( auto aabb = aabbBlocks.begin(); aabb != aabbBlocks.end(); ++aabb )
@@ -293,10 +293,10 @@ void initializeVTKOutput( std::map< std::string, SelectableOutputFunction > & ou
          filters[ bb->getKey() ] = CellBBCellFilter( CellInterval( xmin, ymin, zmin, xmax, ymax, zmax ), level );
       }
 
-      for( auto selectedWriter = selectedWriters.begin(); selectedWriter != selectedWriters.end(); ++selectedWriter )
-         vtkOutput->addCellDataWriter( *selectedWriter );
+      for(auto & selectedWriter : selectedWriters)
+         vtkOutput->addCellDataWriter( selectedWriter );
 
-      Config::BlockHandle inclusionFiltersBlock = block->getBlock( "inclusion_filters" );
+      Config::BlockHandle inclusionFiltersBlock = block.getBlock( "inclusion_filters" );
       if( inclusionFiltersBlock )
       {
          for( auto inclusionFilterId = inclusionFiltersBlock.begin(); inclusionFilterId != inclusionFiltersBlock.end(); ++inclusionFilterId )
@@ -305,12 +305,12 @@ void initializeVTKOutput( std::map< std::string, SelectableOutputFunction > & ou
             {
                std::vector< std::string > filterList = splitList( inclusionFilterId->second );
                ChainedFilter combine;
-               for( auto filter = filterList.begin(); filter != filterList.end(); ++filter )
+               for(auto & filter : filterList)
                {
-                  if( filters.find( *filter ) != filters.end() )
-                     combine.addFilter( filters[ *filter ] );
+                  if( filters.find( filter ) != filters.end() )
+                     combine.addFilter( filters[ filter ] );
                   else
-                     WALBERLA_ABORT( "You have requested an inclusion cell filter \"" << *filter << "\". This filter is not available!" );
+                     WALBERLA_ABORT( "You have requested an inclusion cell filter \"" << filter << "\". This filter is not available!" );
                }
                vtkOutput->addCellInclusionFilter( combine );
             }
@@ -324,7 +324,7 @@ void initializeVTKOutput( std::map< std::string, SelectableOutputFunction > & ou
          }
       }
 
-      Config::BlockHandle exclusionFiltersBlock = block->getBlock( "exclusion_filters" );
+      Config::BlockHandle exclusionFiltersBlock = block.getBlock( "exclusion_filters" );
       if( exclusionFiltersBlock )
       {
          for( auto exclusionFilterId = exclusionFiltersBlock.begin(); exclusionFilterId != exclusionFiltersBlock.end(); ++exclusionFilterId )
@@ -333,12 +333,12 @@ void initializeVTKOutput( std::map< std::string, SelectableOutputFunction > & ou
             {
                std::vector< std::string > filterList = splitList( exclusionFilterId->second );
                ChainedFilter combine;
-               for( auto filter = filterList.begin(); filter != filterList.end(); ++filter )
+               for(auto & filter : filterList)
                {
-                  if( filters.find( *filter ) != filters.end() )
-                     combine.addFilter( filters[ *filter ] );
+                  if( filters.find( filter ) != filters.end() )
+                     combine.addFilter( filters[ filter ] );
                   else
-                     WALBERLA_ABORT( "You have requested an exclusion cell filter \"" << *filter << "\". This filter is not available!" );
+                     WALBERLA_ABORT( "You have requested an exclusion cell filter \"" << filter << "\". This filter is not available!" );
                }
                vtkOutput->addCellExclusionFilter( combine );
             }
@@ -353,30 +353,30 @@ void initializeVTKOutput( std::map< std::string, SelectableOutputFunction > & ou
       }
 
       Set<SUID> requiredGlobalStates;
-      if( block->isDefined( "requiredGlobalStates" ) )
+      if( block.isDefined( "requiredGlobalStates" ) )
       {
-         std::string states = block->getParameter< std::string >( "requiredGlobalStates" );
+         std::string states = block.getParameter< std::string >( "requiredGlobalStates" );
          addStates( requiredGlobalStates, states );
       }
 
       Set<SUID> incompatibleGlobalStates;
-      if( block->isDefined( "incompatibleGlobalStates" ) )
+      if( block.isDefined( "incompatibleGlobalStates" ) )
       {
-         std::string states = block->getParameter< std::string >( "incompatibleGlobalStates" );
+         std::string states = block.getParameter< std::string >( "incompatibleGlobalStates" );
          addStates( incompatibleGlobalStates, states );
       }
 
       Set<SUID> requiredBlockStates;
-      if( block->isDefined( "requiredBlockStates" ) )
+      if( block.isDefined( "requiredBlockStates" ) )
       {
-         std::string states = block->getParameter< std::string >( "requiredBlockStates" );
+         std::string states = block.getParameter< std::string >( "requiredBlockStates" );
          addStates( requiredBlockStates, states );
       }
 
       Set<SUID> incompatibleBlockStates;
-      if( block->isDefined( "incompatibleBlockStates" ) )
+      if( block.isDefined( "incompatibleBlockStates" ) )
       {
-         std::string states = block->getParameter< std::string >( "incompatibleBlockStates" );
+         std::string states = block.getParameter< std::string >( "incompatibleBlockStates" );
          addStates( incompatibleBlockStates, states );
       }
 
diff --git a/src/vtk/VTKOutput.cpp b/src/vtk/VTKOutput.cpp
index 1039abe54e946409f8d692b4933e36fda6237f8f..e8cdf7372facdeb660ad7b09eb1c730353519645 100644
--- a/src/vtk/VTKOutput.cpp
+++ b/src/vtk/VTKOutput.cpp
@@ -196,8 +196,8 @@ VTKOutput::~VTKOutput()
 void VTKOutput::forceWrite( uint_t number, const bool immediatelyWriteCollectors, const int simultaneousIOOperations,
                             const Set<SUID>& requiredStates, const Set<SUID>& incompatibleStates )
 {
-   for( auto func = beforeFunctions_.begin(); func != beforeFunctions_.end(); ++func )
-      ( *func )( );
+   for(auto & beforeFunction : beforeFunctions_)
+      beforeFunction( );
 
    std::ostringstream path;
    path << baseFolder_ << "/" << identifier_ << "/" << executionFolder_ << "_" << number;
@@ -352,9 +352,9 @@ void VTKOutput::writeDomainDecompositionPieces( std::ostream& ofs, const Set<SUI
        << "    <DataArray type=\"" << vtk::typeToString< float >() << "\" NumberOfComponents=\"3\" format=\"" << format_ << "\">\n";
 
    std::vector< float > vertex;
-   for( auto block = blocks.begin(); block != blocks.end(); ++block )
+   for(auto & block : blocks)
    {
-      const AABB& aabb = (*block)->getAABB();
+      const AABB& aabb = block->getAABB();
       vertex.push_back( numeric_cast< float >( aabb.xMin() ) ); vertex.push_back( numeric_cast< float >( aabb.yMin() ) );
       vertex.push_back( numeric_cast< float >( aabb.zMin() ) );
       vertex.push_back( numeric_cast< float >( aabb.xMax() ) ); vertex.push_back( numeric_cast< float >( aabb.yMin() ) );
@@ -376,8 +376,8 @@ void VTKOutput::writeDomainDecompositionPieces( std::ostream& ofs, const Set<SUI
    if( binary_ )
    {
       Base64Writer base64;
-      for( auto v = vertex.begin(); v != vertex.end(); ++v )
-         base64 << *v;
+      for(float & v : vertex)
+         base64 << v;
       ofs << "     "; base64.toStream( ofs );
    }
    else for( uint_t i = 0; i != vertex.size(); i += 3 )
@@ -435,14 +435,14 @@ void VTKOutput::writeDomainDecompositionPieces( std::ostream& ofs, const Set<SUI
    if( binary_ )
    {
       Base64Writer base64;
-      for( auto block = blocks.begin(); block != blocks.end(); ++block )
-         base64 << uint8_c( unstructuredBlockStorage_->getLevel( **block ) );
+      for(auto & block : blocks)
+         base64 << uint8_c( unstructuredBlockStorage_->getLevel( *block ) );
       base64.toStream( ofs );
    }
    else
    {
-      for( auto block = blocks.begin(); block != blocks.end(); ++block )
-         ofs << unstructuredBlockStorage_->getLevel( **block ) << " ";
+      for(auto & block : blocks)
+         ofs << unstructuredBlockStorage_->getLevel( *block ) << " ";
       ofs << "\n";
    }
 
@@ -977,9 +977,9 @@ void VTKOutput::computeVTUCells( const IBlock& block, CellVector & cellsOut ) co
       cellInclusionFunctions_[ 0 ]( includedCells, block, *blockStorage_, ghostLayers_ );
    }
    else {
-      for( auto func = cellInclusionFunctions_.begin(); func != cellInclusionFunctions_.end(); ++func ) {
+      for(const auto & cellInclusionFunction : cellInclusionFunctions_) {
          CellSet cellSet;
-         ( *func )( cellSet, block, *blockStorage_, ghostLayers_ );
+         cellInclusionFunction( cellSet, block, *blockStorage_, ghostLayers_ );
          includedCells += cellSet;
       }
    }
@@ -990,9 +990,9 @@ void VTKOutput::computeVTUCells( const IBlock& block, CellVector & cellsOut ) co
       cellExclusionFunctions_[ 0 ]( excludedCells, block, *blockStorage_, ghostLayers_ );
    }
    else {
-      for( auto func = cellExclusionFunctions_.begin(); func != cellExclusionFunctions_.end(); ++func ) {
+      for(const auto & cellExclusionFunction : cellExclusionFunctions_) {
          CellSet cellSet;
-         ( *func )( cellSet, block, *blockStorage_, ghostLayers_ );
+         cellExclusionFunction( cellSet, block, *blockStorage_, ghostLayers_ );
          excludedCells += cellSet;
       }
    }
@@ -1035,10 +1035,10 @@ void VTKOutput::writeBlocks( const std::string& path, const Set<SUID>& requiredS
          if( selectable::isSetSelected( uid::globalState() + block->getState(), requiredStates, incompatibleStates ) )
             blocks.push_back( block.get() );
       }
-      for( auto it = blocks.begin(); it != blocks.end(); ++it )
+      for( auto & it : blocks )
       {
-         WALBERLA_ASSERT_NOT_NULLPTR( *it );
-         const IBlock& block = **it;
+         WALBERLA_ASSERT_NOT_NULLPTR( it );
+         const IBlock& block = *it;
          const uint_t level = blockStorage_->getLevel(block);
 
          std::ostringstream file;
@@ -1096,10 +1096,10 @@ void VTKOutput::writeBlockPieces( std::ostream & oss, const Set<SUID>& requiredS
       configured_ = true;
    }
 
-   for( auto it = blocks.begin(); it != blocks.end(); ++it )
+   for( auto & it : blocks )
    {
-      WALBERLA_ASSERT_NOT_NULLPTR( *it );
-      const IBlock& block = **it;
+      WALBERLA_ASSERT_NOT_NULLPTR( it );
+      const IBlock& block = *it;
 
       if( uniformGrid_ ) // uniform data -> vti
       {
@@ -1213,11 +1213,11 @@ void VTKOutput::writeVTIPiece_sampling( std::ostream& ofs, const IBlock& block )
        << "   <CellData>\n";
 
    CellVector cells;
-   for( auto it = cellBB.begin(); it != cellBB.end(); ++it )
+   for(auto it : cellBB)
    {
-      Vector3<real_t> world( domain.xMin() + ( real_c( it->x() ) + real_t(0.5) ) * samplingDx_,
-         domain.yMin() + ( real_c( it->y() ) + real_t(0.5) ) * samplingDy_,
-         domain.zMin() + ( real_c( it->z() ) + real_t(0.5) ) * samplingDz_ );
+      Vector3<real_t> world( domain.xMin() + ( real_c( it.x() ) + real_t(0.5) ) * samplingDx_,
+         domain.yMin() + ( real_c( it.y() ) + real_t(0.5) ) * samplingDy_,
+         domain.zMin() + ( real_c( it.z() ) + real_t(0.5) ) * samplingDz_ );
 
       Cell cell;
       blockStorage_->getCell( cell, world[0], world[1], world[2], level );
@@ -1272,15 +1272,15 @@ void VTKOutput::writeParallelVTU( std::ostream& ofs, const Set<SUID>& requiredSt
       const cell_idx_t factorToFinest = 1 << (finestLevel - level);
       const CellInterval cells = blockStorage_->getBlockCellBB(*block); //  These are global cells
 
-      for (auto cell = cells.begin(); cell != cells.end(); ++cell)
+      for (auto cell : cells)
       {
          numberOfCells++;
-         const AABB aabb = blockStorage_->getCellAABB(*cell, level);
+         const AABB aabb = blockStorage_->getCellAABB(cell, level);
          for (cell_idx_t z = 0; z != 2; ++z) {
             for (cell_idx_t y = 0; y != 2; ++y) {
                for (cell_idx_t x = 0; x != 2; ++x)
                {
-                  const Vertex v((cell->x() + x) * factorToFinest, (cell->y() + y) * factorToFinest, (cell->z() + z) * factorToFinest);
+                  const Vertex v((cell.x() + x) * factorToFinest, (cell.y() + y) * factorToFinest, (cell.z() + z) * factorToFinest);
                   auto mapping = vimap.find(v);
                   if (mapping != vimap.end()) // vertex already exists
                   {
@@ -1326,16 +1326,16 @@ void VTKOutput::writeVTUPiece( std::ostream& ofs, const IBlock& block, const Cel
    std::vector< VertexCoord >               vc;    // vertex coordinates
    std::vector< Index >                     ci;    // ci[0] to ci[7]: indices for cell number one, ci[8] to ci[15]: ...
 
-   for (auto cell = cells.begin(); cell != cells.end(); ++cell)
+   for (auto cell : cells)
    {
       AABB aabb;
-      blockStorage_->getBlockLocalCellAABB(block, *cell, aabb);
+      blockStorage_->getBlockLocalCellAABB(block, cell, aabb);
 
       for (cell_idx_t z = 0; z != 2; ++z) {
          for (cell_idx_t y = 0; y != 2; ++y) {
             for (cell_idx_t x = 0; x != 2; ++x)
             {
-               Vertex v(cell->x() + x, cell->y() + y, cell->z() + z);
+               Vertex v(cell.x() + x, cell.y() + y, cell.z() + z);
 
                auto mapping = vimap.find(v);
                if (mapping != vimap.end()) // vertex already exists
@@ -1372,14 +1372,14 @@ void VTKOutput::writeVTUPiece( std::ostream& ofs, const IBlock& block, const Cel
       if (binary_)
       {
          Base64Writer base64;
-         for (auto cell = cells.begin(); cell != cells.end(); ++cell)
-            base64 << ghostLayerNr(block, cell->x(), cell->y(), cell->z());
+         for (auto cell : cells)
+            base64 << ghostLayerNr(block, cell.x(), cell.y(), cell.z());
          base64.toStream(ofs);
       }
       else
       {
-         for (auto cell = cells.begin(); cell != cells.end(); ++cell)
-            ofs << uint_c(ghostLayerNr(block, cell->x(), cell->y(), cell->z())) << " ";
+         for (auto cell : cells)
+            ofs << uint_c(ghostLayerNr(block, cell.x(), cell.y(), cell.z())) << " ";
          ofs << "\n";
       }
 
@@ -1419,12 +1419,12 @@ void VTKOutput::writeVTUPiece_sampling(std::ostream& ofs, const IBlock& block, c
    std::vector< VertexCoord >               vc;    // vertex coordinates
    std::vector< Index >                     ci;    // ci[0] to ci[7]: indices for cell number one, ci[8] to ci[15]: ...
 
-   for (auto cell = cells.begin(); cell != cells.end(); ++cell) {
+   for (auto & cell : cells) {
       for (cell_idx_t z = 0; z != 2; ++z) {
          for (cell_idx_t y = 0; y != 2; ++y) {
             for (cell_idx_t x = 0; x != 2; ++x)
             {
-               Vertex v(cell->coordinates_.x() + x, cell->coordinates_.y() + y, cell->coordinates_.z() + z);
+               Vertex v(cell.coordinates_.x() + x, cell.coordinates_.y() + y, cell.coordinates_.z() + z);
 
                auto mapping = vimap.find(v);
                if (mapping != vimap.end()) // vertex already exists
@@ -1435,9 +1435,9 @@ void VTKOutput::writeVTUPiece_sampling(std::ostream& ofs, const IBlock& block, c
                {
                   vimap[v] = numeric_cast< Index >(vc.size());
                   ci.push_back(numeric_cast< Index >(vc.size()));
-                  vc.emplace_back((x == 0) ? cell->aabb_.xMin() : cell->aabb_.xMax(),
-                     (y == 0) ? cell->aabb_.yMin() : cell->aabb_.yMax(),
-                     (z == 0) ? cell->aabb_.zMin() : cell->aabb_.zMax());
+                  vc.emplace_back((x == 0) ? cell.aabb_.xMin() : cell.aabb_.xMax(),
+                     (y == 0) ? cell.aabb_.yMin() : cell.aabb_.yMax(),
+                     (z == 0) ? cell.aabb_.zMin() : cell.aabb_.zMax());
                }
             }
          }
@@ -1482,14 +1482,14 @@ void VTKOutput::writeVTUHeaderPiece( std::ostream& ofs, const uint_t numberOfCel
    if( binary_ )
    {
       Base64Writer base64;
-      for( auto vertex = vc.begin(); vertex != vc.end(); ++vertex )
-         base64 << numeric_cast<float>( std::get<0>( *vertex ) ) << numeric_cast<float>( std::get<1>( *vertex ) )
-                << numeric_cast<float>( std::get<2>( *vertex ) );
+      for(const auto & vertex : vc)
+         base64 << numeric_cast<float>( std::get<0>( vertex ) ) << numeric_cast<float>( std::get<1>( vertex ) )
+                << numeric_cast<float>( std::get<2>( vertex ) );
       ofs << "     "; base64.toStream( ofs );
    }
-   else for( auto vertex = vc.begin(); vertex != vc.end(); ++vertex )
-      ofs << "     " << numeric_cast<float>( std::get<0>( *vertex ) ) << " " << numeric_cast<float>( std::get<1>( *vertex ) )
-          << " " << numeric_cast<float>( std::get<2>( *vertex ) ) << "\n";
+   else for(const auto & vertex : vc)
+      ofs << "     " << numeric_cast<float>( std::get<0>( vertex ) ) << " " << numeric_cast<float>( std::get<1>( vertex ) )
+          << " " << numeric_cast<float>( std::get<2>( vertex ) ) << "\n";
 
    ofs << "    </DataArray>\n"
        << "   </Points>\n"
@@ -1635,29 +1635,29 @@ void VTKOutput::writeCellData( std::ostream& ofs, const IBlock& block, const Cel
 {
    WALBERLA_ASSERT_NOT_NULLPTR( blockStorage_ );
 
-   for( auto writer = cellDataWriter_.begin(); writer != cellDataWriter_.end(); ++writer )
+   for(const auto & writer : cellDataWriter_)
    {
-      (*writer)->configure( block, *blockStorage_ );
+      writer->configure( block, *blockStorage_ );
 
-      ofs << "    <DataArray type=\"" << (*writer)->typeString() << "\" Name=\"" << (*writer)->identifier()
-                                      << "\" NumberOfComponents=\"" << (*writer)->fSize() << "\" format=\"" << format_ << "\">\n";
+      ofs << "    <DataArray type=\"" << writer->typeString() << "\" Name=\"" << writer->identifier()
+                                      << "\" NumberOfComponents=\"" << writer->fSize() << "\" format=\"" << format_ << "\">\n";
 
       if( binary_ )
       {
          Base64Writer base64;
-         for( auto cell = cells.begin(); cell != cells.end(); ++cell )
-            for( uint_t f = 0; f != (*writer)->fSize(); ++f )
-               (*writer)->push( base64, cell->x(), cell->y(), cell->z(), cell_idx_c(f) );
+         for(auto cell : cells)
+            for( uint_t f = 0; f != writer->fSize(); ++f )
+               writer->push( base64, cell.x(), cell.y(), cell.z(), cell_idx_c(f) );
          ofs << "     "; base64.toStream( ofs );
       }
       else
       {
-         for( auto cell = cells.begin(); cell != cells.end(); ++cell ) {
+         for(auto cell : cells) {
             ofs << "     ";
-            for( uint_t f = 0; f != (*writer)->fSize(); ++f )
+            for( uint_t f = 0; f != writer->fSize(); ++f )
             {
-               (*writer)->push( ofs, cell->x(), cell->y(), cell->z(), cell_idx_c(f) );
-               ofs << ( ( f == (*writer)->fSize() - 1 ) ? "\n" : " " );
+               writer->push( ofs, cell.x(), cell.y(), cell.z(), cell_idx_c(f) );
+               ofs << ( ( f == writer->fSize() - 1 ) ? "\n" : " " );
             }
          }
       }
@@ -1671,10 +1671,10 @@ void VTKOutput::writeCellData( std::ostream& ofs, const Set<SUID>& requiredState
 {
    WALBERLA_ASSERT_NOT_NULLPTR( blockStorage_ );
 
-   for( auto writer = cellDataWriter_.begin(); writer != cellDataWriter_.end(); ++writer )
+   for(const auto & writer : cellDataWriter_)
    {
-      ofs << "    <DataArray type=\"" << (*writer)->typeString() << "\" Name=\"" << (*writer)->identifier()
-          << "\" NumberOfComponents=\"" << (*writer)->fSize() << "\" format=\"" << format_ << "\">\n";
+      ofs << "    <DataArray type=\"" << writer->typeString() << "\" Name=\"" << writer->identifier()
+          << "\" NumberOfComponents=\"" << writer->fSize() << "\" format=\"" << format_ << "\">\n";
 
       for( auto block = blockStorage_->begin(); block != blockStorage_->end(); ++block )
       {
@@ -1683,24 +1683,24 @@ void VTKOutput::writeCellData( std::ostream& ofs, const Set<SUID>& requiredState
 
          CellVector cells; // cells to be written to file
          computeVTUCells(*block, cells);
-         (*writer)->configure( *block, *blockStorage_ );
+         writer->configure( *block, *blockStorage_ );
 
          if( binary_ )
          {
             Base64Writer base64;
-            for( auto cell = cells.begin(); cell != cells.end(); ++cell )
-               for( uint_t f = 0; f != (*writer)->fSize(); ++f )
-                  (*writer)->push( base64, cell->x(), cell->y(), cell->z(), cell_idx_c(f) );
+            for(auto & cell : cells)
+               for( uint_t f = 0; f != writer->fSize(); ++f )
+                  writer->push( base64, cell.x(), cell.y(), cell.z(), cell_idx_c(f) );
             ofs << "     "; base64.toStream( ofs );
          }
          else
          {
-            for( auto cell = cells.begin(); cell != cells.end(); ++cell ) {
+            for(auto & cell : cells) {
                ofs << "     ";
-               for( uint_t f = 0; f != (*writer)->fSize(); ++f )
+               for( uint_t f = 0; f != writer->fSize(); ++f )
                {
-                  (*writer)->push( ofs, cell->x(), cell->y(), cell->z(), cell_idx_c(f) );
-                  ofs << ( ( f == (*writer)->fSize() - 1 ) ? "\n" : " " );
+                  writer->push( ofs, cell.x(), cell.y(), cell.z(), cell_idx_c(f) );
+                  ofs << ( ( f == writer->fSize() - 1 ) ? "\n" : " " );
                }
             }
          }
@@ -1714,35 +1714,35 @@ void VTKOutput::writeCellData( std::ostream& ofs, const IBlock& block, const std
 {
    WALBERLA_ASSERT_NOT_NULLPTR( blockStorage_ );
 
-   for( auto writer = cellDataWriter_.begin(); writer != cellDataWriter_.end(); ++writer )
+   for(const auto & writer : cellDataWriter_)
    {
-      (*writer)->configure( block, *blockStorage_ );
+      writer->configure( block, *blockStorage_ );
 
-      ofs << "    <DataArray type=\"" << (*writer)->typeString() << "\" Name=\"" << (*writer)->identifier()
-                                      << "\" NumberOfComponents=\"" << (*writer)->fSize() << "\" format=\"" << format_ << "\">\n";
+      ofs << "    <DataArray type=\"" << writer->typeString() << "\" Name=\"" << writer->identifier()
+                                      << "\" NumberOfComponents=\"" << writer->fSize() << "\" format=\"" << format_ << "\">\n";
 
       if( binary_ )
       {
          Base64Writer base64;
-         for( auto cell = cells.begin(); cell != cells.end(); ++cell )
-            for( uint_t f = 0; f != (*writer)->fSize(); ++f )
-               (*writer)->push( base64, cell->localCell_.x(), cell->localCell_.y(), cell->localCell_.z(), cell_idx_c(f),
-                                        cell->localCellX_,    cell->localCellY_,    cell->localCellZ_,
-                                        cell->globalX_   ,    cell->globalY_,       cell->globalZ_,
+         for(const auto & cell : cells)
+            for( uint_t f = 0; f != writer->fSize(); ++f )
+               writer->push( base64, cell.localCell_.x(), cell.localCell_.y(), cell.localCell_.z(), cell_idx_c(f),
+                                        cell.localCellX_,    cell.localCellY_,    cell.localCellZ_,
+                                        cell.globalX_   ,    cell.globalY_,       cell.globalZ_,
                                         samplingDx_,          samplingDy_,          samplingDz_ );
          ofs << "     "; base64.toStream( ofs );
       }
       else
       {
-         for( auto cell = cells.begin(); cell != cells.end(); ++cell ) {
+         for(const auto & cell : cells) {
             ofs << "     ";
-            for( uint_t f = 0; f != (*writer)->fSize(); ++f )
+            for( uint_t f = 0; f != writer->fSize(); ++f )
             {
-               (*writer)->push( ofs, cell->localCell_.x(), cell->localCell_.y(), cell->localCell_.z(), cell_idx_c(f),
-                                     cell->localCellX_,    cell->localCellY_,    cell->localCellZ_,
-                                     cell->globalX_   ,    cell->globalY_,       cell->globalZ_,
+               writer->push( ofs, cell.localCell_.x(), cell.localCell_.y(), cell.localCell_.z(), cell_idx_c(f),
+                                     cell.localCellX_,    cell.localCellY_,    cell.localCellZ_,
+                                     cell.globalX_   ,    cell.globalY_,       cell.globalZ_,
                                      samplingDx_,          samplingDy_,          samplingDz_ );
-               ofs << ( ( f == (*writer)->fSize() - 1 ) ? "\n" : " " );
+               ofs << ( ( f == writer->fSize() - 1 ) ? "\n" : " " );
             }
          }
       }
@@ -1768,23 +1768,23 @@ void VTKOutput::writeCollectors( const bool barrier )
 
 
 
-   for( auto collector = collectorsToWrite_.begin(); collector != collectorsToWrite_.end(); ++collector )
+   for(unsigned long & collector : collectorsToWrite_)
    {
       if( uniformGrid_ )
       {
          if( samplingDx_ <= real_c(0) || samplingDy_ <= real_c(0) || samplingDz_ <= real_c(0) )
-            writePVTI( *collector );
+            writePVTI( collector );
          else
-            writePVTI_sampled( *collector );
+            writePVTI_sampled( collector );
       }
       else if (amrFileFormat_)
       {
          writeVTHBSeries();
-         writeVTHB( *collector );
+         writeVTHB( collector );
       }
       else
       {
-         writePVTU( *collector ); // also applies for outputDomainDecomposition_ == true and pointDataSource_ != nullptr
+         writePVTU( collector ); // also applies for outputDomainDecomposition_ == true and pointDataSource_ != nullptr
                                   // and polylineDataSource_ != nullptr (uniformGrid_ will be false)
       }
    }
@@ -1845,11 +1845,11 @@ void VTKOutput::writePVD()
          ending = ".pvti";
    }
 
-   for( auto collector = allCollectors_.begin(); collector != allCollectors_.end(); ++collector )
+   for(unsigned long & allCollector : allCollectors_)
    {
       std::ostringstream collection;
-      collection << identifier_ << "/" << executionFolder_ << "_" << *collector << ending;
-      ofs << "  <DataSet timestep=\"" << *collector << "\" file=\"" << collection.str() << "\"/>\n";
+      collection << identifier_ << "/" << executionFolder_ << "_" << allCollector << ending;
+      ofs << "  <DataSet timestep=\"" << allCollector << "\" file=\"" << collection.str() << "\"/>\n";
    }
    allCollectors_.clear();
 
@@ -1901,11 +1901,11 @@ void VTKOutput::writeVTHBSeries()
 
    std::string ending = ".vthb";
 
-   for( auto collector = allCollectors_.begin(); collector != allCollectors_.end(); ++collector )
+   for(unsigned long & allCollector : allCollectors_)
    {
       std::ostringstream collection;
-      collection << identifier_ << "/" << executionFolder_ << "_" << *collector << ending;
-      ofs << "      { \"name\" : \"" << collection.str() << "\", \"time\":" << *collector << " },\n";
+      collection << identifier_ << "/" << executionFolder_ << "_" << allCollector << ending;
+      ofs << "      { \"name\" : \"" << collection.str() << "\", \"time\":" << allCollector << " },\n";
    }
    allCollectors_.clear();
 
@@ -1946,9 +1946,9 @@ void VTKOutput::writePVTI( const uint_t collector ) const
    std::vector< filesystem::path > files;
    getFilenames( files, collector );
 
-   for( auto file = files.begin(); file != files.end(); ++file )
+   for(auto & file : files)
    {
-      std::ifstream ifs( file->string().c_str() );
+      std::ifstream ifs( file.string().c_str() );
 
       std::string piece;
       for( uint_t i = 0; i != 4; ++i )
@@ -1957,7 +1957,7 @@ void VTKOutput::writePVTI( const uint_t collector ) const
 
       piece.erase( piece.length()-1, 1 );
 
-      ofs << piece << " Source=\"" << executionFolder_ << "_" << collector << "/" << file->filename().string() << "\"/>\n";
+      ofs << piece << " Source=\"" << executionFolder_ << "_" << collector << "/" << file.filename().string() << "\"/>\n";
    }
 
    ofs << " </PImageData>\n"
@@ -1987,8 +1987,8 @@ void VTKOutput::writeVTHB( const uint_t collector ) const
    for( uint_t level = 0; level < files.size(); level++){
       ofs << "  <Block level=\"" << level << "\">\n";
       walberla::uint_t index = 0;
-      for( auto file = files[level].begin(); file != files[level].end(); ++file ){
-         ofs << "   <DataSet index=\"" << index << "\" file=\"" << executionFolder_ << "_" << collector << "/" << file->filename().string() << "\"/>\n";
+      for(auto & file : files[level]){
+         ofs << "   <DataSet index=\"" << index << "\" file=\"" << executionFolder_ << "_" << collector << "/" << file.filename().string() << "\"/>\n";
          index++;
       }
       ofs << "  </Block>\n";
@@ -2030,9 +2030,9 @@ void VTKOutput::writePVTI_sampled( const uint_t collector ) const
    std::vector< filesystem::path > files;
    getFilenames( files, collector );
 
-   for( auto file = files.begin(); file != files.end(); ++file )
+   for(auto & file : files)
    {
-      std::ifstream ifs( file->string().c_str() );
+      std::ifstream ifs( file.string().c_str() );
 
       std::string piece;
       for( uint_t i = 0; i != 4; ++i )
@@ -2041,7 +2041,7 @@ void VTKOutput::writePVTI_sampled( const uint_t collector ) const
 
       piece.erase( piece.length()-1, 1 );
 
-      ofs << piece << " Source=\"" << executionFolder_ << "_" << collector << "/" << file->filename().string() << "\"/>\n";
+      ofs << piece << " Source=\"" << executionFolder_ << "_" << collector << "/" << file.filename().string() << "\"/>\n";
    }
 
    ofs << " </PImageData>\n"
@@ -2178,8 +2178,8 @@ void VTKOutput::writePVTU( const uint_t collector ) const
    std::vector< filesystem::path > files;
    getFilenames( files, collector );
 
-   for( auto file = files.begin(); file != files.end(); ++file )
-      ofs << "  <Piece Source=\"" << executionFolder_ << "_" << collector << "/" << file->filename().string() << "\"/>\n";
+   for(auto & file : files)
+      ofs << "  <Piece Source=\"" << executionFolder_ << "_" << collector << "/" << file.filename().string() << "\"/>\n";
 
    ofs << " </PUnstructuredGrid>\n"
        << "</VTKFile>\n";
@@ -2276,16 +2276,16 @@ void VTKOutput::writePPointData( std::ofstream& ofs ) const
    if( pointDataSource_ )
    {
       auto attributes = pointDataSource_->getAttributes();
-      for( auto dataArray = attributes.begin(); dataArray != attributes.end(); ++dataArray )
-         ofs << "   <PDataArray type=\"" << dataArray->type << "\" Name=\"" << dataArray->name
-                                         << "\" NumberOfComponents=\"" << dataArray->components << "\" format=\"" << format_ << "\"/>\n";
+      for(auto & attribute : attributes)
+         ofs << "   <PDataArray type=\"" << attribute.type << "\" Name=\"" << attribute.name
+                                         << "\" NumberOfComponents=\"" << attribute.components << "\" format=\"" << format_ << "\"/>\n";
    }
    else if( polylineDataSource_ )
    {
       auto attributes = polylineDataSource_->getAttributes();
-      for( auto dataArray = attributes.begin(); dataArray != attributes.end(); ++dataArray )
-         ofs << "   <PDataArray type=\"" << dataArray->type << "\" Name=\"" << dataArray->name
-                                         << "\" NumberOfComponents=\"" << dataArray->components << "\" format=\"" << format_ << "\"/>\n";
+      for(auto & attribute : attributes)
+         ofs << "   <PDataArray type=\"" << attribute.type << "\" Name=\"" << attribute.name
+                                         << "\" NumberOfComponents=\"" << attribute.components << "\" format=\"" << format_ << "\"/>\n";
    }
 }
 
@@ -2301,10 +2301,10 @@ void VTKOutput::writePCellData( std::ofstream& ofs ) const
                                       << "\" Name=\"Process\" NumberOfComponents=\"1\" format=\"" << format_ << "\"/>\n";
    }
 
-   for( auto writer = cellDataWriter_.begin(); writer != cellDataWriter_.end(); ++writer )
+   for(const auto & writer : cellDataWriter_)
    {
-      ofs << "   <PDataArray type=\"" << (*writer)->typeString() << "\" Name=\"" << (*writer)->identifier()
-                                      << "\" NumberOfComponents=\"" << (*writer)->fSize() << "\" format=\"" << format_ << "\"/>\n";
+      ofs << "   <PDataArray type=\"" << writer->typeString() << "\" Name=\"" << writer->identifier()
+                                      << "\" NumberOfComponents=\"" << writer->fSize() << "\" format=\"" << format_ << "\"/>\n";
    }
 }
 
diff --git a/src/vtk/VTKOutput.h b/src/vtk/VTKOutput.h
index 74f12f05a58e7aeeb16c53b85bbe161181b2b8e9..bda84f9d77ef9f3e46e2156619bf410b6b019567 100644
--- a/src/vtk/VTKOutput.h
+++ b/src/vtk/VTKOutput.h
@@ -180,8 +180,6 @@ public:
 
 private:
 
-   VTKOutput();
-
    /// creates a VTKOutput object that is supposed to output the domain decomposition
    VTKOutput( const BlockStorage & sbs, const std::string & identifier, const uint_t writeFrequency,
               const std::string & baseFolder, const std::string & executionFolder,
@@ -714,14 +712,14 @@ inline VTKOutput::Write writeFiles( const shared_ptr<VTKOutput> & vtk,
                                     const Set<SUID>& requiredStates     = Set<SUID>::emptySet(),
                                     const Set<SUID>& incompatibleStates = Set<SUID>::emptySet() )
 {
-   return VTKOutput::Write( vtk, immediatelyWriteCollectors, simultaneousIOOperations, requiredStates, incompatibleStates );
+   return { vtk, immediatelyWriteCollectors, simultaneousIOOperations, requiredStates, incompatibleStates };
 }
 
 
 
 inline VTKOutput::WriteCollectors writeCollectorFiles( const shared_ptr<VTKOutput> & vtk, const bool barrier )
 {
-   return VTKOutput::WriteCollectors( vtk, barrier );
+   return { vtk, barrier };
 }
 
 
diff --git a/tests/blockforest/BlockDataIOTest.cpp b/tests/blockforest/BlockDataIOTest.cpp
index b72a9dded44f10062ab290fe758dd93199df53c3..a62edefd12e4c826aed5c4903fa685efd955cfea 100644
--- a/tests/blockforest/BlockDataIOTest.cpp
+++ b/tests/blockforest/BlockDataIOTest.cpp
@@ -42,24 +42,24 @@ const Set< SUID > None(Set< SUID >::emptySet());
 
 static void refinementSelectionFunction(SetupBlockForest& forest)
 {
-   for (auto block = forest.begin(); block != forest.end(); ++block)
-      if (block->getAABB().contains(Vector3< real_t >(real_t(75))))
-         if (!block->hasFather()) block->setMarker(true);
+   for (auto & block : forest)
+      if (block.getAABB().contains(Vector3< real_t >(real_t(75))))
+         if (!block.hasFather()) block.setMarker(true);
 }
 
 static void workloadMemorySUIDAssignmentFunction(SetupBlockForest& forest)
 {
-   for (auto block = forest.begin(); block != forest.end(); ++block)
+   for (auto & block : forest)
    {
-      block->setMemory(memory_t(1));
-      block->setWorkload(workload_t(1));
-      if (block->getAABB().contains(Vector3< real_t >(real_t(25)))) block->addState(Empty);
+      block.setMemory(memory_t(1));
+      block.setWorkload(workload_t(1));
+      if (block.getAABB().contains(Vector3< real_t >(real_t(25)))) block.addState(Empty);
    }
 }
 
 void test()
 {
-   typedef field::GhostLayerField< double, 2 > FieldType;
+   using FieldType = field::GhostLayerField<double, 2>;
 
    SetupBlockForest sforest;
 
diff --git a/tests/blockforest/BlockForestTest.cpp b/tests/blockforest/BlockForestTest.cpp
index 6c18b2fa0d5f8130b5bb45789fa29675e579070b..e9a007d8b2f7bc3f56ab04df3015281d3dada79c 100644
--- a/tests/blockforest/BlockForestTest.cpp
+++ b/tests/blockforest/BlockForestTest.cpp
@@ -89,8 +89,7 @@ static void workloadMemorySUIDAssignmentFunction( SetupBlockForest& forest ) {
       suids.emplace_back( oss.str(), false );
    }
 
-   for( uint_t i = 0; i != blocks.size(); ++i ) {
-      SetupBlock* block = blocks[i];
+   for(auto block : blocks) {
       block->setMemory( numeric_cast< memory_t >( 1.0 ) );
       block->setWorkload( numeric_cast< workload_t >( std::pow( 2.0, numeric_cast<double>(block->getLevel()) ) ) );
       if( block->getLevel() > 0 )
@@ -102,11 +101,11 @@ static void workloadMemorySUIDAssignmentFunction( SetupBlockForest& forest ) {
 
 static memory_t communicationCalculationFunction( const SetupBlock* const a, const SetupBlock* const b ) {
 
-   uint_t faces[] = { 4, 10, 12, 13, 15, 21 };
+   std::array< uint_t, 6 > faces = { 4, 10, 12, 13, 15, 21 };
 
-   for( uint_t i = 0; i != 6; ++i ) {
-      for( uint_t j = 0; j != a->getNeighborhoodSectionSize(faces[i]); ++j )
-         if( a->getNeighbor(faces[i],j) == b )
+   for(uint_t face : faces) {
+      for( uint_t j = 0; j != a->getNeighborhoodSectionSize(face); ++j )
+         if( a->getNeighbor(face,j) == b )
             return 1000.0;
    }
 
@@ -457,8 +456,8 @@ static void test() {
       setupBlockSet.insert( block->getId() );
    }
 
-   for( auto blockId = blockIds.begin(); blockId != blockIds.end(); ++blockId ) {
-      const BlockID id = *dynamic_cast< BlockID* >( blockId->get() );
+   for(auto & blockId : blockIds) {
+      const BlockID id = *dynamic_cast< BlockID* >( blockId.get() );
       WALBERLA_CHECK_EQUAL( forestBlockSet.find( id ), forestBlockSet.end() )
       forestBlockSet.insert( id );
    }
diff --git a/tests/blockforest/SetupBlockForestTest.cpp b/tests/blockforest/SetupBlockForestTest.cpp
index 527a41776b4f14dc341a36988aad0f21c19dfffc..990561bc6fbfd227b4ceed11b3794899ef2201e8 100644
--- a/tests/blockforest/SetupBlockForestTest.cpp
+++ b/tests/blockforest/SetupBlockForestTest.cpp
@@ -39,8 +39,8 @@ static void refinementSelectionFunctionAll( SetupBlockForest& forest ) {
    std::vector< SetupBlock* > blocks;
    forest.getBlocks( blocks );
 
-   for( uint_t i = 0; i != blocks.size(); ++i )
-      if( blocks[i]->getLevel() < 2 ) blocks[i]->setMarker( true );
+   for(auto & block : blocks)
+      if( block->getLevel() < 2 ) block->setMarker( true );
 }
 
 
@@ -83,8 +83,8 @@ static void checkCollectorConsistency( SetupBlockForest& forest ) {
       WALBERLA_CHECK( blocks[i] == itBlocks[i] )
 
    std::set< SetupBlock* > baseSet;
-   for( uint_t i = 0; i != blocks.size(); ++i )
-      baseSet.insert( blocks[i] );
+   for(auto block : blocks)
+      baseSet.insert( block );
    WALBERLA_CHECK_EQUAL( baseSet.size(), blocks.size() )
 
    std::vector< SetupBlock* > hilbertBlocks;
@@ -92,8 +92,8 @@ static void checkCollectorConsistency( SetupBlockForest& forest ) {
    WALBERLA_CHECK_EQUAL( hilbertBlocks.size(), blocks.size() )
 
    std::set< SetupBlock* > hilbertSet;
-   for( uint_t i = 0; i != hilbertBlocks.size(); ++i )
-      hilbertSet.insert( hilbertBlocks[i] );
+   for(auto hilbertBlock : hilbertBlocks)
+      hilbertSet.insert( hilbertBlock );
    WALBERLA_CHECK_EQUAL( hilbertSet.size(), hilbertBlocks.size() )
 
    std::set< SetupBlock* >::iterator baseIterator    = baseSet.begin();
@@ -110,8 +110,8 @@ static void checkCollectorConsistency( SetupBlockForest& forest ) {
    WALBERLA_CHECK_EQUAL( aabbBlocks.size(), blocks.size() )
 
    std::set< SetupBlock* > aabbSet;
-   for( uint_t i = 0; i != aabbBlocks.size(); ++i )
-      aabbSet.insert( aabbBlocks[i] );
+   for(auto aabbBlock : aabbBlocks)
+      aabbSet.insert( aabbBlock );
    WALBERLA_CHECK_EQUAL( aabbSet.size(), aabbBlocks.size() )
 
                                      baseIterator = baseSet.begin();
diff --git a/tests/blockforest/StructuredBlockForestTest.cpp b/tests/blockforest/StructuredBlockForestTest.cpp
index 8b0bf5b940c93fcfa8c3249e47a66b8c4cf441e6..ba69ede4ad9fd4e747e1b0e3f9a21522f4c4101b 100644
--- a/tests/blockforest/StructuredBlockForestTest.cpp
+++ b/tests/blockforest/StructuredBlockForestTest.cpp
@@ -59,9 +59,9 @@ static void workloadMemorySUIDAssignmentFunction( SetupBlockForest& forest ) {
    std::vector< SetupBlock* > blocks;
    forest.getBlocks( blocks );
 
-   for( uint_t i = 0; i != blocks.size(); ++i ) {
-      blocks[i]->setMemory( 1.0 );
-      blocks[i]->setWorkload( 1.0 );
+   for(auto & block : blocks) {
+      block->setMemory( 1.0 );
+      block->setWorkload( 1.0 );
    }
 }
 
diff --git a/tests/blockforest/communication/DirectionBasedReduceCommTest.cpp b/tests/blockforest/communication/DirectionBasedReduceCommTest.cpp
index 9382547824e4b3b307033a7e7e9fb1607e08a773..143f3c7316f93c28fe24cf93b836fb22aae5477f 100644
--- a/tests/blockforest/communication/DirectionBasedReduceCommTest.cpp
+++ b/tests/blockforest/communication/DirectionBasedReduceCommTest.cpp
@@ -39,7 +39,7 @@
 
 namespace walberla {
 
-typedef GhostLayerField<real_t,1> ScalarField;
+using ScalarField = GhostLayerField<real_t, 1>;
 
 template<bool init_>
 class SumSweep
@@ -88,7 +88,7 @@ class CompareSweep
          WALBERLA_ASSERT_NOT_NULLPTR( bf )
 
          const AABB & bb = block->getAABB();
-         const cell_idx_t offset [3] = { cell_idx_c(bb.min(uint_t(0u))),
+         const std::array< cell_idx_t, 3 > offset = { cell_idx_c(bb.min(uint_t(0u))),
                                          cell_idx_c(bb.min(uint_t(1u))),
                                          cell_idx_c(bb.min(uint_t(2u))) };
 
@@ -113,8 +113,8 @@ int main(int argc, char **argv)
    debug::enterTestMode();
    mpi::Environment env( argc, argv );
 
-   const uint_t cells [] = { uint_t(5u), uint_t(2u), uint_t(7u) };
-   const uint_t blockCount [] = { uint_t(1u), uint_t(1u), uint_c( MPIManager::instance()->numProcesses() ) };
+   const std::array< uint_t, 3 > cells = { uint_t(5u), uint_t(2u), uint_t(7u) };
+   const std::array< uint_t, 3 > blockCount = { uint_t(1u), uint_t(1u), uint_c( MPIManager::instance()->numProcesses() ) };
    const uint_t nrOfTimeSteps = uint_t(3u);
    bool periodic = false;
    const field::Layout layout = field::fzyx;
diff --git a/tests/blockforest/communication/GhostLayerCommTest.cpp b/tests/blockforest/communication/GhostLayerCommTest.cpp
index 932ec08768f2d3154186b96667ae34d4b9ff1a11..98a3c44847e7efab04105887c043d17884c01c48 100644
--- a/tests/blockforest/communication/GhostLayerCommTest.cpp
+++ b/tests/blockforest/communication/GhostLayerCommTest.cpp
@@ -43,7 +43,7 @@
 namespace walberla {
 namespace wlb = walberla;
 
-typedef GhostLayerField<real_t,19> PdfField;
+using PdfField = GhostLayerField<real_t, 19>;
 
 
 template<typename Sten>
@@ -65,7 +65,7 @@ class StreamingSweep
 
          for(PdfField::iterator i = dst->begin(); i != dst->end(); ++i )
          {
-            stencil::Direction d = Sten::dir[i.f()];
+            stencil::Direction d = Sten::dir[uint_c(i.f())];
             *i = src->get( i.x() - cx[d], i.y() - cy[d], i.z() - cz[d], i.f() );
          }
          src->swapDataPointers( dst );
@@ -131,7 +131,7 @@ class CompareSweep
          PdfField * bf = block->getData<PdfField>(bigField_);
 
          const AABB & bb = block->getAABB();
-         const cell_idx_t offset [3] = { wlb::cell_idx_c(bb.min(0)),
+         const std::array< cell_idx_t, 3 > offset = { wlb::cell_idx_c(bb.min(0)),
                                          wlb::cell_idx_c(bb.min(1)),
                                          wlb::cell_idx_c(bb.min(2)) };
 
@@ -187,8 +187,8 @@ int main(int argc, char **argv)
    auto mpiManager = MPIManager::instance();
    mpiManager->initializeMPI(&argc,&argv);
 
-   const uint_t cells [] = { 5,2,7 };
-   const uint_t blockCount [] = { uint_c( mpiManager->numProcesses() ), 1, 1 };
+   const std::array< uint_t, 3 > cells = { 5,2,7 };
+   const std::array< uint_t, 3 > blockCount = { uint_c( mpiManager->numProcesses() ), 1, 1 };
    const uint_t nrOfTimeSteps = 30;
    bool periodic = true;
    const field::Layout layout = field::fzyx;
diff --git a/tests/boundary/BoundaryHandling.cpp b/tests/boundary/BoundaryHandling.cpp
index 77213c33d6fb45e04d93644c8451c38e0cd2b09a..3e9c16e469882235de3d2a54fd085ec5de3fc269 100644
--- a/tests/boundary/BoundaryHandling.cpp
+++ b/tests/boundary/BoundaryHandling.cpp
@@ -43,8 +43,8 @@ namespace walberla {
 using flag_t = uint8_t;
 
 using FlagField_T = FlagField<flag_t>;
-typedef GhostLayerField< uint_t, stencil::D3Q27::Size > WorkField_T;
-typedef GhostLayerField< uint_t, 1 >                    FactorField_T;
+using WorkField_T = GhostLayerField<uint_t, stencil::D3Q27::Size>;
+using FactorField_T = GhostLayerField<uint_t, 1>;
 
 
 
@@ -60,7 +60,7 @@ public:
       { return make_shared<BoundaryConfiguration>(); }
 
    CopyBoundary( const FlagUID& uid1, const FlagUID& uid2, WorkField_T* const field ) :
-      Boundary<flag_t>("CopyBoundary"), uid1_( uid1 ), uid2_( uid2 ), field_( field ), beforeCounter_(0), afterCounter_(0) { WALBERLA_ASSERT_NOT_NULLPTR( field_ ); }
+      Boundary<flag_t>("CopyBoundary"), uid1_( uid1 ), uid2_( uid2 ), field_( field ) { WALBERLA_ASSERT_NOT_NULLPTR( field_ ); }
 
    void pushFlags( std::vector< FlagUID >& uids ) const { uids.push_back( uid1_ ); uids.push_back( uid2_ ); }
 
@@ -70,7 +70,7 @@ public:
    void registerCell( const flag_t, const cell_idx_t x, const cell_idx_t y, const cell_idx_t z, const BoundaryConfiguration& ) {
       registeredCells_.push_back(x,y,z); }
    void registerCells( const flag_t, const CellInterval& interval, const BoundaryConfiguration& ) {
-      for( auto cell = interval.begin(); cell != interval.end(); ++cell ) registeredCells_.push_back( cell->x(), cell->y(), cell->z() ); }
+      for(auto cell : interval) registeredCells_.push_back( cell.x(), cell.y(), cell.z() ); }
    template< typename CellIterator >
    void registerCells( const flag_t, const CellIterator& begin, const CellIterator& end, const BoundaryConfiguration& ) {
       for( auto cell = begin; cell != end; ++cell ) registeredCells_.push_back( cell->x(), cell->y(), cell->z() ); }
@@ -108,8 +108,8 @@ private:
 
    WorkField_T* const field_;
 
-   uint_t beforeCounter_;
-   uint_t afterCounter_;
+   uint_t beforeCounter_{0};
+   uint_t afterCounter_{0};
 
    CellVector registeredCells_;
    CellVector unregisteredCells_;
@@ -154,8 +154,8 @@ public:
       factorField_->get(x,y,z) = dynamic_cast< const Configuration& >( factor ).f();
    }
    inline void registerCells( const flag_t, const CellInterval& cells, const BoundaryConfiguration& factor ) {
-      for( auto cell = cells.begin(); cell != cells.end(); ++cell )
-         factorField_->get( cell->x(), cell->y(), cell->z() ) = dynamic_cast< const Configuration& >( factor ).f();
+      for(auto cell : cells)
+         factorField_->get( cell.x(), cell.y(), cell.z() ) = dynamic_cast< const Configuration& >( factor ).f();
    }
    template< typename CellIterator >
    inline void registerCells( const flag_t, const CellIterator& begin, const CellIterator& end, const BoundaryConfiguration& factor ) {
@@ -201,7 +201,7 @@ private:
 // TEST BOUNDARY HANDLING //
 ////////////////////////////
 
-typedef BoundaryHandling< FlagField_T, stencil::D3Q27, CopyBoundary, AddBoundary > TestBoundaryHandling;
+using TestBoundaryHandling = BoundaryHandling<FlagField_T, stencil::D3Q27, CopyBoundary, AddBoundary>;
 
 
 
@@ -444,22 +444,22 @@ static int main( int argc, char **argv )
    CellVector cellVec;
    for( uint_t i = 3; i != 8; ++i )
       cellVec.push_back( cell_idx_c(1), cell_idx_c(5), cell_idx_c(i) );
-   for( auto c = cellVec.begin(); c != cellVec.end(); ++c )
-      flagField_Ref.addMask( c->x(), c->y(), c->z(), domainFlag1 );
+   for(auto & c : cellVec)
+      flagField_Ref.addMask( c.x(), c.y(), c.z(), domainFlag1 );
    handling.setDomain( domainFlag1, cellVec.begin(), cellVec.end() );
 
    cellVec.clear();
    for( uint_t i = 1; i != 5; ++i )
       cellVec.push_back( cell_idx_c(1), cell_idx_c(3), cell_idx_c(i) );
-   for( auto c = cellVec.begin(); c != cellVec.end(); ++c )
-      flagField_Ref.addFlag( c->x(), c->y(), c->z(), domainFlag1 );
+   for(auto & c : cellVec)
+      flagField_Ref.addFlag( c.x(), c.y(), c.z(), domainFlag1 );
    handling.setDomain( domainFlag1, cellVec.begin(), cellVec.end() );
 
    CellSet cellSet;
    for( cell_idx_t i = -1; i != 4; ++i )
       cellSet.insert( cell_idx_c(1), cell_idx_c(1), i );
-   for( auto c = cellSet.begin(); c != cellSet.end(); ++c )
-      flagField_Ref.addFlag( c->x(), c->y(), c->z(), domainFlag2 );
+   for(auto c : cellSet)
+      flagField_Ref.addFlag( c.x(), c.y(), c.z(), domainFlag2 );
    handling.setDomain( domainFlag2, cellSet.begin(), cellSet.end() );
 
    WALBERLA_CHECK_EQUAL( flagField_Ref, flagField_BH );
@@ -467,13 +467,13 @@ static int main( int argc, char **argv )
    // setDomain - interval
 
    CellInterval cells( cell_idx_c(-1), cell_idx_c(2), cell_idx_c(2), cell_idx_c(-1), cell_idx_c(4), cell_idx_c(6) );
-   for( auto c = cells.begin(); c != cells.end(); ++c )
-      flagField_Ref.addMask( c->x(), c->y(), c->z(), domainFlag1 );
+   for(auto c : cells)
+      flagField_Ref.addMask( c.x(), c.y(), c.z(), domainFlag1 );
    handling.setDomain( domainFlag1, cells );
 
    cells = CellInterval( cell_idx_c(2), cell_idx_c(-1), cell_idx_c(-1), cell_idx_c(3), cell_idx_c(5), cell_idx_c(8) );
-   for( auto c = cells.begin(); c != cells.end(); ++c )
-      flagField_Ref.addFlag( c->x(), c->y(), c->z(), domainFlag2 );
+   for(auto c : cells)
+      flagField_Ref.addFlag( c.x(), c.y(), c.z(), domainFlag2 );
    handling.setDomain( domainFlag2, cells );
 
    WALBERLA_CHECK_EQUAL( flagField_Ref, flagField_BH );
@@ -515,18 +515,18 @@ static int main( int argc, char **argv )
    // setBoundary - interval
 
    cells = CellInterval( cell_idx_c(4), cell_idx_c(1), cell_idx_c(-1), cell_idx_c(4), cell_idx_c(2), cell_idx_c(8) );
-   for( auto c = cells.begin(); c != cells.end(); ++c )
+   for(auto c : cells)
    {
-      flagField_Ref.addFlag( c->x(), c->y(), c->z(), addFlag );
-      factorField_Ref( c->x(), c->y(), c->z() ) = uint_c(42);
+      flagField_Ref.addFlag( c.x(), c.y(), c.z(), addFlag );
+      factorField_Ref( c.x(), c.y(), c.z() ) = uint_c(42);
    }
    handling.setBoundary( add, cells, AddBoundary::Configuration( uint_c(42) ) );
 
    cells = CellInterval( cell_idx_c(4), cell_idx_c(3), cell_idx_c(-1), cell_idx_c(4), cell_idx_c(5), cell_idx_c(8) );
-   for( auto c = cells.begin(); c != cells.end(); ++c )
+   for(auto c : cells)
    {
-      flagField_Ref.addMask( c->x(), c->y(), c->z(), copyFlag1 );
-      registeredCells.push_back( c->x(), c->y(), c->z() );
+      flagField_Ref.addMask( c.x(), c.y(), c.z(), copyFlag1 );
+      registeredCells.push_back( c.x(), c.y(), c.z() );
    }
    handling.setBoundary( copyFlag1, cells );
 
@@ -535,20 +535,20 @@ static int main( int argc, char **argv )
    cellVec.clear();
    for( uint_t i = 1; i != 4; ++i )
       cellVec.push_back( cell_idx_c(6), cell_idx_c(2), cell_idx_c(i) );
-   for( auto c = cellVec.begin(); c != cellVec.end(); ++c )
+   for(auto & c : cellVec)
    {
-      flagField_Ref.addFlag( c->x(), c->y(), c->z(), addFlag );
-      factorField_Ref( c->x(), c->y(), c->z() ) = uint_c(5);
+      flagField_Ref.addFlag( c.x(), c.y(), c.z(), addFlag );
+      factorField_Ref( c.x(), c.y(), c.z() ) = uint_c(5);
    }
    handling.setBoundary( add, cellVec.begin(), cellVec.end(), AddBoundary::Configuration( uint_c(5) ) );
 
    cellSet.clear();
    for( uint_t i = 1; i != 4; ++i )
       cellSet.insert( cell_idx_c(6), cell_idx_c(3), cell_idx_c(i) );
-   for( auto c = cellSet.begin(); c != cellSet.end(); ++c )
+   for(auto c : cellSet)
    {
-      flagField_Ref.addFlag( c->x(), c->y(), c->z(), copyFlag2 );
-      registeredCells.push_back( c->x(), c->y(), c->z() );
+      flagField_Ref.addFlag( c.x(), c.y(), c.z(), copyFlag2 );
+      registeredCells.push_back( c.x(), c.y(), c.z() );
    }
    handling.setBoundary( copyFlag2, cellSet.begin(), cellSet.end() );
 
@@ -679,20 +679,20 @@ static int main( int argc, char **argv )
    // forceBoundary - interval
 
    cells = CellInterval( cell_idx_c(8), cell_idx_c(3), cell_idx_c(-1), cell_idx_c(8), cell_idx_c(3), cell_idx_c(8) );
-   for( auto c = cells.begin(); c != cells.end(); ++c )
+   for(auto c : cells)
    {
-      clear( c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, unregisteredCells );
-      flagField_Ref.addFlag( c->x(), c->y(), c->z(), addFlag );
-      factorField_Ref( c->x(), c->y(), c->z() ) = uint_c(5);
+      clear( c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, unregisteredCells );
+      flagField_Ref.addFlag( c.x(), c.y(), c.z(), addFlag );
+      factorField_Ref( c.x(), c.y(), c.z() ) = uint_c(5);
    }
    handling.forceBoundary( add, cells, AddBoundary::Configuration( uint_c(5) ) );
 
    cells = CellInterval( cell_idx_c(8), cell_idx_c(4), cell_idx_c(4), cell_idx_c(8), cell_idx_c(5), cell_idx_c(8) );
-   for( auto c = cells.begin(); c != cells.end(); ++c )
+   for(auto c : cells)
    {
-      clear( c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, unregisteredCells );
-      flagField_Ref.addMask( c->x(), c->y(), c->z(), copyFlag1 );
-      registeredCells.push_back( c->x(), c->y(), c->z() );
+      clear( c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, unregisteredCells );
+      flagField_Ref.addMask( c.x(), c.y(), c.z(), copyFlag1 );
+      registeredCells.push_back( c.x(), c.y(), c.z() );
    }
    handling.forceBoundary( copyFlag1, cells );
 
@@ -701,22 +701,22 @@ static int main( int argc, char **argv )
    cellVec.clear();
    for( uint_t i = 1; i != 4; ++i )
       cellVec.push_back( cell_idx_c(10), cell_idx_c(i), cell_idx_c(3) );
-   for( auto c = cellVec.begin(); c != cellVec.end(); ++c )
+   for(auto & c : cellVec)
    {
-      clear( c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, unregisteredCells );
-      flagField_Ref.addFlag( c->x(), c->y(), c->z(), addFlag );
-      factorField_Ref( c->x(), c->y(), c->z() ) = uint_c(23);
+      clear( c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, unregisteredCells );
+      flagField_Ref.addFlag( c.x(), c.y(), c.z(), addFlag );
+      factorField_Ref( c.x(), c.y(), c.z() ) = uint_c(23);
    }
    handling.forceBoundary( add, cellVec.begin(), cellVec.end(), AddBoundary::Configuration( uint_c(23) ) );
 
    cellSet.clear();
    for( uint_t i = 1; i != 6; ++i )
       cellSet.insert( cell_idx_c(10), cell_idx_c(2), cell_idx_c(i) );
-   for( auto c = cellSet.begin(); c != cellSet.end(); ++c )
+   for(auto c : cellSet)
    {
-      clear( c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, unregisteredCells );
-      flagField_Ref.addFlag( c->x(), c->y(), c->z(), copyFlag1 );
-      registeredCells.push_back( c->x(), c->y(), c->z() );
+      clear( c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, unregisteredCells );
+      flagField_Ref.addFlag( c.x(), c.y(), c.z(), copyFlag1 );
+      registeredCells.push_back( c.x(), c.y(), c.z() );
    }
    handling.forceBoundary( copyFlag1, cellSet.begin(), cellSet.end() );
 
@@ -760,13 +760,13 @@ static int main( int argc, char **argv )
    // removeBoundary - interval
 
    cells = CellInterval( cell_idx_c(4), cell_idx_c(-1), cell_idx_c(-1), cell_idx_c(4), cell_idx_c(2), cell_idx_c(5) );
-   for( auto c = cells.begin(); c != cells.end(); ++c )
-      remove( numeric_cast<flag_t>( copyFlag1 | copyFlag2 | addFlag ), c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, add, unregisteredCells );
+   for(auto c : cells)
+      remove( numeric_cast<flag_t>( copyFlag1 | copyFlag2 | addFlag ), c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, add, unregisteredCells );
    handling.removeBoundary( cells );
 
    cells = CellInterval( cell_idx_c(4), cell_idx_c(3), cell_idx_c(4), cell_idx_c(4), cell_idx_c(5), cell_idx_c(8) );
-   for( auto c = cells.begin(); c != cells.end(); ++c )
-      remove( numeric_cast<flag_t>( copyFlag1 | copyFlag2 ), c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, add, unregisteredCells );
+   for(auto c : cells)
+      remove( numeric_cast<flag_t>( copyFlag1 | copyFlag2 ), c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, add, unregisteredCells );
    handling.removeBoundary( numeric_cast<flag_t>( copyFlag1 | copyFlag2 ), cells );
 
    // removeBoundary - iterators
@@ -774,15 +774,15 @@ static int main( int argc, char **argv )
    cellVec.clear();
    for( uint_t i = 1; i != 4; ++i )
       cellVec.push_back( cell_idx_c(6), cell_idx_c(2), cell_idx_c(i) );
-   for( auto c = cellVec.begin(); c != cellVec.end(); ++c )
-      remove( addFlag, c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, add, unregisteredCells );
+   for(auto & c : cellVec)
+      remove( addFlag, c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, add, unregisteredCells );
    handling.removeBoundary( add, cellVec.begin(), cellVec.end() );
 
    cellSet.clear();
    for( uint_t i = 1; i != 4; ++i )
       cellSet.insert( cell_idx_c(6), cell_idx_c(3), cell_idx_c(i) );
-   for( auto c = cellSet.begin(); c != cellSet.end(); ++c )
-      remove( numeric_cast<flag_t>( copyFlag1 | copyFlag2 | addFlag ), c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, add, unregisteredCells );
+   for(auto c : cellSet)
+      remove( numeric_cast<flag_t>( copyFlag1 | copyFlag2 | addFlag ), c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, add, unregisteredCells );
    handling.removeBoundary( cellSet.begin(), cellSet.end() );
 
    resetNearFlags( flagField_Ref, domain1, domain2, near, copy1, copy2, add );
@@ -819,27 +819,27 @@ static int main( int argc, char **argv )
    handling.clear( cell.x(), cell.y(), cell.z() );
 
    cells = CellInterval( cell_idx_c(8), cell_idx_c(3), cell_idx_c(4), cell_idx_c(8), cell_idx_c(3), cell_idx_c(8) );
-   for( auto c = cells.begin(); c != cells.end(); ++c )
-      clear( c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, unregisteredCells );
+   for(auto c : cells)
+      clear( c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, unregisteredCells );
    handling.clear( cells );
 
    cells = CellInterval( cell_idx_c(8), cell_idx_c(5), cell_idx_c(4), cell_idx_c(8), cell_idx_c(5), cell_idx_c(8) );
-   for( auto c = cells.begin(); c != cells.end(); ++c )
-      clear( c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, unregisteredCells );
+   for(auto c : cells)
+      clear( c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, unregisteredCells );
    handling.clear( cells );
 
    cellVec.clear();
    for( uint_t i = 0; i != 3; ++i )
       cellVec.push_back( cell_idx_c(10), cell_idx_c(i), cell_idx_c(3) );
-   for( auto c = cellVec.begin(); c != cellVec.end(); ++c )
-      clear( c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, unregisteredCells );
+   for(auto & c : cellVec)
+      clear( c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, unregisteredCells );
    handling.clear( cellVec.begin(), cellVec.end() );
 
    cellSet.clear();
    for( uint_t i = 0; i != 4; ++i )
       cellSet.insert( cell_idx_c(10), cell_idx_c(2), cell_idx_c(i) );
-   for( auto c = cellSet.begin(); c != cellSet.end(); ++c )
-      clear( c->x(), c->y(), c->z(), flagField_Ref, copy1, copy2, unregisteredCells );
+   for(auto c : cellSet)
+      clear( c.x(), c.y(), c.z(), flagField_Ref, copy1, copy2, unregisteredCells );
    handling.clear( cellSet.begin(), cellSet.end() );
 
    resetNearFlags( flagField_Ref, domain1, domain2, near, copy1, copy2, add );
diff --git a/tests/core/FunctionTraitsTest.cpp b/tests/core/FunctionTraitsTest.cpp
index dc503f2db3df10f911fe2df14d7accbe0a800524..020a6732632524c85b21319bf7b560ee66ec5a84 100644
--- a/tests/core/FunctionTraitsTest.cpp
+++ b/tests/core/FunctionTraitsTest.cpp
@@ -30,16 +30,16 @@ template< typename F>
 struct SomeClass
 {
    template< typename T>
-   static bool checkParameter1( typename std::enable_if< (FunctionTraits<F>::arity > 1 ), T >::type * = nullptr) {
+   static bool checkParameter1( std::enable_if_t< (FunctionTraits<F>::arity > 1 ), T > * = nullptr) {
 
       // The keyword "template" before "argument<1>" is crucial when these functions are inside a class. If the
       // keyword is dropped, compilers interpret "<1" as an arithmetic expression and therefore throw errors.
-      typedef typename FunctionTraits<F>::template argument<1>::type argType;
-      return std::is_same< T, argType >::value;
+      using argType = typename FunctionTraits<F>::template argument<1>::type;
+      return std::is_same_v< T, argType >;
    }
 
    template< typename T>
-   static bool checkParameter1( typename std::enable_if< (FunctionTraits<F>::arity <= 1 ), T >::type * = 0) {
+   static bool checkParameter1( std::enable_if_t< (FunctionTraits<F>::arity <= 1 ), T > * = 0) {
       return false;
    }
 
@@ -51,10 +51,10 @@ int main( int /*argc*/, char** /*argv*/ )
    debug::enterTestMode();
 
    // obtain a function pointer's type
-   typedef typename std::remove_pointer< bool (*)(int, float, double) >::type FuncType;
+   using FuncType = std::remove_pointer_t<bool (*)(int, float, double)>;
 
    // check return type
-   constexpr auto retTypeEqual = std::is_same< FunctionTraits<FuncType>::return_type, bool>::value;
+   constexpr auto retTypeEqual = std::is_same_v< FunctionTraits<FuncType>::return_type, bool>;
    WALBERLA_CHECK( retTypeEqual );
 
    // check arity
@@ -62,13 +62,13 @@ int main( int /*argc*/, char** /*argv*/ )
    WALBERLA_CHECK_EQUAL( argNumber, 3 );
 
    // check argument types
-   constexpr auto arg0TypeEqual = std::is_same< FunctionTraits<FuncType>::argument<0>::type, int >::value;
+   constexpr auto arg0TypeEqual = std::is_same_v< FunctionTraits<FuncType>::argument<0>::type, int >;
    WALBERLA_CHECK ( arg0TypeEqual );
 
-   constexpr auto arg1TypeEqual = std::is_same< FunctionTraits<FuncType>::argument<1>::type, float >::value;
+   constexpr auto arg1TypeEqual = std::is_same_v< FunctionTraits<FuncType>::argument<1>::type, float >;
    WALBERLA_CHECK ( arg1TypeEqual );
 
-   constexpr auto arg2TypeEqual = std::is_same< FunctionTraits<FuncType>::argument<2>::type, double >::value;
+   constexpr auto arg2TypeEqual = std::is_same_v< FunctionTraits<FuncType>::argument<2>::type, double >;
    WALBERLA_CHECK ( arg2TypeEqual );
 
    // check usage inside class
diff --git a/tests/core/SetTest.cpp b/tests/core/SetTest.cpp
index 5c46ded40ffb0722c565e9af209087de6af425d7..ebd249153086a816b6194b6f5ed7e881200ac86f 100644
--- a/tests/core/SetTest.cpp
+++ b/tests/core/SetTest.cpp
@@ -86,11 +86,11 @@ int main( int /*argc*/, char** /*argv*/ ) {
    result.insert( A.begin(), A.end() );
    WALBERLA_CHECK_EQUAL( result, expected );
 
-   result   = A & A;
+   result   = A & A; // NOLINT: represent zero difference
    expected = Set<int>(1) + Set<int>(2) + Set<int>(3) + Set<int>(4);
    WALBERLA_CHECK_EQUAL( result, expected );
 
-   result   = A - A;
+   result   = A - A; // NOLINT: represent zero difference
    expected = Set<int>::emptySet();
    WALBERLA_CHECK_EQUAL( result, expected );
 
diff --git a/tests/core/cell/CellIntervalTest.cpp b/tests/core/cell/CellIntervalTest.cpp
index fe0035feec169c5dd3399c63a27c96a0e51764de..29a1cf56f0a8b7460c5e33f947f8e3ed4f91e0ad 100644
--- a/tests/core/cell/CellIntervalTest.cpp
+++ b/tests/core/cell/CellIntervalTest.cpp
@@ -30,7 +30,8 @@
 
 using namespace walberla;
 
-typedef std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 > mt11213b;
+using mt11213b = std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7,
+                                               0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 >;
 
 CellInterval makeRandomInterval(uint_t maxSize)
 {
@@ -46,7 +47,7 @@ CellInterval makeRandomInterval(uint_t maxSize)
    cell_idx_t yMax = yMin + cell_idx_c( dist2(rng) );
    cell_idx_t zMax = zMin + cell_idx_c( dist2(rng) );
 
-   return CellInterval(xMin, yMin, zMin, xMax, yMax, zMax);
+   return { xMin, yMin, zMin, xMax, yMax, zMax };
 }
 
 CellInterval makeRandomEmptyInterval(uint_t maxSize)
@@ -77,14 +78,14 @@ CellInterval makeRandomEmptyInterval(uint_t maxSize)
    cell_idx_t yMax = yMin + ( yNegative ? - cell_idx_c( dist2(rng) ) : cell_idx_c( dist2(rng) ) );
    cell_idx_t zMax = zMin + ( zNegative ? - cell_idx_c( dist2(rng) ) : cell_idx_c( dist2(rng) ) );
 
-   return CellInterval(xMin, yMin, zMin, xMax, yMax, zMax);
+   return { xMin, yMin, zMin, xMax, yMax, zMax };
 }
 
 Cell makeRandomCell()
 {
    static mt11213b rng;
    std::uniform_int_distribution<cell_idx_t> dist( std::numeric_limits<cell_idx_t>::min(), std::numeric_limits<cell_idx_t>::max() );
-   return Cell( dist(rng), dist(rng), dist(rng) );
+   return { dist(rng), dist(rng), dist(rng) };
 }
 
 inline void testCI( const CellInterval & ci )
diff --git a/tests/core/cell/CellTest.cpp b/tests/core/cell/CellTest.cpp
index 59fc28c0081f31a7b0657a413b916429aef7410e..e5229a86cfcf5a421ef387489a239daaa5f94985 100644
--- a/tests/core/cell/CellTest.cpp
+++ b/tests/core/cell/CellTest.cpp
@@ -53,7 +53,7 @@ void testCell( cell_idx_t x, cell_idx_t y, cell_idx_t z )
    tmp += c;
    WALBERLA_CHECK_EQUAL( tmp, sum );
 
-   Cell difference = c - c;
+   Cell difference = c - c; // NOLINT: represent zero difference
    WALBERLA_CHECK_EQUAL( difference.x(), cell_idx_t(0) );
    WALBERLA_CHECK_EQUAL( difference.y(), cell_idx_t(0) );
    WALBERLA_CHECK_EQUAL( difference.z(), cell_idx_t(0) );
@@ -194,7 +194,7 @@ int main( int /*argc*/, char** /*argv*/ ) {
 
    debug::enterTestMode();
 
-   typedef std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 > mt11213b;
+   using mt11213b = std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 >;
    mt11213b rng;
    std::uniform_int_distribution<cell_idx_t> dist( std::numeric_limits<cell_idx_t>::min(), std::numeric_limits<cell_idx_t>::max() );
 
diff --git a/tests/core/load_balancing/ParMetisTest.cpp b/tests/core/load_balancing/ParMetisTest.cpp
index b0d9f578e281e3d17ee0c4e6308664ec8013822d..64f8b65c1376fdbc7bff757aa3d1c06e58ada682 100644
--- a/tests/core/load_balancing/ParMetisTest.cpp
+++ b/tests/core/load_balancing/ParMetisTest.cpp
@@ -102,10 +102,10 @@ int main( int argc, char * argv[] )
    scheme.addPackInfo( make_shared< field::communication::PackInfo< FieldType > >( domainId ) );
    scheme();
 
-   std::vector< int64_t > vtxdist;
-   for( int i = 0; i < MPIManager::instance()->numProcesses() + 1; ++i )
+   std::vector< int64_t > vtxdist(uint_c(MPIManager::instance()->numProcesses()) + 1);
+   for (uint_t i = 0; i < uint_c(MPIManager::instance()->numProcesses()) + 1; ++i)
    {
-      vtxdist.push_back( int64_c(i) * int64_c( fieldSize[0] * fieldSize[1] ) );
+      vtxdist[i] = int64_c(i) * int64_c(fieldSize[0] * fieldSize[1]);
    }
 
    int64_t ncon  = int64_t(1);
@@ -130,13 +130,13 @@ int main( int argc, char * argv[] )
    int64_t nparts = int64_c( partitions );
    std::vector< double > tpwgts( partitions, 1.0 / numeric_cast<double>( partitions ) );
    std::vector< double > ubvec( numeric_cast<size_t>(ncon), 1.05 );
-   int64_t options[] = {0,0,0};
+   std::array< int64_t, 3 > options = { 0, 0, 0 };
    int64_t edgecut;
    std::vector< int64_t > part( fieldSize[0] * fieldSize[1] );
    MPI_Comm comm = MPIManager::instance()->comm();
 
    int result = core::ParMETIS_V3_PartKway( &(vtxdist.front()), &(xadj.front()), &(adjncy.front()), nullptr, nullptr, &wgtflag, &numflag, &ncon, &nparts,
-                                            &(tpwgts.front()), &(ubvec.front()), options, &edgecut, &(part.front()), &comm );
+                                            &(tpwgts.front()), &(ubvec.front()), options.data(), &edgecut, &(part.front()), &comm );
 
 
    WALBERLA_CHECK_EQUAL( result, core::METIS_OK );  
diff --git a/tests/core/load_balancing/PlainParMetisTest.cpp b/tests/core/load_balancing/PlainParMetisTest.cpp
index 3da514b38451c70db287b216e76ea7a78b634da0..7ed8321963ff23efac16e2a914857b7b2f31e3c9 100644
--- a/tests/core/load_balancing/PlainParMetisTest.cpp
+++ b/tests/core/load_balancing/PlainParMetisTest.cpp
@@ -165,29 +165,29 @@ int main( int argc, char * argv[] )
    std::vector< double > tpwgts( static_cast<size_t>(nparts), 1.0 / static_cast<double>( nparts ) );
    std::vector< double > ubvec(  static_cast<size_t>(ncon), 1.05 );
    double  ipc2redist =  1.0;
-   int64_t options[] = {0,0,0};
+   std::array< int64_t, 3 > options = { 0, 0, 0 };
    int64_t edgecut;
    std::vector< int64_t > part( numVertices );
    MPI_Comm comm = MPI_COMM_WORLD;
 
    std::cout << "ParMETIS_V3_PartKway" << std::endl;
    WALBERLA_CHECK_EQUAL( ParMETIS_V3_PartKway( &(vtxdist.front()), &(xadj.front()), &(adjncy.front()), nullptr, nullptr, &wgtflag, &numflag, &ncon, &nparts,
-                                &(tpwgts.front()), &(ubvec.front()), options, &edgecut, &(part.front()), &comm ),
+                                &(tpwgts.front()), &(ubvec.front()), options.data(), &edgecut, &(part.front()), &comm ),
                          METIS_OK );
    std::cout << "ParMETIS_V3_PartGeomKway" << std::endl;
    WALBERLA_CHECK_EQUAL( ParMETIS_V3_PartGeomKway( &(vtxdist.front()), &(xadj.front()), &(adjncy.front()), nullptr, nullptr, &wgtflag, &numflag, &ndims, &(xyz.front()), &ncon, &nparts,
-                                &(tpwgts.front()), &(ubvec.front()), options, &edgecut, &(part.front()), &comm ),
+                                &(tpwgts.front()), &(ubvec.front()), options.data(), &edgecut, &(part.front()), &comm ),
                          METIS_OK );
    std::cout << "ParMETIS_V3_PartGeom" << std::endl;
    WALBERLA_CHECK_EQUAL( ParMETIS_V3_PartGeom( &(vtxdist.front()), &ndims, &(xyz.front()), &(part.front()), &comm ),
                          METIS_OK );
    std::cout << "ParMETIS_V3_AdaptiveRepart" << std::endl;
    WALBERLA_CHECK_EQUAL( ParMETIS_V3_AdaptiveRepart( &(vtxdist.front()), &(xadj.front()), &(adjncy.front()), nullptr, nullptr, nullptr, &wgtflag, &numflag, &ncon, &nparts,
-                                &(tpwgts.front()), &(ubvec.front()), &ipc2redist, options, &edgecut, &(part.front()), &comm ),
+                                &(tpwgts.front()), &(ubvec.front()), &ipc2redist, options.data(), &edgecut, &(part.front()), &comm ),
                          METIS_OK );
    std::cout << "ParMETIS_V3_RefineKway" << std::endl;
    WALBERLA_CHECK_EQUAL( ParMETIS_V3_RefineKway( &(vtxdist.front()), &(xadj.front()), &(adjncy.front()), nullptr, nullptr, &wgtflag, &numflag, &ncon, &nparts,
-                                &(tpwgts.front()), &(ubvec.front()), options, &edgecut, &(part.front()), &comm ),
+                                &(tpwgts.front()), &(ubvec.front()), options.data(), &edgecut, &(part.front()), &comm ),
                          METIS_OK );
 
    MPI_Finalize();
diff --git a/tests/core/math/GenericAABBTest.cpp b/tests/core/math/GenericAABBTest.cpp
index f1d386ade803ce23909bf47a5df4f6b1307618d2..d64705d217665ee560d6ba3297ec665a0a38b519 100644
--- a/tests/core/math/GenericAABBTest.cpp
+++ b/tests/core/math/GenericAABBTest.cpp
@@ -530,7 +530,7 @@ void testConstructors( const T x0, const T y0, const T z0, const T x1, const T y
 template< typename T >
 void randomTest()
 {
-   typedef std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 > mt11213b;
+   using mt11213b = std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 >;
    mt11213b rng;
 
    std::uniform_real_distribution<T> dist( -T(10), T(10) );
diff --git a/tests/core/math/PlaneTest.cpp b/tests/core/math/PlaneTest.cpp
index 6c0a49a95886e62d830f782f2c91ee0fbb49c2a8..5e47174b6c5b18d5cdb68c3f8cb89365f81cddec 100644
--- a/tests/core/math/PlaneTest.cpp
+++ b/tests/core/math/PlaneTest.cpp
@@ -38,7 +38,8 @@ template < typename scalar_t >
 struct RandomPointGenerator
 {
    using vector_t = walberla::Vector3<scalar_t>;
-   typedef std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 > mt11213b;
+   using mt11213b = std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7,
+                                                  0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 >;
    using RandomNumberEngine = mt11213b;
    using NormalDistribution = std::normal_distribution<scalar_t>;
 
diff --git a/tests/core/math/PrimesTest.cpp b/tests/core/math/PrimesTest.cpp
index 141a9704ba2670a11bba4e8d3e342232b2d49c0f..ce463a6add42fe812f648f86ae342b7311e054f9 100644
--- a/tests/core/math/PrimesTest.cpp
+++ b/tests/core/math/PrimesTest.cpp
@@ -52,19 +52,19 @@ void runTests( const uint_t n )
       WALBERLA_CHECK_EQUAL( n % i == 0, devisors.find( i ) != devisors.end() );
    }
 
-   for( auto it = primes.begin(); it != primes.end(); ++it )
-      WALBERLA_CHECK( math::isPrime( *it ) );
+   for(unsigned long & prime : primes)
+      WALBERLA_CHECK( math::isPrime( prime ) );
 
-   for( auto it = devisors.begin(); it != devisors.end(); ++it )
-      WALBERLA_CHECK( n % *it == 0 );
+   for(unsigned long devisor : devisors)
+      WALBERLA_CHECK( n % devisor == 0 );
 
    if( n != 0 )
    {
       auto primeFactors = math::getPrimeFactors(n);
       WALBERLA_CHECK( ::is_sorted( primeFactors.begin(), primeFactors.end() ) );
       WALBERLA_CHECK_EQUAL( n, std::accumulate( primeFactors.begin(), primeFactors.end(), uint_c(1), std::multiplies<uint_t>() ) );
-      for( auto it = primeFactors.begin(); it != primeFactors.end(); ++it )
-         WALBERLA_CHECK( math::isPrime(*it) );
+      for(unsigned long & primeFactor : primeFactors)
+         WALBERLA_CHECK( math::isPrime(primeFactor) );
    }
 }
 
@@ -84,7 +84,7 @@ int main(int argc, char * argv[])
       runTests( n );
    }
 
-   typedef std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 > mt11213b;
+   using mt11213b = std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 >;
    mt11213b rng;
    std::uniform_int_distribution<uint_t> dist( 100, 10000 );
    for(int i = 0; i < 100; ++i)
diff --git a/tests/core/mpi/SetReductionTest.cpp b/tests/core/mpi/SetReductionTest.cpp
index 03822b995adf3c6482733fc3c9b53328d3c5cdc7..cf76d8e56b0a9926f56567a4de2b1ceb60ed1f2e 100644
--- a/tests/core/mpi/SetReductionTest.cpp
+++ b/tests/core/mpi/SetReductionTest.cpp
@@ -60,9 +60,9 @@ void testRankSet()
    WALBERLA_CHECK_EQUAL( reducedSetUnion.size(), numberOfRanks );
 
    int ctr = 0;
-   for( auto it = reducedSetUnion.begin(); it != reducedSetUnion.end(); ++it )
+   for (auto & reducedRank : reducedSetUnion)
    {
-      WALBERLA_CHECK_EQUAL( *it, ctr );
+      WALBERLA_CHECK_EQUAL( reducedRank, ctr );
       ++ctr;
    }
    
@@ -91,7 +91,7 @@ void testRankSet()
 }
 
 static const int         NUM_FRUITS = 5;
-static const std::string FRUITS[] = { "apple", "banana", "pear", "melon", "grapefruit" };
+static const std::array< std::string, 5 > FRUITS = { "apple", "banana", "pear", "melon", "grapefruit" };
 
 void testStrings()
 {
@@ -99,7 +99,7 @@ void testStrings()
    int numProcesses = mpi::MPIManager::instance()->numProcesses();
    
    std::vector< std::string > values;
-   values.push_back( FRUITS[rank % NUM_FRUITS] );
+   values.push_back( FRUITS[size_t(rank % NUM_FRUITS)] );
 
    std::vector< std::string > reducedValuesUnion = mpi::allReduceSet( values, mpi::UNION );
 
@@ -124,7 +124,7 @@ void testStrings()
    //WALBERLA_LOG_DEVEL( oss.str() );
 
    int numberOfProcesses = mpi::MPIManager::instance()->numProcesses();
-   std::vector< std::string > expectedSet( FRUITS, FRUITS + std::min( numberOfProcesses, NUM_FRUITS ) );
+   std::vector< std::string > expectedSet(FRUITS.data(), FRUITS.data() + std::min(numberOfProcesses, NUM_FRUITS));
    std::sort( expectedSet.begin(), expectedSet.end() );
 
    WALBERLA_CHECK_EQUAL( reducedValuesUnion.size(), expectedSet.size() );
diff --git a/tests/core/selectable/SetSelectableObjectTest.cpp b/tests/core/selectable/SetSelectableObjectTest.cpp
index 7e3ffec4a7d0146d2c704a79c257d7a9d6725bf1..e084035f1720364e962ef10be29b4aaeef845eb9 100644
--- a/tests/core/selectable/SetSelectableObjectTest.cpp
+++ b/tests/core/selectable/SetSelectableObjectTest.cpp
@@ -129,8 +129,8 @@ int main( int /*argc*/, char** /*argv*/ ) {
    WALBERLA_CHECK_EQUAL( function, expected[0] );
 
    functions.clear();
-   for( auto it = container.begin(); it != container.end(); ++it )
-      functions.push_back( *it );
+   for(auto & it : container)
+      functions.push_back( it );
 
    expected.clear();
    expected.emplace_back("function_1");
diff --git a/tests/field/AccuracyEvaluationTest.cpp b/tests/field/AccuracyEvaluationTest.cpp
index c7656509fbdf86324d345f76bc027c6f90d2050f..8ffe9477ff7b50ba4def146b013108d9019855e0 100644
--- a/tests/field/AccuracyEvaluationTest.cpp
+++ b/tests/field/AccuracyEvaluationTest.cpp
@@ -38,8 +38,8 @@ namespace accuracy_evaluation_test {
    
 using namespace walberla;
 
-typedef field::GhostLayerField< real_t, 1 >           ScalarField_T;
-typedef field::GhostLayerField< Vector3<real_t>, 1 >  VectorField_T;
+using ScalarField_T = field::GhostLayerField<real_t, 1>;
+using VectorField_T = field::GhostLayerField<Vector3<real_t>, 1>;
 
 const real_t          scalarValue( real_c(23) );
 const Vector3<real_t> vectorValue( real_c(23), real_c(42), real_c(5) );
@@ -56,7 +56,7 @@ Vector3<real_t> vectorSolution( const Vector3<real_t> & )
 }
 
 
-int main( int argc, char* argv[] )
+int main( int argc, char** argv )
 {
    debug::enterTestMode();
 
diff --git a/tests/field/AddToStorageTest.cpp b/tests/field/AddToStorageTest.cpp
index 3f5a47f6e6722331cc77e4a5a01958af8d622214..272f432b2b5500cf0b251b220de9cd60039ba65b 100644
--- a/tests/field/AddToStorageTest.cpp
+++ b/tests/field/AddToStorageTest.cpp
@@ -40,8 +40,8 @@ int main( int argc, char ** argv )
                                                        1.0,           // dx
                                                        false
                                                        );
-   typedef GhostLayerField<Vector3<uint_t>,1> VectorField;
-   typedef GhostLayerField<uint_t, 3> FlattenedField;
+   using VectorField = GhostLayerField<Vector3<uint_t>, 1>;
+   using FlattenedField = GhostLayerField<uint_t, 3>;
    BlockDataID fieldID = field::addToStorage<VectorField>( blocks, "Field", Vector3<uint_t>(uint_c(0)), field::zyxf );
    BlockDataID flattenedID = field::addFlattenedShallowCopyToStorage<VectorField>( blocks, fieldID, "flattened Field");
 
diff --git a/tests/field/FieldFileIOTest.cpp b/tests/field/FieldFileIOTest.cpp
index 8559deacfd9f9a0eb567f5c276e241b0df451fd7..504b0f8f7cfa8598bad83faa927e8716087497c2 100644
--- a/tests/field/FieldFileIOTest.cpp
+++ b/tests/field/FieldFileIOTest.cpp
@@ -56,16 +56,16 @@ static void workloadMemorySUIDAssignmentFunction(SetupBlockForest& forest)
    std::vector< SetupBlock* > blocks;
    forest.getBlocks(blocks);
 
-   for (uint_t i = 0; i != blocks.size(); ++i)
+   for (auto & block : blocks)
    {
-      blocks[i]->setMemory(1.0);
-      blocks[i]->setWorkload(1.0);
+      block->setMemory(1.0);
+      block->setWorkload(1.0);
    }
 }
 
-void test(int argc, char* argv[])
+void test(int argc, char** argv)
 {
-   typedef field::GhostLayerField< double, 3 > FieldType;
+   using FieldType = field::GhostLayerField<double, 3>;
 
    std::vector< std::string > args(argv, argv + argc);
 
diff --git a/tests/field/FieldGatherTest.cpp b/tests/field/FieldGatherTest.cpp
index 5e0aacc5796a9aa5a92e94725ecb8c85176da4a9..4e943449637610923c8737421331815f7e464b57 100644
--- a/tests/field/FieldGatherTest.cpp
+++ b/tests/field/FieldGatherTest.cpp
@@ -42,7 +42,7 @@ int main( int argc, char ** argv )
                                                        1.0,           // dx
                                                        oneBlockPerProcess
                                                        );
-   typedef GhostLayerField<cell_idx_t,3> MyField;
+   using MyField = GhostLayerField<cell_idx_t, 3>;
    BlockDataID fieldID = field::addToStorage<MyField>( blocks, "Field" );
 
 
diff --git a/tests/field/FieldMPIDatatypesTest.cpp b/tests/field/FieldMPIDatatypesTest.cpp
index 0eba715567a53e2edd773b05344d7453978d5602..8c70a07f2237ed986384c2732959ba49440cd475 100644
--- a/tests/field/FieldMPIDatatypesTest.cpp
+++ b/tests/field/FieldMPIDatatypesTest.cpp
@@ -104,7 +104,7 @@ void testOctantCopy( const SourceField & src, TargetField & dst )
    cell_idx_t yMid = fullInterval.yMin() + cell_idx_t( fullInterval.ySize() ) / cell_idx_t( 2 );
    cell_idx_t zMid = fullInterval.zMin() + cell_idx_t( fullInterval.ySize() ) / cell_idx_t( 2 );
 
-   CellInterval octants[] = {
+   std::array<CellInterval, 8> octants = {
       CellInterval( fullInterval.xMin(),  fullInterval.yMin(),  fullInterval.zMin(),  xMid,                 yMid,                 zMid                ),
       CellInterval( fullInterval.xMin(),  fullInterval.yMin(),  zMid + cell_idx_t(1), xMid,                 yMid,                 fullInterval.zMax() ),
       CellInterval( fullInterval.xMin(),  yMid + cell_idx_t(1), fullInterval.zMin(),  xMid,                 fullInterval.yMax(),  zMid                ),
@@ -117,10 +117,10 @@ void testOctantCopy( const SourceField & src, TargetField & dst )
 
    WALBERLA_CHECK( src != dst );
 
-   for( auto it = octants; it != octants + 8; ++it )
+   for( const auto& it : octants )
    {
-      MPI_Datatype srcType = mpiDatatypeSliceXYZ( src, *it, cell_idx_t( 0 ), cell_idx_c( src.fSize() ) - cell_idx_t( 1 ) );
-      MPI_Datatype dstType = mpiDatatypeSliceXYZ( dst, *it, cell_idx_t( 0 ), cell_idx_c( dst.fSize() ) - cell_idx_t( 1 ) );
+      MPI_Datatype srcType = mpiDatatypeSliceXYZ( src, it, cell_idx_t( 0 ), cell_idx_c( src.fSize() ) - cell_idx_t( 1 ) );
+      MPI_Datatype dstType = mpiDatatypeSliceXYZ( dst, it, cell_idx_t( 0 ), cell_idx_c( dst.fSize() ) - cell_idx_t( 1 ) );
 
       MPI_Type_commit( &srcType );
       MPI_Type_commit( &dstType );
@@ -226,17 +226,17 @@ void testIntervalCopy( const SourceField & src, TargetField & dst, const CellInt
    MPI_Type_free( &dstType );
 
    CellInterval fieldInterval = src.xyzSize();
-   for( auto it = fieldInterval.begin(); it != fieldInterval.end(); ++it )
+   for(const auto& ival : fieldInterval)
    {
-      if( interval.contains( *it ) )
+      if( interval.contains( ival ) )
       {
          for( cell_idx_t f = fBeg; f <= fEnd; ++f )
-            WALBERLA_CHECK_IDENTICAL( src.get( *it, f ), dst.get( *it, f ) );
+            WALBERLA_CHECK_IDENTICAL( src.get( ival, f ), dst.get( ival, f ) );
       }
       else
       {
          for( cell_idx_t f = fBeg; f <= fEnd; ++f )
-            WALBERLA_CHECK_IDENTICAL( dst.get( *it, f ), numeric_cast< typename SourceField::value_type >( 0 ) );
+            WALBERLA_CHECK_IDENTICAL( dst.get( ival, f ), numeric_cast< typename SourceField::value_type >( 0 ) );
       }
    }
 }
@@ -523,7 +523,7 @@ void runTests( const Vector3<uint_t> & size )
    runTests< double >( size );
 }
 
-int main( int argc, char* argv[] )
+int main( int argc, char** argv )
 {
    debug::enterTestMode();
 
diff --git a/tests/field/FieldTest.cpp b/tests/field/FieldTest.cpp
index 3214a77490d11e77ec67e92bc3c9541381977037..b8588737dd9119798b6091257b78f243fd772ab0 100644
--- a/tests/field/FieldTest.cpp
+++ b/tests/field/FieldTest.cpp
@@ -108,7 +108,7 @@ void alignmentTest()
    const uint_t fs = 2;
 
    const uint_t alignment =64;
-   typedef field::AllocateAligned<short,alignment> Allocator;
+   using Allocator = field::AllocateAligned<short, alignment>;
    shared_ptr<Allocator> alloc = make_shared<Allocator>();
    Field<short,fs > field (xs,ys,zs,field::fzyx,alloc);
    for(cell_idx_t f=0; f < cell_idx_c( field.fSize() ); ++f )
@@ -130,7 +130,7 @@ void ghostLayerFieldAlignmentTest()
    const uint_t gl = 1;
 
    const uint_t alignment = 4 * sizeof( double );
-   typedef field::AllocateAligned<double,alignment> Allocator;
+   using Allocator = field::AllocateAligned<double, alignment>;
    shared_ptr<Allocator> alloc = make_shared<Allocator>();
    GhostLayerField<double,fs > field (xs,ys,zs,gl,field::fzyx,alloc);
    for(cell_idx_t f=0; f < cell_idx_c( field.fSize() ); ++f )
@@ -494,7 +494,7 @@ void isIteratorConsecutiveTest ( field::Layout layout )
 
 void swapableCompareTest ( )
 {
-   typedef Field<unsigned char, 1> MyField;
+   using MyField = Field<unsigned char, 1>;
    std::set<MyField*, field::SwapableCompare<MyField*> >  fieldSet;
 
    fieldSet.insert( new MyField(2,4,1, field::zyxf) );
@@ -507,18 +507,18 @@ void swapableCompareTest ( )
    fieldSet.insert( new MyField(1,2,2, field::fzyx) );
    fieldSet.insert( new MyField(1,2,3, field::fzyx) );
 
-   for ( auto i = fieldSet.begin(); i != fieldSet.end(); ++i )
+   for (auto i : fieldSet)
    {
-      std::cout << "( " << (*i)->xSize()
-                << ","  << (*i)->ySize()
-                << ","  << (*i)->zSize()
-                << ","  << (*i)->layout() << ")" << std::endl;
+      std::cout << "( " << i->xSize()
+                << ","  << i->ySize()
+                << ","  << i->zSize()
+                << ","  << i->layout() << ")" << std::endl;
 
    }
 
-   for ( auto i = fieldSet.begin(); i != fieldSet.end(); ++i )
+   for (auto i : fieldSet)
    {
-      delete *i;
+      delete i;
    }
 }
 
diff --git a/tests/field/FieldTiming.cpp b/tests/field/FieldTiming.cpp
index 283f0dc5fbf623ec1dd315ea3088f1e73cfcb4cb..b522153b4ac984dc5766231e61f4ad9e33e451d9 100644
--- a/tests/field/FieldTiming.cpp
+++ b/tests/field/FieldTiming.cpp
@@ -42,7 +42,7 @@ using std::stringstream;
 
 const uint_t fSize = 19;
 
-typedef Field<double,fSize > DoubleField;
+using DoubleField = Field<double, fSize>;
 
 
 double sumHandWritten(const DoubleField & field)
diff --git a/tests/field/adaptors/AdaptorTest.cpp b/tests/field/adaptors/AdaptorTest.cpp
index f18e70498829822ba7163a354129f0d524c1e5e8..1c1587dca6a95059577061bf0ec514e2c011980b 100644
--- a/tests/field/adaptors/AdaptorTest.cpp
+++ b/tests/field/adaptors/AdaptorTest.cpp
@@ -44,8 +44,8 @@ namespace walberla {
 using LatticeModel_T = lbm::D3Q19<lbm::collision_model::SRT>;
 
 using PdfField = lbm::PdfField<LatticeModel_T>;
-typedef GhostLayerField<real_t,1 >          ScalarField;
-typedef GhostLayerField<Vector3<real_t>,1 > VectorField;
+using ScalarField = GhostLayerField<real_t, 1>;
+using VectorField = GhostLayerField<Vector3<real_t>, 1>;
 
 
 template<typename Field_T>
@@ -105,7 +105,7 @@ void iteratorTest()
 
 void simpleTest()
 {
-   typedef GhostLayerField<real_t, 3> MyField;
+   using MyField = GhostLayerField<real_t, 3>;
 
    MyField field( 2, 2, 1, 2, 42 );
 
diff --git a/tests/field/codegen/CodegenJacobiCPU.cpp b/tests/field/codegen/CodegenJacobiCPU.cpp
index ffac6db84c0c1a477185bbe0593d8d682b03b214..3e36ddd08f5670ea0c26790044e4cf1ea3fe40b0 100644
--- a/tests/field/codegen/CodegenJacobiCPU.cpp
+++ b/tests/field/codegen/CodegenJacobiCPU.cpp
@@ -38,7 +38,7 @@
 
 using namespace walberla;
 
-typedef GhostLayerField<real_t, 1> ScalarField;
+using ScalarField = GhostLayerField<real_t, 1>;
 
 
 void testJacobi2D()
@@ -66,8 +66,8 @@ void testJacobi2D()
             f->get( x, y, 0 ) = real_c(1.0);
    }
 
-   typedef blockforest::communication::UniformBufferedScheme<stencil::D2Q9> CommScheme;
-   typedef field::communication::PackInfo<ScalarField> Packing;
+   using CommScheme = blockforest::communication::UniformBufferedScheme<stencil::D2Q9>;
+   using Packing = field::communication::PackInfo<ScalarField>;
    CommScheme commScheme(blocks);
    commScheme.addDataToCommunicate( make_shared<Packing>(fieldID) );
 
@@ -115,8 +115,8 @@ void testJacobi3D()
                f->get( x, y, z ) = real_c(1.0);
    }
 
-   typedef blockforest::communication::UniformBufferedScheme<stencil::D3Q7> CommScheme;
-   typedef field::communication::PackInfo<ScalarField> Packing;
+   using CommScheme = blockforest::communication::UniformBufferedScheme<stencil::D3Q7>;
+   using Packing = field::communication::PackInfo<ScalarField>;
    CommScheme commScheme(blocks);
    commScheme.addDataToCommunicate( make_shared<Packing>(fieldID) );
 
diff --git a/tests/field/codegen/CodegenPoissonCPU.cpp b/tests/field/codegen/CodegenPoissonCPU.cpp
index 582195ca4dbcb446dada56517ee1eda767476178..afb851593298a354738643c727352b6317847987 100644
--- a/tests/field/codegen/CodegenPoissonCPU.cpp
+++ b/tests/field/codegen/CodegenPoissonCPU.cpp
@@ -37,7 +37,7 @@
 
 using namespace walberla;
 
-typedef GhostLayerField<real_t, 1> ScalarField_T;
+using ScalarField_T = GhostLayerField<real_t, 1>;
 
 // U with Dirichlet Boundary
 void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockDataID & srcId )
@@ -49,10 +49,10 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
          ScalarField_T * src = block->getData< ScalarField_T >( srcId );
          CellInterval xyz = src->xyzSizeWithGhostLayer();
          xyz.yMin() = xyz.yMax();
-         for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+         for(const auto& cell : xyz)
          {
-            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
-            src->get( *cell ) = std::sin( math::pi * p[0] ) * std::sinh( math::pi * p[1] );
+            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
+            src->get( cell ) = std::sin( math::pi * p[0] ) * std::sinh( math::pi * p[1] );
          }
       }
    }
@@ -65,9 +65,9 @@ void initF( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
    {
       ScalarField_T * f = block->getData< ScalarField_T >( fId );
       CellInterval xyz = f->xyzSize();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(const auto& cell : xyz)
       {
-         f->get( *cell ) = real_c(0.0);
+         f->get( cell ) = real_c(0.0);
       }
    }
 }
@@ -98,8 +98,8 @@ void testPoisson()
    BlockDataID fId = field::addToStorage< ScalarField_T >( blocks, "f", real_c(0.0));
    initF( blocks, fId );
 
-   typedef blockforest::communication::UniformBufferedScheme<stencil::D2Q9> CommScheme;
-   typedef field::communication::PackInfo<ScalarField_T> Packing;
+   using CommScheme = blockforest::communication::UniformBufferedScheme<stencil::D2Q9>;
+   using Packing = field::communication::PackInfo<ScalarField_T>;
    CommScheme commScheme(blocks);
    commScheme.addDataToCommunicate( make_shared<Packing>(fieldID) );
 
diff --git a/tests/field/codegen/EK.cpp b/tests/field/codegen/EK.cpp
index 1f795b8730e159b4c138cacd59689949ddedc715..c719f0b27b35e1ffd34e5813a72a0844368573bb 100644
--- a/tests/field/codegen/EK.cpp
+++ b/tests/field/codegen/EK.cpp
@@ -38,8 +38,8 @@
 
 using namespace walberla;
 
-typedef GhostLayerField<real_t, 1> DensityField_T;
-typedef GhostLayerField<real_t, 2> FluxField_T;
+using DensityField_T = GhostLayerField<real_t, 1>;
+using FluxField_T = GhostLayerField<real_t, 2>;
 
 void initC(const shared_ptr< StructuredBlockStorage > & blocks, BlockDataID cID)
 {
@@ -117,8 +117,8 @@ void testEK()
    initC(blocks, c);
    BlockDataID j = field::addToStorage<FluxField_T>(blocks, "j", real_c(0.0), field::fzyx);
    
-   typedef blockforest::communication::UniformBufferedScheme<stencil::D2Q9> CommScheme;
-   typedef field::communication::PackInfo<DensityField_T> Packing;
+   using CommScheme = blockforest::communication::UniformBufferedScheme<stencil::D2Q9>;
+   using Packing = field::communication::PackInfo<DensityField_T>;
    CommScheme commScheme(blocks);
    commScheme.addDataToCommunicate( make_shared<Packing>(c) );
    
diff --git a/tests/field/codegen/MultipleFieldSwaps.cpp b/tests/field/codegen/MultipleFieldSwaps.cpp
index 5fa7eec874d414136481147a07ad966f65a8d87e..225cb8b5c0c425190739fa1951e5d8cb6d6aff61 100644
--- a/tests/field/codegen/MultipleFieldSwaps.cpp
+++ b/tests/field/codegen/MultipleFieldSwaps.cpp
@@ -32,7 +32,7 @@
 
 using namespace walberla;
 
-typedef GhostLayerField<real_t ,1> ScalarField;
+using ScalarField = GhostLayerField<real_t, 1>;
 void testMultipleFieldSwaps()
 {
    uint_t xSize = 5;
diff --git a/tests/field/codegen/SweepCollection.cpp b/tests/field/codegen/SweepCollection.cpp
index 33c8d2be099b9146d6738a5d7809023dbb7fa3b4..ad4da4e605d5a0debd1aff091c795d9ab7ebc6ca 100644
--- a/tests/field/codegen/SweepCollection.cpp
+++ b/tests/field/codegen/SweepCollection.cpp
@@ -30,7 +30,7 @@
 
 using namespace walberla;
 
-typedef GhostLayerField<real_t, 1> ScalarField;
+using ScalarField = GhostLayerField<real_t, 1>;
 using SweepCollection_T = pystencils::SweepCollection;
 
 void testSweepCollection()
diff --git a/tests/field/distributors/DistributionTest.cpp b/tests/field/distributors/DistributionTest.cpp
index a96429c326eb5ef49fb200d7b31ab7f78873f8d4..3be4782c5c104bce2d9504f7bb443ca84d7ee84a 100644
--- a/tests/field/distributors/DistributionTest.cpp
+++ b/tests/field/distributors/DistributionTest.cpp
@@ -41,9 +41,9 @@ const uint_t FieldGhostLayers( 1 );
 using flag_t = walberla::uint8_t;
 using FlagField_T = FlagField<flag_t>;
 
-typedef GhostLayerField< real_t, 1>          ScalarField_T;
-typedef GhostLayerField< Vector3<real_t>, 1> Vec3Field_T;
-typedef GhostLayerField< real_t, 3>          MultiComponentField_T;
+using ScalarField_T = GhostLayerField<real_t, 1>;
+using Vec3Field_T = GhostLayerField<Vector3<real_t>, 1>;
+using MultiComponentField_T = GhostLayerField<real_t, 3>;
 
 
 const FlagUID Domain_Flag ( "domain" );
@@ -126,11 +126,11 @@ void getScalarFieldQuantities( const shared_ptr<StructuredBlockStorage> & blocks
       auto domainFlag = flagField->getFlag( Domain_Flag );
 
       CellInterval xyzSizeWithGhostLayers = field->xyzSizeWithGhostLayer();
-      for( auto cellIt = xyzSizeWithGhostLayers.begin(); cellIt != xyzSizeWithGhostLayers.end(); ++cellIt )
+      for(const auto& cellIt : xyzSizeWithGhostLayers)
       {
-         if( flagField->isFlagSet(*cellIt,domainFlag))
+         if(flagField->isFlagSet(cellIt,domainFlag))
          {
-            real_t value = field->get(*cellIt);
+            real_t value = field->get(cellIt);
             sum += value;
             min = std::min(min, value);
             max = std::max(max, value);
@@ -162,11 +162,11 @@ void getVectorFieldQuantities( const shared_ptr<StructuredBlockStorage> & blocks
       auto flagField = blockIt->getData<FlagField_T>( flagFieldID );
       auto domainFlag = flagField->getFlag( Domain_Flag );
       CellInterval xyzSizeWithGhostLayers = field->xyzSizeWithGhostLayer();
-      for( auto cellIt = xyzSizeWithGhostLayers.begin(); cellIt != xyzSizeWithGhostLayers.end(); ++cellIt )
+      for(const auto& cellIt : xyzSizeWithGhostLayers)
       {
-         if( flagField->isFlagSet(*cellIt,domainFlag))
+         if(flagField->isFlagSet(cellIt,domainFlag))
          {
-            Vector3<real_t> value = field->get(*cellIt);
+            Vector3<real_t> value = field->get(cellIt);
             sum += value;
             for (size_t i = 0; i < 3; ++i) {
                min[i] = std::min(min[i], value[i]);
@@ -202,19 +202,19 @@ void getMultiCompFieldQuantities( const shared_ptr<StructuredBlockStorage> & blo
       auto flagField = blockIt->getData<FlagField_T>( flagFieldID );
       auto domainFlag = flagField->getFlag( Domain_Flag );
       CellInterval xyzSizeWithGhostLayers = field->xyzSizeWithGhostLayer();
-      for( auto cellIt = xyzSizeWithGhostLayers.begin(); cellIt != xyzSizeWithGhostLayers.end(); ++cellIt )
+      for(const auto& cellIt : xyzSizeWithGhostLayers)
       {
-         if( flagField->isFlagSet(*cellIt,domainFlag))
+         if(flagField->isFlagSet(cellIt,domainFlag))
          {
-            real_t value0 = field->get(*cellIt, 0);
+            real_t value0 = field->get(cellIt, 0);
             sum[0] += value0;
             min[0] = std::min(min[0], value0);
             max[0] = std::max(max[0], value0);
-            real_t value1 = field->get(*cellIt, 1);
+            real_t value1 = field->get(cellIt, 1);
             sum[1] += value1;
             min[1] = std::min(min[1], value1);
             max[1] = std::max(max[1], value1);
-            real_t value2 = field->get(*cellIt, 2);
+            real_t value2 = field->get(cellIt, 2);
             sum[2] += value2;
             min[2] = std::min(min[2], value2);
             max[2] = std::max(max[2], value2);
@@ -237,9 +237,9 @@ void testNearestNeighborDistributor( const shared_ptr<StructuredBlockStorage> &
                                      const BlockDataID & scalarFieldID, const BlockDataID & vectorFieldID, const BlockDataID & multiComponentFieldID )
 {
    // distributors
-   typedef field::NearestNeighborDistributor<ScalarField_T, FlagField_T>         ScalarDistributor_T;
-   typedef field::NearestNeighborDistributor<Vec3Field_T, FlagField_T>           Vec3Distributor_T;
-   typedef field::NearestNeighborDistributor<MultiComponentField_T, FlagField_T> MultiComponentDistributor_T;
+   using ScalarDistributor_T = field::NearestNeighborDistributor<ScalarField_T, FlagField_T>;
+   using Vec3Distributor_T = field::NearestNeighborDistributor<Vec3Field_T, FlagField_T>;
+   using MultiComponentDistributor_T = field::NearestNeighborDistributor<MultiComponentField_T, FlagField_T>;
    BlockDataID scalarDistributorID         = field::addDistributor< ScalarDistributor_T, FlagField_T >( blocks, scalarFieldID, flagFieldID, Domain_Flag );
    BlockDataID vectorDistributorID         = field::addDistributor< Vec3Distributor_T, FlagField_T >( blocks, vectorFieldID, flagFieldID, Domain_Flag );
    BlockDataID multiComponentDistributorID = field::addDistributor< MultiComponentDistributor_T, FlagField_T >( blocks, multiComponentFieldID, flagFieldID, Domain_Flag );
@@ -322,9 +322,9 @@ void testKernelDistributor( const shared_ptr<StructuredBlockStorage> & blocks, c
                             const BlockDataID & scalarFieldID, const BlockDataID & vectorFieldID, const BlockDataID & multiComponentFieldID )
 {
    // distributors
-   typedef field::KernelDistributor<ScalarField_T, FlagField_T>         ScalarDistributor_T;
-   typedef field::KernelDistributor<Vec3Field_T, FlagField_T>           Vec3Distributor_T;
-   typedef field::KernelDistributor<MultiComponentField_T, FlagField_T> MultiComponentDistributor_T;
+   using ScalarDistributor_T = field::KernelDistributor<ScalarField_T, FlagField_T>;
+   using Vec3Distributor_T = field::KernelDistributor<Vec3Field_T, FlagField_T>;
+   using MultiComponentDistributor_T = field::KernelDistributor<MultiComponentField_T, FlagField_T>;
    BlockDataID scalarDistributorID         = field::addDistributor< ScalarDistributor_T, FlagField_T >( blocks, scalarFieldID, flagFieldID, Domain_Flag );
    BlockDataID vectorDistributorID         = field::addDistributor< Vec3Distributor_T, FlagField_T >( blocks, vectorFieldID, flagFieldID, Domain_Flag );
    BlockDataID multiComponentDistributorID = field::addDistributor< MultiComponentDistributor_T, FlagField_T >( blocks, multiComponentFieldID, flagFieldID, Domain_Flag );
@@ -407,7 +407,7 @@ void testNearestNeighborDistributorAtBoundary( const shared_ptr<StructuredBlockS
                                                const BlockDataID & flagFieldID, const BlockDataID & scalarFieldID )
 {
    // distributor
-   typedef field::NearestNeighborDistributor<ScalarField_T, FlagField_T> ScalarDistributor_T;
+   using ScalarDistributor_T = field::NearestNeighborDistributor<ScalarField_T, FlagField_T>;
    BlockDataID scalarDistributorID = field::addDistributor<ScalarDistributor_T, FlagField_T>(blocks, scalarFieldID, flagFieldID, Domain_Flag);
 
    // check scalar interpolation close to boundary
@@ -451,7 +451,7 @@ void testKernelDistributorAtBoundary( const shared_ptr<StructuredBlockStorage> &
                                       const BlockDataID & flagFieldID, const BlockDataID & scalarFieldID )
 {
    // distributor
-   typedef field::KernelDistributor<ScalarField_T, FlagField_T> ScalarDistributor_T;
+   using ScalarDistributor_T = field::KernelDistributor<ScalarField_T, FlagField_T>;
    BlockDataID scalarDistributorID = field::addDistributor<ScalarDistributor_T, FlagField_T>(blocks, scalarFieldID, flagFieldID, Domain_Flag);
 
    // check scalar interpolation close to boundary
diff --git a/tests/field/interpolators/FieldInterpolationTest.cpp b/tests/field/interpolators/FieldInterpolationTest.cpp
index 712f89de97c12a9dae6d8f9f8ec6b7c1c9639009..1a5533141bdd5118e976af03d4039bb48e57b2a2 100644
--- a/tests/field/interpolators/FieldInterpolationTest.cpp
+++ b/tests/field/interpolators/FieldInterpolationTest.cpp
@@ -41,9 +41,9 @@ const uint_t FieldGhostLayers( 1 );
 using flag_t = walberla::uint8_t;
 using FlagField_T = FlagField<flag_t>;
 
-typedef GhostLayerField< real_t, 1>          ScalarField_T;
-typedef GhostLayerField< Vector3<real_t>, 1> Vec3Field_T;
-typedef GhostLayerField< real_t, 3>          MultiComponentField_T;
+using ScalarField_T = GhostLayerField<real_t, 1>;
+using Vec3Field_T = GhostLayerField<Vector3<real_t>, 1>;
+using MultiComponentField_T = GhostLayerField<real_t, 3>;
 
 
 const FlagUID Domain_Flag ( "domain" );
@@ -118,9 +118,9 @@ void testNearestNeighborFieldInterpolator( const shared_ptr<StructuredBlockStora
                                            const BlockDataID & scalarFieldID, const BlockDataID & vectorFieldID, const BlockDataID & multiComponentFieldID )
 {
    // field interpolators
-   typedef field::NearestNeighborFieldInterpolator<ScalarField_T, FlagField_T>         ScalarFieldInterpolator_T;
-   typedef field::NearestNeighborFieldInterpolator<Vec3Field_T, FlagField_T>           Vec3FieldInterpolator_T;
-   typedef field::NearestNeighborFieldInterpolator<MultiComponentField_T, FlagField_T> MultiComponentFieldInterpolator_T;
+   using ScalarFieldInterpolator_T = field::NearestNeighborFieldInterpolator<ScalarField_T, FlagField_T>;
+   using Vec3FieldInterpolator_T = field::NearestNeighborFieldInterpolator<Vec3Field_T, FlagField_T>;
+   using MultiComponentFieldInterpolator_T = field::NearestNeighborFieldInterpolator<MultiComponentField_T, FlagField_T>;
    BlockDataID scalarFieldInterpolatorID         = field::addFieldInterpolator< ScalarFieldInterpolator_T, FlagField_T >( blocks, scalarFieldID, flagFieldID, Domain_Flag );
    BlockDataID vectorFieldInterpolatorID         = field::addFieldInterpolator< Vec3FieldInterpolator_T, FlagField_T >( blocks, vectorFieldID, flagFieldID, Domain_Flag );
    BlockDataID multiComponentFieldInterpolatorID = field::addFieldInterpolator< MultiComponentFieldInterpolator_T, FlagField_T >( blocks, multiComponentFieldID, flagFieldID, Domain_Flag );
@@ -171,9 +171,9 @@ void testTrilinearFieldInterpolator( const shared_ptr<StructuredBlockStorage> &
                                      const BlockDataID & scalarFieldID, const BlockDataID & vectorFieldID, const BlockDataID & multiComponentFieldID )
 {
    // field interpolators
-   typedef field::TrilinearFieldInterpolator<ScalarField_T, FlagField_T>         ScalarFieldInterpolator_T;
-   typedef field::TrilinearFieldInterpolator<Vec3Field_T, FlagField_T>           Vec3FieldInterpolator_T;
-   typedef field::TrilinearFieldInterpolator<MultiComponentField_T, FlagField_T> MultiComponentFieldInterpolator_T;
+   using ScalarFieldInterpolator_T = field::TrilinearFieldInterpolator<ScalarField_T, FlagField_T>;
+   using Vec3FieldInterpolator_T = field::TrilinearFieldInterpolator<Vec3Field_T, FlagField_T>;
+   using MultiComponentFieldInterpolator_T = field::TrilinearFieldInterpolator<MultiComponentField_T, FlagField_T>;
    BlockDataID scalarFieldInterpolatorID         = field::addFieldInterpolator< ScalarFieldInterpolator_T, FlagField_T >( blocks, scalarFieldID, flagFieldID, Domain_Flag );
    BlockDataID vectorFieldInterpolatorID         = field::addFieldInterpolator< Vec3FieldInterpolator_T, FlagField_T >( blocks, vectorFieldID, flagFieldID, Domain_Flag );
    BlockDataID multiComponentFieldInterpolatorID = field::addFieldInterpolator< MultiComponentFieldInterpolator_T, FlagField_T >( blocks, multiComponentFieldID, flagFieldID, Domain_Flag );
@@ -224,9 +224,9 @@ void testKernelFieldInterpolator( const shared_ptr<StructuredBlockStorage> & blo
                                   const BlockDataID & scalarFieldID, const BlockDataID & vectorFieldID, const BlockDataID & multiComponentFieldID )
 {
    // field interpolators
-   typedef field::KernelFieldInterpolator<ScalarField_T, FlagField_T>         ScalarFieldInterpolator_T;
-   typedef field::KernelFieldInterpolator<Vec3Field_T, FlagField_T>           Vec3FieldInterpolator_T;
-   typedef field::KernelFieldInterpolator<MultiComponentField_T, FlagField_T> MultiComponentFieldInterpolator_T;
+   using ScalarFieldInterpolator_T = field::KernelFieldInterpolator<ScalarField_T, FlagField_T>;
+   using Vec3FieldInterpolator_T = field::KernelFieldInterpolator<Vec3Field_T, FlagField_T>;
+   using MultiComponentFieldInterpolator_T = field::KernelFieldInterpolator<MultiComponentField_T, FlagField_T>;
    BlockDataID scalarFieldInterpolatorID         = field::addFieldInterpolator< ScalarFieldInterpolator_T, FlagField_T >( blocks, scalarFieldID, flagFieldID, Domain_Flag );
    BlockDataID vectorFieldInterpolatorID         = field::addFieldInterpolator< Vec3FieldInterpolator_T, FlagField_T >( blocks, vectorFieldID, flagFieldID, Domain_Flag );
    BlockDataID multiComponentFieldInterpolatorID = field::addFieldInterpolator< MultiComponentFieldInterpolator_T, FlagField_T >( blocks, multiComponentFieldID, flagFieldID, Domain_Flag );
@@ -277,7 +277,7 @@ void testKernelFieldInterpolator( const shared_ptr<StructuredBlockStorage> & blo
 void testNearestNeighborFieldInterpolatorAtBoundary( const shared_ptr<StructuredBlockStorage> & blocks,
                                                      const BlockDataID & flagFieldID, const BlockDataID & scalarFieldID ) {
    // field interpolators
-   typedef field::NearestNeighborFieldInterpolator<ScalarField_T, FlagField_T> ScalarFieldInterpolator_T;
+   using ScalarFieldInterpolator_T = field::NearestNeighborFieldInterpolator<ScalarField_T, FlagField_T>;
    BlockDataID scalarFieldInterpolatorID = field::addFieldInterpolator<ScalarFieldInterpolator_T, FlagField_T>(blocks, scalarFieldID, flagFieldID, Domain_Flag);
 
    // check scalar interpolation close to boundary
@@ -310,7 +310,7 @@ void testNearestNeighborFieldInterpolatorAtBoundary( const shared_ptr<Structured
 void testTrilinearFieldInterpolatorAtBoundary( const shared_ptr<StructuredBlockStorage> & blocks,
                                                const BlockDataID & flagFieldID, const BlockDataID & scalarFieldID ) {
    // field interpolators
-   typedef field::TrilinearFieldInterpolator<ScalarField_T, FlagField_T> ScalarFieldInterpolator_T;
+   using ScalarFieldInterpolator_T = field::TrilinearFieldInterpolator<ScalarField_T, FlagField_T>;
    BlockDataID scalarFieldInterpolatorID = field::addFieldInterpolator<ScalarFieldInterpolator_T, FlagField_T>(blocks, scalarFieldID, flagFieldID, Domain_Flag);
 
    // check scalar interpolation close to boundary
@@ -343,7 +343,7 @@ void testTrilinearFieldInterpolatorAtBoundary( const shared_ptr<StructuredBlockS
 void testKernelFieldInterpolatorAtBoundary( const shared_ptr<StructuredBlockStorage> & blocks,
                                             const BlockDataID & flagFieldID, const BlockDataID & scalarFieldID ) {
    // field interpolators
-   typedef field::KernelFieldInterpolator<ScalarField_T, FlagField_T> ScalarFieldInterpolator_T;
+   using ScalarFieldInterpolator_T = field::KernelFieldInterpolator<ScalarField_T, FlagField_T>;
    BlockDataID scalarFieldInterpolatorID = field::addFieldInterpolator<ScalarFieldInterpolator_T, FlagField_T>(blocks, scalarFieldID, flagFieldID, Domain_Flag);
 
    // check scalar interpolation close to boundary
diff --git a/tests/geometry/BinaryRawFileTest.cpp b/tests/geometry/BinaryRawFileTest.cpp
index 22ce402d95a9d16f6a284dd8c780fe532052053e..b0ca2f3e59d570eb44e08e2f79cb1eb21ddfc097 100644
--- a/tests/geometry/BinaryRawFileTest.cpp
+++ b/tests/geometry/BinaryRawFileTest.cpp
@@ -42,14 +42,14 @@ namespace geometry {
 void test( const std::string & filename, const Vector3<uint_t> & size, const std::string & datatype, const bool vtkOut )
 {
    WALBERLA_LOG_INFO( "Testing unscaled" );
-   BinaryRawFile brf( filename, size, datatype );
+   BinaryRawFile const brf( filename, size, datatype );
 
    auto blocks = blockforest::createUniformBlockGrid( uint_t(1), uint_t( 1 ), uint_t( 1 ), 
       size[0], size[1], size[2], 
       real_t( 1 ), 
       uint_t( 1 ), uint_t( 1 ), uint_t( 1 ) );
 
-   typedef GhostLayerField< uint8_t, uint_t( 1 ) > ScalarField;
+   using ScalarField = GhostLayerField<uint8_t, uint_t(1)>;
 
    BlockDataID scalarFieldID = field::addToStorage<ScalarField>( blocks, "BinaryRawFile" );
 
@@ -57,7 +57,7 @@ void test( const std::string & filename, const Vector3<uint_t> & size, const std
    {
       auto field = block.getData<ScalarField>( scalarFieldID );
       
-      CellInterval ci( 0, 0, 0, cell_idx_c( size[0] ) - 1, cell_idx_c( size[1] ) - 1, cell_idx_c( size[2] ) - 1 );
+      CellInterval const ci( 0, 0, 0, cell_idx_c( size[0] ) - 1, cell_idx_c( size[1] ) - 1, cell_idx_c( size[2] ) - 1 );
 
       for (const Cell c : ci)
       {
@@ -77,7 +77,7 @@ void test( const std::string & filename, const Vector3<uint_t> & size, const std
 void testScaled( const std::string & filename, const Vector3<uint_t> & size, const std::string & datatype, const bool vtkOut )
 {
    WALBERLA_LOG_INFO( "Testing scaled" );
-   BinaryRawFile brf( filename, size, datatype );
+   BinaryRawFile const brf( filename, size, datatype );
 
    Vector3<uint_t> scaledSize( std::max( uint_t( 1 ), size[0] / uint_t( 2 ) ),
                                std::max( uint_t( 1 ), size[1] / uint_t( 3 ) ),
@@ -88,9 +88,9 @@ void testScaled( const std::string & filename, const Vector3<uint_t> & size, con
       real_t( 1 ),
       uint_t( 1 ), uint_t( 1 ), uint_t( 1 ) );
 
-   BinaryRawFileInterpolator brfi( blocks->getDomain(), brf, BinaryRawFileInterpolator::NEAREST_NEIGHBOR );
+   BinaryRawFileInterpolator const brfi( blocks->getDomain(), brf, BinaryRawFileInterpolator::NEAREST_NEIGHBOR );
 
-   typedef GhostLayerField< uint8_t, uint_t( 1 ) > ScalarField;
+   using ScalarField = GhostLayerField<uint8_t, uint_t(1)>;
 
    BlockDataID scalarFieldID = field::addToStorage<ScalarField>( blocks, "BinaryRawFile" );
 
@@ -98,7 +98,7 @@ void testScaled( const std::string & filename, const Vector3<uint_t> & size, con
    {
       auto field = block.getData<ScalarField>( scalarFieldID );
 
-      CellInterval ci( 0, 0, 0, cell_idx_c( scaledSize[0] ) - 1, cell_idx_c( scaledSize[1] ) - 1, cell_idx_c( scaledSize[2] ) - 1 );
+      CellInterval const ci( 0, 0, 0, cell_idx_c( scaledSize[0] ) - 1, cell_idx_c( scaledSize[1] ) - 1, cell_idx_c( scaledSize[2] ) - 1 );
 
       for (const Cell c : ci)
       {
@@ -121,7 +121,7 @@ void testScaled( const std::string & filename, const Vector3<uint_t> & size, con
 
 int main( int argc, char * argv[] )
 {
-   walberla::mpi::Environment env( argc, argv );
+   walberla::mpi::Environment const env( argc, argv );
 
    std::vector< std::string > args( argv, argv + argc );
 
diff --git a/tests/geometry/CellAABBTest.cpp b/tests/geometry/CellAABBTest.cpp
index 902be4d75e05df9ab324b08188c868bdf8a72261..1a00057732c4efa7977b7c75a52084089d45c36d 100644
--- a/tests/geometry/CellAABBTest.cpp
+++ b/tests/geometry/CellAABBTest.cpp
@@ -30,7 +30,7 @@ int main()
    using walberla::geometry::CellAABB;
 
    {
-      CellAABB ca;
+      CellAABB const ca;
 
       WALBERLA_CHECK_EQUAL( ca.xBegin, 0 );
       WALBERLA_CHECK_EQUAL( ca.yBegin, 0 );
@@ -46,7 +46,7 @@ int main()
       WALBERLA_CHECK_EQUAL( ca.numCells(), 1 );
    }
    {
-      CellAABB ca(1, 2, 3, 4, 5, 6);
+      CellAABB const ca(1, 2, 3, 4, 5, 6);
 
       WALBERLA_CHECK_EQUAL( ca.xBegin, 1 );
       WALBERLA_CHECK_EQUAL( ca.yBegin, 2 );
@@ -62,19 +62,19 @@ int main()
       WALBERLA_CHECK_EQUAL( ca.numCells(), 4*4*4 );
    }
    {
-      CellAABB ca(0, 0, 0, 0, 0, 0);
+      CellAABB const ca(0, 0, 0, 0, 0, 0);
       WALBERLA_CHECK_EQUAL( ca.numCells(), 1 );
    }
    {
-      CellAABB ca(0, 0, 0, 1, 1, 1);
+      CellAABB const ca(0, 0, 0, 1, 1, 1);
       WALBERLA_CHECK_EQUAL( ca.numCells(), 8 );
    }
    {
-      CellAABB ca(0, 0, 0, 9, 9, 9);
+      CellAABB const ca(0, 0, 0, 9, 9, 9);
       WALBERLA_CHECK_EQUAL( ca.numCells(), 1000 );
    }
    {
-      CellAABB ca(1, 1, 1, 10, 10, 10);
+      CellAABB const ca(1, 1, 1, 10, 10, 10);
       WALBERLA_CHECK_EQUAL( ca.numCells(), 1000 );
    }
 }
diff --git a/tests/geometry/ImageTest.cpp b/tests/geometry/ImageTest.cpp
index 4ab354b5dc31e20be550939a96e13feb8056979f..afe1260dc50c9f2acacc084184e5e9135598dd64 100644
--- a/tests/geometry/ImageTest.cpp
+++ b/tests/geometry/ImageTest.cpp
@@ -33,14 +33,14 @@ using namespace walberla;
 int main( int argc, char ** argv )
 {
    debug::enterTestMode();
-   walberla::Environment walberlaEnv( argc, argv );
+   walberla::Environment const walberlaEnv( argc, argv );
 
 
    using geometry::RGBAImage;
 
    RGBAImage::pixel_t pixelValue;
 
-   std::string colorStr ("ff1100");
+   std::string const colorStr ("ff1100");
    std::stringstream ss( colorStr );
    ss >> pixelValue;
 
diff --git a/tests/geometry/ScalarFieldFromBodyTest.cpp b/tests/geometry/ScalarFieldFromBodyTest.cpp
index 11908c1836faa679ed7cac974600cf8d242b530d..fb58b7a696a89dc9bbe78ca47f8ba79c8d81f889 100644
--- a/tests/geometry/ScalarFieldFromBodyTest.cpp
+++ b/tests/geometry/ScalarFieldFromBodyTest.cpp
@@ -42,10 +42,10 @@
 namespace walberla {
 using namespace geometry;
 
-const uint_t confBlockCount []      = { 1, 1, 1 };
-const uint_t confCells []           = { 30, 30, 30 };
+const std::array<uint_t, 3> confBlockCount = { 1, 1, 1 };
+const std::array<uint_t, 3> confCells      = { 30, 30, 30 };
 
-typedef GhostLayerField<real_t,1> ScalarField;
+using ScalarField = GhostLayerField<real_t, 1>;
 
 //======================================================================================================================
 //
@@ -121,13 +121,13 @@ void boxTest( StructuredBlockStorage & storage,
 
    manager.init( cfg.getBlock("Geometry") );
 
-   real_t volumeFromFileInit = getVolume( storage, fieldID );
+   real_t const volumeFromFileInit = getVolume( storage, fieldID );
 
    resetField( storage, fieldID );
 
    // Manual initialization
    initializer.init( AABB(min[0], min[1], min[2], max[0],max[1], max[2] ), false );
-   real_t volumeFromManualInit = getVolume( storage, fieldID );
+   real_t const volumeFromManualInit = getVolume( storage, fieldID );
 
 
    WALBERLA_LOG_RESULT("Box initialization test (Manual,File,Expected): ("
@@ -174,14 +174,14 @@ void ellipsoidTest( StructuredBlockStorage & storage,
 
    manager.init( cfg.getBlock("Geometry") );
 
-   real_t volumeFromFileInit = getVolume( storage, fieldID );
+   real_t const volumeFromFileInit = getVolume( storage, fieldID );
 
    resetField( storage, fieldID );
 
    // Manual initialization
 
    initializer.init( Ellipsoid( midpoint, axis1, axis2, radii ), false );
-   real_t volumeFromManualInit = getVolume( storage, fieldID );
+   real_t const volumeFromManualInit = getVolume( storage, fieldID );
 
 
    WALBERLA_LOG_RESULT("Ellipsoid initialization test (Manual,File,Expected): ("
@@ -219,7 +219,7 @@ void sphereTest( StructuredBlockStorage & storage,
 
    manager.init( cfg.getBlock("Geometry") );
 
-   real_t volumeFromFileInit = getVolume( storage, fieldID );
+   real_t const volumeFromFileInit = getVolume( storage, fieldID );
 
    resetField( storage, fieldID );
 
@@ -227,7 +227,7 @@ void sphereTest( StructuredBlockStorage & storage,
    // Manual initialization
 
    initializer.init( Sphere( midpoint, radius), false );
-   real_t volumeFromManualInit = getVolume( storage, fieldID );
+   real_t const volumeFromManualInit = getVolume( storage, fieldID );
 
 
    WALBERLA_LOG_RESULT("Sphere initialization test (Manual,File,Expected): ("
diff --git a/tests/geometry/ScalarFieldFromGrayScaleImageTest.cpp b/tests/geometry/ScalarFieldFromGrayScaleImageTest.cpp
index 0cb86e1ed0aac2132a2097c0c87faa4e46e72a2a..c0885ecd8112242b9fc25210ba1386343eb932a6 100644
--- a/tests/geometry/ScalarFieldFromGrayScaleImageTest.cpp
+++ b/tests/geometry/ScalarFieldFromGrayScaleImageTest.cpp
@@ -39,8 +39,8 @@
 namespace walberla {
 using namespace geometry;
 
-const uint_t confBlockCount []      = { 1, 1, 1 };
-const uint_t confCells []           = { 30, 30, 30 };
+const std::array<uint_t, 3> confBlockCount = { 1, 1, 1 };
+const std::array<uint_t, 3> confCells      = { 30, 30, 30 };
 
 int main( int argc, char ** argv )
 {
diff --git a/tests/geometry/VoxelFileTest.cpp b/tests/geometry/VoxelFileTest.cpp
index 8d3e8ace32aa3959f7597c8c85e91bba19a2b607..09274461bec68614cfe6b1ac1df9f0dddccdf43e 100644
--- a/tests/geometry/VoxelFileTest.cpp
+++ b/tests/geometry/VoxelFileTest.cpp
@@ -31,7 +31,7 @@
 
 #include <random>
 
-typedef std::mersenne_twister_engine< walberla::uint32_t, 32, 351, 175, 19, 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 0xa37d3c92 > mt11213b;
+using mt11213b = std::mersenne_twister_engine<walberla::uint32_t, 32, 351, 175, 19, 3433795303U, 11, 4294967295U, 7, 834054912, 15, 4293197824U, 17, 2742893714U>;
 
 /// randomize the memory underlying the vector up the maximal size (== capacity)
 template<typename T>
@@ -42,7 +42,7 @@ void randomizeVector( std::vector<T> & v )
    mt11213b rng;
    std::uniform_int_distribution<T> dist( std::numeric_limits<T>::min(), std::numeric_limits<T>::max() );
 
-   size_t oldSize = v.size();
+   size_t const oldSize = v.size();
    v.resize( v.capacity() );
    for(typename std::vector<T>::iterator it = v.begin(); it != v.end(); ++it)
       *it = dist(rng);
@@ -55,10 +55,10 @@ void randomizeVector( std::vector<unsigned char> & v )
    mt11213b rng;
    std::uniform_int_distribution<walberla::int16_t> dist( std::numeric_limits<unsigned char>::min(), std::numeric_limits<unsigned char>::max() );
 
-   size_t oldSize = v.size();
+   size_t const oldSize = v.size();
    v.resize( v.capacity() );
-   for(typename std::vector<unsigned char>::iterator it = v.begin(); it != v.end(); ++it)
-      *it = static_cast<unsigned char>( dist(rng) );
+   for(unsigned char & it : v)
+      it = static_cast<unsigned char>( dist(rng) );
    v.resize(oldSize);
 }
 
@@ -68,10 +68,10 @@ void randomizeVector( std::vector<char> & v )
    mt11213b rng;
    std::uniform_int_distribution<int16_t> dist( std::numeric_limits<char>::min(), std::numeric_limits<char>::max() );
 
-   size_t oldSize = v.size();
+   size_t const oldSize = v.size();
    v.resize( v.capacity() );
-   for(typename std::vector<char>::iterator it = v.begin(); it != v.end(); ++it)
-      *it = static_cast<char>( dist(rng) );
+   for(char & it : v)
+      it = static_cast<char>( dist(rng) );
    v.resize(oldSize);
 }
 
@@ -92,8 +92,8 @@ void makeRandomMultiArray( std::vector<unsigned char> & ma) {
    mt11213b rng;
    std::uniform_int_distribution<walberla::int16_t> dist(std::numeric_limits<unsigned char>::min(), std::numeric_limits<unsigned char>::max());
 
-   for (auto it = ma.begin(); it != ma.end(); ++it)
-      *it = static_cast<unsigned char>( dist(rng));
+   for (unsigned char & it : ma)
+      it = static_cast<unsigned char>( dist(rng));
 }
 
 template<>
@@ -101,8 +101,8 @@ void makeRandomMultiArray( std::vector<char> & ma)
 {
    mt11213b rng;
    std::uniform_int_distribution<int16_t> dist( std::numeric_limits<char>::min(), std::numeric_limits<char>::max() );
-   for (auto it = ma.begin(); it != ma.end(); ++it)
-      *it = static_cast<char>( dist(rng) );
+   for (char & it : ma)
+      it = static_cast<char>( dist(rng) );
 }
 
 template<typename T>
@@ -119,7 +119,7 @@ int main(int argc, char** argv)
 
    WALBERLA_LOG_INFO("Starting test!");
 
-   bool longrun = std::find(argv, argv + argc, std::string("--longrun")) != argv + argc;
+   bool const longrun = std::find(argv, argv + argc, std::string("--longrun")) != argv + argc;
 
    std::vector<size_t> sizes;
    if(longrun)
@@ -133,27 +133,27 @@ int main(int argc, char** argv)
 
    for(std::vector<size_t>::const_iterator xSize = sizes.begin(); xSize != sizes.end(); ++xSize)
       for(std::vector<size_t>::const_iterator ySize = sizes.begin(); ySize != sizes.end(); ++ySize)
-         for(std::vector<size_t>::const_iterator zSize = sizes.begin(); zSize != sizes.end(); ++zSize)
+         for(unsigned long const size : sizes)
          {
             std::stringstream ss;
-            ss << "geometry_testfile_" << *xSize << "_" << *ySize << "_" << *zSize << ".dat";
+            ss << "geometry_testfile_" << *xSize << "_" << *ySize << "_" << size << ".dat";
 
-            std::string filename = ss.str();
+            std::string const filename = ss.str();
 
-            runTests<unsigned char>(filename, *xSize, *ySize, *zSize);
+            runTests<unsigned char>(filename, *xSize, *ySize, size);
 
             if(longrun)
             {
-               runTests<char>(filename, *xSize, *ySize, *zSize);
+               runTests<char>(filename, *xSize, *ySize, size);
 
-               runTests<short>(filename, *xSize, *ySize, *zSize);
-               runTests<unsigned short>(filename, *xSize, *ySize, *zSize);
+               runTests<short>(filename, *xSize, *ySize, size);
+               runTests<unsigned short>(filename, *xSize, *ySize, size);
 
-               runTests<int>(filename, *xSize, *ySize, *zSize);
-               runTests<unsigned int>(filename, *xSize, *ySize, *zSize);
+               runTests<int>(filename, *xSize, *ySize, size);
+               runTests<unsigned int>(filename, *xSize, *ySize, size);
 
-               runTests<long>(filename, *xSize, *ySize, *zSize);
-               runTests<unsigned long>(filename, *xSize, *ySize, *zSize);
+               runTests<long>(filename, *xSize, *ySize, size);
+               runTests<unsigned long>(filename, *xSize, *ySize, size);
             }
          }
 }
@@ -166,13 +166,13 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
 
    WALBERLA_LOG_INFO( "Running Test with size " << xSize << "x" << ySize << "x" << zSize << " T = " << typeid(T).name() );
 
-   filesystem::path path(filename);
+   filesystem::path const path(filename);
 
    if( filesystem::exists( path ) )
       filesystem::remove( path );
 
-   CellInterval aabb(0, 0, 0, cell_idx_c(xSize - 1), cell_idx_c(ySize - 1), cell_idx_c(zSize - 1));
-   uint_t numCells = aabb.numCells();
+   CellInterval const aabb(0, 0, 0, cell_idx_c(xSize - 1), cell_idx_c(ySize - 1), cell_idx_c(zSize - 1));
+   uint_t const numCells = aabb.numCells();
 
    VoxelFileReader<T> geometryFile(filename, xSize, ySize, zSize);
 
@@ -301,10 +301,7 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
    if( zSize > size_t( 1 ) )
       blockSizesZ.push_back(std::max(zSize / 2 - 1, size_t(1)));
 
-   for( auto xit = blockSizesX.begin(); xit != blockSizesX.end(); ++xit ) { size_t blockSizeX = *xit;
-      for( auto yit = blockSizesY.begin(); yit != blockSizesY.end(); ++yit ) { size_t blockSizeY = *yit;
-         for( auto zit = blockSizesZ.begin(); zit != blockSizesZ.end(); ++zit ) { size_t blockSizeZ = *zit;
-            for(size_t zz = 0; zz <= (zSize - 1) / blockSizeZ; ++zz) {
+   for(unsigned long const blockSizeX : blockSizesX) { for(unsigned long const blockSizeY : blockSizesY) { for(unsigned long const blockSizeZ : blockSizesZ) { for(size_t zz = 0; zz <= (zSize - 1) / blockSizeZ; ++zz) {
                for(size_t yy = 0; yy <= (ySize - 1) / blockSizeY; ++yy) {
                   for(size_t xx = 0; xx <= (xSize - 1) / blockSizeX; ++xx)
                   {
@@ -352,10 +349,7 @@ void runTests(const std::string & filename, size_t xSize, size_t ySize, size_t z
 
    geometryFile.create(filename, xSize, ySize, zSize);
 
-   for( auto xit = blockSizesX.begin(); xit != blockSizesX.end(); ++xit ) { size_t blockSizeX = *xit;
-      for( auto yit = blockSizesY.begin(); yit != blockSizesY.end(); ++yit ) { size_t blockSizeY = *yit;
-         for( auto zit = blockSizesZ.begin(); zit != blockSizesZ.end(); ++zit ) { size_t blockSizeZ = *zit;
-            for(size_t zz = 0; zz <= (zSize - 1) / blockSizeZ; ++zz) {
+   for(unsigned long const blockSizeX : blockSizesX) { for(unsigned long const blockSizeY : blockSizesY) { for(unsigned long const blockSizeZ : blockSizesZ) { for(size_t zz = 0; zz <= (zSize - 1) / blockSizeZ; ++zz) {
                for(size_t yy = 0; yy <= (ySize - 1) / blockSizeY; ++yy) {
                   for(size_t xx = 0; xx <= (xSize - 1) / blockSizeX; ++xx)
                   {
@@ -460,10 +454,10 @@ void modifyHeader(std::string inputFilename, std::string outputFilename,
 
    while(!is.eof())
    {
-      char buffer[1024];
-      is.read(buffer, 1024);
-      std::streamsize bytesRead = is.gcount();
-      os.write( buffer, bytesRead );
+      std::array<char, 1024> buffer;
+      is.read(buffer.data(), 1024);
+      std::streamsize const bytesRead = is.gcount();
+      os.write( buffer.data(), bytesRead );
       WALBERLA_CHECK( is.eof() || !is.fail() );
       WALBERLA_CHECK( !os.fail() );
    }
diff --git a/tests/lbm_mesapd_coupling/momentum_exchange_method/DragForceSphereMEM.cpp b/tests/lbm_mesapd_coupling/momentum_exchange_method/DragForceSphereMEM.cpp
index ca976cfc719ca61bfd59d7ec029eb9754329fe1a..be0ae38ec58ad51a8fe6cdcc14a05a5c750c0641 100644
--- a/tests/lbm_mesapd_coupling/momentum_exchange_method/DragForceSphereMEM.cpp
+++ b/tests/lbm_mesapd_coupling/momentum_exchange_method/DragForceSphereMEM.cpp
@@ -187,8 +187,7 @@ public:
                        const shared_ptr<ParticleAccessor_T>& ac, walberla::id_t sphereID )
 :     timeloop_( timeloop ), setup_( setup ), blocks_( blocks ),
       flagFieldID_( flagFieldID ), pdfFieldID_( pdfFieldID ),
-      ac_( ac ), sphereID_( sphereID ),
-      normalizedDragOld_( 0.0 ), normalizedDragNew_( 0.0 )
+      ac_( ac ), sphereID_( sphereID )
    {
       // calculate the analytical drag force value based on the series expansion of chi
       // see also Sangani - Slow flow through a periodic array of spheres, IJMF 1982. Eq. 60 and Table 1
@@ -196,12 +195,15 @@ public:
       real_t tempChiPowS = real_c(1);
 
       // coefficients to calculate the drag in a series expansion
-      real_t dragCoefficients[31] = {  real_c(1.000000),  real_c(1.418649),  real_c(2.012564),  real_c(2.331523),  real_c(2.564809),   real_c(2.584787),
-                                       real_c(2.873609),  real_c(3.340163),  real_c(3.536763),  real_c(3.504092),  real_c(3.253622),   real_c(2.689757),
-                                       real_c(2.037769),  real_c(1.809341),  real_c(1.877347),  real_c(1.534685), real_c(0.9034708),  real_c(0.2857896),
-                                       real_c(-0.5512626), real_c(-1.278724),  real_c(1.013350),  real_c(5.492491),  real_c(4.615388), real_c(-0.5736023),
-                                       real_c(-2.865924), real_c(-4.709215), real_c(-6.870076), real_c(0.1455304),  real_c(12.51891),   real_c(9.742811),
-                                       real_c(-5.566269)};
+      std::array< real_t, 31 > dragCoefficients = {
+         real_c(1.000000),  real_c(1.418649),  real_c(2.012564),  real_c(2.331523),   real_c(2.564809),
+         real_c(2.584787),  real_c(2.873609),  real_c(3.340163),  real_c(3.536763),   real_c(3.504092),
+         real_c(3.253622),  real_c(2.689757),  real_c(2.037769),  real_c(1.809341),   real_c(1.877347),
+         real_c(1.534685),  real_c(0.9034708), real_c(0.2857896), real_c(-0.5512626), real_c(-1.278724),
+         real_c(1.013350),  real_c(5.492491),  real_c(4.615388),  real_c(-0.5736023), real_c(-2.865924),
+         real_c(-4.709215), real_c(-6.870076), real_c(0.1455304), real_c(12.51891),   real_c(9.742811),
+         real_c(-5.566269)
+      };
 
       for(uint_t s = 0; s <= uint_t(30); ++s){
          analyticalDrag += dragCoefficients[s] * tempChiPowS;
@@ -321,8 +323,8 @@ private:
    const walberla::id_t sphereID_;
 
    // drag coefficient
-   real_t normalizedDragOld_;
-   real_t normalizedDragNew_;
+   real_t normalizedDragOld_{ 0.0 };
+   real_t normalizedDragNew_{ 0.0 };
 
 };
 
diff --git a/tests/lbm_mesapd_coupling/momentum_exchange_method/PdfReconstructionMEM.cpp b/tests/lbm_mesapd_coupling/momentum_exchange_method/PdfReconstructionMEM.cpp
index 665ddb12f41259f5025eace600f0d084b49c5aee..c58459d4a1010025c270b9fd690a08ee04624194 100644
--- a/tests/lbm_mesapd_coupling/momentum_exchange_method/PdfReconstructionMEM.cpp
+++ b/tests/lbm_mesapd_coupling/momentum_exchange_method/PdfReconstructionMEM.cpp
@@ -585,11 +585,11 @@ int main( int argc, char **argv )
 
    // test setups -> tuple of (setupName, spherePosition, periodicityTested)
    std::vector<std::tuple<std::string, Vector3<real_t>, bool> > testSetups;
-   testSetups.push_back( std::make_tuple( "sphere inside block",          Vector3<real_t>(real_t(10), real_t(10), real_t(10)),        false) );
-   testSetups.push_back( std::make_tuple( "sphere on block boarder",      Vector3<real_t>(real_t(19.5), real_t(10), real_t(10)),      false) );
-   testSetups.push_back( std::make_tuple( "sphere on block boarder 2",    Vector3<real_t>(real_t(20)+radius, real_t(10), real_t(10)), false) );
-   testSetups.push_back( std::make_tuple( "sphere on periodic boarder",   Vector3<real_t>(real_t(59.5), real_t(10), real_t(10)),      true) );
-   testSetups.push_back( std::make_tuple( "sphere on periodic boarder 2", Vector3<real_t>(radius, real_t(10), real_t(10)),            true) );
+   testSetups.emplace_back( "sphere inside block",          Vector3<real_t>(real_t(10), real_t(10), real_t(10)),        false );
+   testSetups.emplace_back( "sphere on block boarder",      Vector3<real_t>(real_t(19.5), real_t(10), real_t(10)),      false );
+   testSetups.emplace_back( "sphere on block boarder 2",    Vector3<real_t>(real_t(20)+radius, real_t(10), real_t(10)), false );
+   testSetups.emplace_back( "sphere on periodic boarder",   Vector3<real_t>(real_t(59.5), real_t(10), real_t(10)),      true );
+   testSetups.emplace_back( "sphere on periodic boarder 2", Vector3<real_t>(radius, real_t(10), real_t(10)),            true );
 
 
    /////////////////////////////////////
diff --git a/tests/lbm_mesapd_coupling/partially_saturated_cells_method/DragForceSpherePSM.cpp b/tests/lbm_mesapd_coupling/partially_saturated_cells_method/DragForceSpherePSM.cpp
index 12bc2a240dd37765d161ebc3556c78d370546fa1..5d39ae1310f4a4dde1f454c9f35ad8080bcae850 100644
--- a/tests/lbm_mesapd_coupling/partially_saturated_cells_method/DragForceSpherePSM.cpp
+++ b/tests/lbm_mesapd_coupling/partially_saturated_cells_method/DragForceSpherePSM.cpp
@@ -106,8 +106,7 @@ class DragForceEvaluator
                       const BlockDataID& pdfFieldID, const BlockDataID& particleAndVolumeFractionFieldID,
                       const shared_ptr< ParticleAccessor_T >& ac, walberla::id_t sphereID)
       : timeloop_(timeloop), setup_(setup), blocks_(blocks), pdfFieldID_(pdfFieldID),
-        particleAndVolumeFractionFieldID_(particleAndVolumeFractionFieldID), ac_(ac), sphereID_(sphereID),
-        normalizedDragOld_(0.0), normalizedDragNew_(0.0)
+        particleAndVolumeFractionFieldID_(particleAndVolumeFractionFieldID), ac_(ac), sphereID_(sphereID)
    {
       // calculate the analytical drag force value based on the series expansion of chi
       // see also Sangani - Slow flow through a periodic array of spheres, IJMF 1982. Eq. 60 and Table 1
@@ -115,14 +114,15 @@ class DragForceEvaluator
       real_t tempChiPowS    = real_c(1);
 
       // coefficients to calculate the drag in a series expansion
-      real_t dragCoefficients[31] = { real_c(1.000000),  real_c(1.418649),  real_c(2.012564),   real_c(2.331523),
-                                      real_c(2.564809),  real_c(2.584787),  real_c(2.873609),   real_c(3.340163),
-                                      real_c(3.536763),  real_c(3.504092),  real_c(3.253622),   real_c(2.689757),
-                                      real_c(2.037769),  real_c(1.809341),  real_c(1.877347),   real_c(1.534685),
-                                      real_c(0.9034708), real_c(0.2857896), real_c(-0.5512626), real_c(-1.278724),
-                                      real_c(1.013350),  real_c(5.492491),  real_c(4.615388),   real_c(-0.5736023),
-                                      real_c(-2.865924), real_c(-4.709215), real_c(-6.870076),  real_c(0.1455304),
-                                      real_c(12.51891),  real_c(9.742811),  real_c(-5.566269) };
+      std::array< real_t, 31 > dragCoefficients = {
+         real_c(1.000000),  real_c(1.418649),  real_c(2.012564),  real_c(2.331523),   real_c(2.564809),
+         real_c(2.584787),  real_c(2.873609),  real_c(3.340163),  real_c(3.536763),   real_c(3.504092),
+         real_c(3.253622),  real_c(2.689757),  real_c(2.037769),  real_c(1.809341),   real_c(1.877347),
+         real_c(1.534685),  real_c(0.9034708), real_c(0.2857896), real_c(-0.5512626), real_c(-1.278724),
+         real_c(1.013350),  real_c(5.492491),  real_c(4.615388),  real_c(-0.5736023), real_c(-2.865924),
+         real_c(-4.709215), real_c(-6.870076), real_c(0.1455304), real_c(12.51891),   real_c(9.742811),
+         real_c(-5.566269)
+      };
 
       for (uint_t s = 0; s <= uint_t(30); ++s)
       {
@@ -231,8 +231,8 @@ class DragForceEvaluator
    const walberla::id_t sphereID_;
 
    // drag coefficient
-   real_t normalizedDragOld_;
-   real_t normalizedDragNew_;
+   real_t normalizedDragOld_{0.0};
+   real_t normalizedDragNew_{0.0};
 };
 
 //////////
diff --git a/tests/lbm_mesapd_coupling/partially_saturated_cells_method/TorqueSpherePSM.cpp b/tests/lbm_mesapd_coupling/partially_saturated_cells_method/TorqueSpherePSM.cpp
index 419897653e391094f62a668e2ec3602395fd4165..02f37ef387e99a53d05f72632401cb527d0b396a 100644
--- a/tests/lbm_mesapd_coupling/partially_saturated_cells_method/TorqueSpherePSM.cpp
+++ b/tests/lbm_mesapd_coupling/partially_saturated_cells_method/TorqueSpherePSM.cpp
@@ -73,7 +73,7 @@ using namespace walberla;
 using walberla::uint_t;
 
 // PDF field, flag field & particle field
-typedef lbm::D3Q19< lbm::collision_model::SRT, false > LatticeModel_T;
+using LatticeModel_T = lbm::D3Q19< lbm::collision_model::SRT, false >;
 
 using Stencil_T  = LatticeModel_T::Stencil;
 using PdfField_T = lbm::PdfField< LatticeModel_T >;
@@ -113,7 +113,7 @@ class TorqueEval
  public:
    TorqueEval(SweepTimeloop* timeloop, Setup* setup, const shared_ptr< StructuredBlockStorage >& blocks,
               const shared_ptr< ParticleAccessor_T >& ac, bool fileIO)
-      : timeloop_(timeloop), setup_(setup), blocks_(blocks), ac_(ac), fileIO_(fileIO), torqueOld_(0.0), torqueNew_(0.0)
+      : timeloop_(timeloop), setup_(setup), blocks_(blocks), ac_(ac), fileIO_(fileIO)
    {
       // calculate the (semi)analytical torque value
       // see also Hofmann et al. - Hydrodynamic interactions in colloidal crystals:(II). Application to dense cubic and
@@ -196,8 +196,8 @@ class TorqueEval
    bool fileIO_;
    std::string filename_;
 
-   real_t torqueOld_;
-   real_t torqueNew_;
+   real_t torqueOld_{ 0.0 };
+   real_t torqueNew_{ 0.0 };
 };
 
 //////////
diff --git a/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/DragForceSpherePSM.cpp b/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/DragForceSpherePSM.cpp
index 84edc556741f33c130d5160f5e2dac06eb24cf2d..5f9afa928bb0d8d69f962a453414c7d03221da03 100644
--- a/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/DragForceSpherePSM.cpp
+++ b/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/DragForceSpherePSM.cpp
@@ -68,7 +68,7 @@ using namespace walberla;
 using walberla::uint_t;
 using namespace lbm_mesapd_coupling::psm::gpu;
 
-typedef pystencils::PSMPackInfo PackInfo_T;
+using PackInfo_T = pystencils::PSMPackInfo;
 
 ////////////////
 // PARAMETERS //
@@ -94,7 +94,7 @@ class DragForceEvaluator
                       const BlockDataID& velocityFieldID, const shared_ptr< ParticleAccessor_T >& ac,
                       walberla::id_t sphereID)
       : timeloop_(timeloop), setup_(setup), blocks_(blocks), velocityFieldID_(velocityFieldID), ac_(ac),
-        sphereID_(sphereID), normalizedDragOld_(0.0), normalizedDragNew_(0.0)
+        sphereID_(sphereID)
    {
       // calculate the analytical drag force value based on the series expansion of chi
       // see also Sangani - Slow flow through a periodic array of spheres, IJMF 1982. Eq. 60 and Table 1
@@ -102,14 +102,15 @@ class DragForceEvaluator
       real_t tempChiPowS    = real_c(1);
 
       // coefficients to calculate the drag in a series expansion
-      real_t dragCoefficients[31] = { real_c(1.000000),  real_c(1.418649),  real_c(2.012564),   real_c(2.331523),
-                                      real_c(2.564809),  real_c(2.584787),  real_c(2.873609),   real_c(3.340163),
-                                      real_c(3.536763),  real_c(3.504092),  real_c(3.253622),   real_c(2.689757),
-                                      real_c(2.037769),  real_c(1.809341),  real_c(1.877347),   real_c(1.534685),
-                                      real_c(0.9034708), real_c(0.2857896), real_c(-0.5512626), real_c(-1.278724),
-                                      real_c(1.013350),  real_c(5.492491),  real_c(4.615388),   real_c(-0.5736023),
-                                      real_c(-2.865924), real_c(-4.709215), real_c(-6.870076),  real_c(0.1455304),
-                                      real_c(12.51891),  real_c(9.742811),  real_c(-5.566269) };
+      std::array< real_t, 31 > dragCoefficients = {
+         real_c(1.000000),  real_c(1.418649),  real_c(2.012564),  real_c(2.331523),   real_c(2.564809),
+         real_c(2.584787),  real_c(2.873609),  real_c(3.340163),  real_c(3.536763),   real_c(3.504092),
+         real_c(3.253622),  real_c(2.689757),  real_c(2.037769),  real_c(1.809341),   real_c(1.877347),
+         real_c(1.534685),  real_c(0.9034708), real_c(0.2857896), real_c(-0.5512626), real_c(-1.278724),
+         real_c(1.013350),  real_c(5.492491),  real_c(4.615388),  real_c(-0.5736023), real_c(-2.865924),
+         real_c(-4.709215), real_c(-6.870076), real_c(0.1455304), real_c(12.51891),   real_c(9.742811),
+         real_c(-5.566269)
+      };
 
       for (uint_t s = 0; s <= uint_t(30); ++s)
       {
@@ -213,8 +214,8 @@ class DragForceEvaluator
    const walberla::id_t sphereID_;
 
    // drag coefficient
-   real_t normalizedDragOld_;
-   real_t normalizedDragNew_;
+   real_t normalizedDragOld_{ 0.0 };
+   real_t normalizedDragNew_{ 0.0 };
 };
 
 //////////
@@ -412,7 +413,7 @@ int main(int argc, char** argv)
 
    // setup of the LBM communication for synchronizing the pdf field between neighboring blocks
 #ifdef WALBERLA_BUILD_WITH_GPU_SUPPORT
-   gpu::communication::UniformGPUScheme< Stencil_T > com(blocks, 0, false);
+   gpu::communication::UniformGPUScheme< Stencil_T > com(blocks, false, false);
 #else
    walberla::blockforest::communication::UniformBufferedScheme< Stencil_T > com(blocks);
 #endif
diff --git a/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/SettlingSpherePSM.cpp b/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/SettlingSpherePSM.cpp
index bbcf1a2392322e9e4f45ffeb316240ba3bc0abe4..cc4cd9dfe1b07bab04491c0306405aeae260706a 100644
--- a/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/SettlingSpherePSM.cpp
+++ b/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/SettlingSpherePSM.cpp
@@ -97,7 +97,7 @@ using namespace lbm_mesapd_coupling::psm::gpu;
 using flag_t      = walberla::uint8_t;
 using FlagField_T = FlagField< flag_t >;
 
-typedef pystencils::PSMPackInfo PackInfo_T;
+using PackInfo_T = pystencils::PSMPackInfo;
 
 ///////////
 // FLAGS //
@@ -639,7 +639,7 @@ int main(int argc, char** argv)
 
    // setup of the LBM communication for synchronizing the pdf field between neighboring blocks
 #ifdef WALBERLA_BUILD_WITH_GPU_SUPPORT
-   gpu::communication::UniformGPUScheme< Stencil_T > com(blocks, 0, false);
+   gpu::communication::UniformGPUScheme< Stencil_T > com(blocks, false, false);
 #else
    walberla::blockforest::communication::UniformBufferedScheme< Stencil_T > com(blocks);
 #endif
diff --git a/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/TorqueSpherePSM.cpp b/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/TorqueSpherePSM.cpp
index 194b3eb3a7dfbfc8f356aa9108c4b70694c1241a..3192aac970e0216242aa691eb824c5befab5c397 100644
--- a/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/TorqueSpherePSM.cpp
+++ b/tests/lbm_mesapd_coupling/partially_saturated_cells_method/codegen/TorqueSpherePSM.cpp
@@ -69,7 +69,7 @@ using namespace lbm_mesapd_coupling::psm::gpu;
 using flag_t      = walberla::uint8_t;
 using FlagField_T = FlagField< flag_t >;
 
-typedef pystencils::PSMPackInfo PackInfo_T;
+using PackInfo_T = pystencils::PSMPackInfo;
 
 ///////////
 // FLAGS //
@@ -103,7 +103,7 @@ class TorqueEval
  public:
    TorqueEval(SweepTimeloop* timeloop, Setup* setup, const shared_ptr< StructuredBlockStorage >& blocks,
               const shared_ptr< ParticleAccessor_T >& ac, bool fileIO)
-      : timeloop_(timeloop), setup_(setup), blocks_(blocks), ac_(ac), fileIO_(fileIO), torqueOld_(0.0), torqueNew_(0.0)
+      : timeloop_(timeloop), setup_(setup), blocks_(blocks), ac_(ac), fileIO_(fileIO)
    {
       // calculate the (semi)analytical torque value
       // see also Hofmann et al. - Hydrodynamic interactions in colloidal crystals:(II). Application to dense cubic and
@@ -186,8 +186,8 @@ class TorqueEval
    bool fileIO_;
    std::string filename_;
 
-   real_t torqueOld_;
-   real_t torqueNew_;
+   real_t torqueOld_{ 0.0 };
+   real_t torqueNew_{ 0.0 };
 };
 
 //////////
@@ -393,7 +393,7 @@ int main(int argc, char** argv)
 
    // setup of the LBM communication for synchronizing the pdf field between neighboring blocks
 #ifdef WALBERLA_BUILD_WITH_GPU_SUPPORT
-   gpu::communication::UniformGPUScheme< Stencil_T > com(blocks, 0, false);
+   gpu::communication::UniformGPUScheme< Stencil_T > com(blocks, false, false);
 #else
    walberla::blockforest::communication::UniformBufferedScheme< Stencil_T > com(blocks);
 #endif
diff --git a/tests/mesh/DistributedMeshVTKTest.cpp b/tests/mesh/DistributedMeshVTKTest.cpp
index ac3e1cc28375765f96909de422794b5e65e70a1b..a5db10b67974debdb56e5fcdbe85d51b275ebad7 100644
--- a/tests/mesh/DistributedMeshVTKTest.cpp
+++ b/tests/mesh/DistributedMeshVTKTest.cpp
@@ -163,7 +163,7 @@ void test( const std::string & meshFile )
 }
 
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
diff --git a/tests/mesh/MatrixVectorOperationsTest.cpp b/tests/mesh/MatrixVectorOperationsTest.cpp
index d7b7ced1c7abeb966dbc6fbf774c4fddafb1cb9b..093cc9c90fea2fbfa9bf3e672d5044aaebacc827 100644
--- a/tests/mesh/MatrixVectorOperationsTest.cpp
+++ b/tests/mesh/MatrixVectorOperationsTest.cpp
@@ -1,15 +1,15 @@
 //======================================================================================================================
 //
-//  This file is part of waLBerla. waLBerla is free software: you can 
+//  This file is part of waLBerla. waLBerla 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.
-//  
-//  waLBerla 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 
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
@@ -28,7 +28,7 @@ namespace walberla {
 namespace mesh {
 
 
-int main( int /*argc*/, char * /*argv*/[] )
+int main( int /*argc*/, char ** /*argv*/ )
 {
    debug::enterTestMode();
 
@@ -65,7 +65,7 @@ int main( int /*argc*/, char * /*argv*/[] )
 } // namespace mesh
 } // namespace walberla
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    return walberla::mesh::main( argc, argv );
 }
\ No newline at end of file
diff --git a/tests/mesh/MeshAABBIntersectionTest.cpp b/tests/mesh/MeshAABBIntersectionTest.cpp
index 451fe062b7f51f7ba96780f3ca03ce271d050355..f7c6b08475fefeda25f626fd33625efc90c11047 100644
--- a/tests/mesh/MeshAABBIntersectionTest.cpp
+++ b/tests/mesh/MeshAABBIntersectionTest.cpp
@@ -78,7 +78,7 @@ void runTests( const uint_t numAABBs )
    }
 }
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
@@ -104,4 +104,4 @@ int main( int argc, char * argv[] )
 int main( int argc, char * argv[] )
 {
    return walberla::mesh::main( argc, argv );
-}
+}
\ No newline at end of file
diff --git a/tests/mesh/MeshAABBSelectionTest.cpp b/tests/mesh/MeshAABBSelectionTest.cpp
index 3e92e09e76f6a4f0455aafbd042059158f361feb..b790baf88c4e340c96de1a895d3449510ef78e55 100644
--- a/tests/mesh/MeshAABBSelectionTest.cpp
+++ b/tests/mesh/MeshAABBSelectionTest.cpp
@@ -1,15 +1,15 @@
 //======================================================================================================================
 //
-//  This file is part of waLBerla. waLBerla is free software: you can 
+//  This file is part of waLBerla. waLBerla 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.
-//  
-//  waLBerla 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 
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
@@ -41,7 +41,7 @@ namespace walberla {
 namespace mesh {
 
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
@@ -79,7 +79,7 @@ int main( int argc, char * argv[] )
       for(uint_t j = 0; j < numPointsTestedPerBox; ++j)
       {
          auto p = toOpenMesh( subAabb.randomPoint( rng ) );
-         
+
          TriangleMesh::FaceHandle fh0, fh1;
          auto d0 = triDist.sqSignedDistance( p, fh0 );
          auto d1 = triDist.sqSignedDistance( subAabbFaces.begin(), subAabbFaces.end(), p, fh1 );
diff --git a/tests/mesh/MeshBlockExclusionTest.cpp b/tests/mesh/MeshBlockExclusionTest.cpp
index cebd9c96d457293f9702b118f44cc6623bc2bd3c..cdc77028a056c58ef2491add46b434d817d8ba03 100644
--- a/tests/mesh/MeshBlockExclusionTest.cpp
+++ b/tests/mesh/MeshBlockExclusionTest.cpp
@@ -63,8 +63,8 @@ struct AnyPointInAABB
 
    inline bool operator()( const AABB & aabb )
    {
-     for( auto it = points_.begin(); it != points_.end(); ++it )
-        if( aabb.contains( *it ) )
+     for(auto & point : points_)
+        if( aabb.contains( point ) )
            return true;
      return false;
    }
@@ -104,9 +104,9 @@ void test(const shared_ptr< DistanceOctree< MeshType > > & distanceOctree, const
    // Check wether all vertices are located in allocated blocks
    std::vector< Vector3<real_t> > uncoveredVertices(vertexPositions);
 
-   for (auto bIt = setupBlocks.begin(); bIt != setupBlocks.end(); ++bIt)
+   for (auto & setupBlock : setupBlocks)
    {
-      const AABB & aabb = (*bIt)->getAABB();
+      const AABB & aabb = setupBlock->getAABB();
 
       uncoveredVertices.erase(std::remove_if(uncoveredVertices.begin(), uncoveredVertices.end(), PointInAABB(aabb)), uncoveredVertices.end());
    }
@@ -138,7 +138,7 @@ void run( const std::string & meshFile, const uint_t numTotalBlocks )
 }
 
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
diff --git a/tests/mesh/MeshContainmentOctreeTest.cpp b/tests/mesh/MeshContainmentOctreeTest.cpp
index ff656b25a2b2c428581c4454836058cd0ff8b060..73f3f09b67f7d8e6f22d1434d340a2f8ecc3b9a6 100644
--- a/tests/mesh/MeshContainmentOctreeTest.cpp
+++ b/tests/mesh/MeshContainmentOctreeTest.cpp
@@ -1,15 +1,15 @@
 //======================================================================================================================
 //
-//  This file is part of waLBerla. waLBerla is free software: you can 
+//  This file is part of waLBerla. waLBerla 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.
-//  
-//  waLBerla 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 
+//
+//  waLBerla 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 waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
 //
@@ -43,7 +43,7 @@
 namespace walberla {
 namespace mesh {
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
@@ -72,16 +72,16 @@ int main( int argc, char * argv[] )
   //static const mesh::TriangleMesh::Point xAxis( 1, 0, 0 );
   //static const mesh::TriangleMesh::Point yAxis( 0, 1, 0 );
   //static const mesh::TriangleMesh::Point zAxis( 0, 0, 1 );
-  
+
   mesh::TriangleMesh::Point r = mesh::toOpenMesh( ( aabb.minCorner() - aabb.maxCorner() ).getNormalized() );
-  
+
   WALBERLA_LOG_DEVEL( "Start: r = " << r );
-  
+
   mesh::TriangleMesh::Scalar sLengthOld = std::numeric_limits< mesh::TriangleMesh::Scalar >::max();
   for(int i = 0; i < 100; ++i)
   {
      mesh::TriangleMesh::Point s(0,0,0);
-  
+
      for(auto vh : mesh->vertices())
      {
         const mesh::TriangleMesh::Point & x = mesh->point(vh);
@@ -89,23 +89,23 @@ int main( int argc, char * argv[] )
      }
      const mesh::TriangleMesh::Scalar sLength = s.length();
      r = s / sLength;
-  
+
      const mesh::TriangleMesh::Scalar eps = sLength - sLengthOld;
      WALBERLA_LOG_DEVEL( "Iteration:" << i << " r = " << r << " eps = " << eps );
      sLengthOld = sLength;
   }
 
   auto testVolume = aabb.getScaled( real_t(1.5) ); // AABB containing the test points
-  
+
   auto triDist = make_shared< mesh::TriangleDistance<mesh::TriangleMesh> >( mesh );
   auto distanceOctree = make_shared< DistanceOctree<mesh::TriangleMesh> >( triDist );
   geometry::ContainmentOctree< DistanceOctree<mesh::TriangleMesh> > containmentOctree( distanceOctree );
-  
+
   if( writeVtk )
      containmentOctree.writeVTKOutput( "containment_octree" );
-  
+
   std::mt19937 rng;
-  
+
   for( int i = 0; i < 10000; ++i )
   {
      const auto p = toOpenMesh( testVolume.randomPoint( rng ) );
@@ -113,7 +113,7 @@ int main( int argc, char * argv[] )
      const real_t distance = distanceOctree->sqSignedDistance( p );
      WALBERLA_CHECK_EQUAL( distance <= DistanceOctree<mesh::TriangleMesh>::Scalar(0), isContained, "Point " << std::setprecision(16) << p << " is " << ( isContained ? "inside" : "outside" ) << " but has distance " << distance );
   }
-  
+
   return EXIT_SUCCESS;
 }
 
@@ -124,4 +124,4 @@ int main( int argc, char * argv[] )
 int main( int argc, char * argv[] )
 {
    return walberla::mesh::main( argc, argv );
-}
+}
\ No newline at end of file
diff --git a/tests/mesh/MeshConversionTest.cpp b/tests/mesh/MeshConversionTest.cpp
index 38f0bcca145f2bd7ecb2f269e96acac8381bdeba..6710f1cd1e806f9693811164a82f7c67a7928aba 100644
--- a/tests/mesh/MeshConversionTest.cpp
+++ b/tests/mesh/MeshConversionTest.cpp
@@ -55,7 +55,7 @@ void test()
    WALBERLA_CHECK_EQUAL( convWbMesh.getNumVertices(), convOmMesh.n_vertices() );
 }
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
diff --git a/tests/mesh/MeshDistanceCompareTest.cpp b/tests/mesh/MeshDistanceCompareTest.cpp
index d565f87ca427f6a554975efc3547744825fb373e..828e031161a47a0b569873721c431942acd41375 100644
--- a/tests/mesh/MeshDistanceCompareTest.cpp
+++ b/tests/mesh/MeshDistanceCompareTest.cpp
@@ -64,7 +64,7 @@ void testAABBDistance( const Vector3<real_t> & translationVector = Vector3<real_
 
 }
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
diff --git a/tests/mesh/MeshDistanceOctreeTest.cpp b/tests/mesh/MeshDistanceOctreeTest.cpp
index 00e597fafec090b1f70a6b661954af8db62e453e..26f6ea64020d720dfd97c032d0c8d6a4c70e6048 100644
--- a/tests/mesh/MeshDistanceOctreeTest.cpp
+++ b/tests/mesh/MeshDistanceOctreeTest.cpp
@@ -70,7 +70,7 @@ void test( const std::string & meshFile )
    }
 }
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
diff --git a/tests/mesh/MeshDistancePlausibilityTest.cpp b/tests/mesh/MeshDistancePlausibilityTest.cpp
index 1263b06b38d9bf042f79dc1fa11a6aabc5af4998..3edc84a3c695ecd792e9a76650fe38ab59ec681b 100644
--- a/tests/mesh/MeshDistancePlausibilityTest.cpp
+++ b/tests/mesh/MeshDistancePlausibilityTest.cpp
@@ -51,11 +51,11 @@
 namespace walberla {
 namespace mesh {
 
-typedef field::GhostLayerField< real_t                        , 1 > DistanceField;
-typedef field::GhostLayerField< uint8_t                       , 1 > ErrorMarkerField;
-typedef field::GhostLayerField< mesh::TriangleMesh::FaceHandle, 1 > FaceHandleField;
+using DistanceField = field::GhostLayerField<real_t, 1>;
+using ErrorMarkerField = field::GhostLayerField<uint8_t, 1>;
+using FaceHandleField = field::GhostLayerField<mesh::TriangleMesh::FaceHandle, 1>;
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
diff --git a/tests/mesh/MeshInitilizationHelperTest.cpp b/tests/mesh/MeshInitilizationHelperTest.cpp
index 71c9e41712ec4b02a24925b93669722c843d08c5..a5311b18bc3be74dd4f93b3a87affc46c559417d 100644
--- a/tests/mesh/MeshInitilizationHelperTest.cpp
+++ b/tests/mesh/MeshInitilizationHelperTest.cpp
@@ -67,7 +67,7 @@ void testHelperFunctions( const std::string & meshFile, const uint_t numTotalBlo
 
    WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with createStructuredBlockStorageInsideMesh with block size" );
    auto sbf0 = mesh::createStructuredBlockStorageInsideMesh( distanceOctree, dx, numTotalBlocks );
-   
+
    WALBERLA_LOG_INFO_ON_ROOT( "Creating SBF with createStructuredBlockStorageInsideMesh with block size" );
    Vector3<uint_t> blockSize( sbf0->getNumberOfXCells(), sbf0->getNumberOfYCells(), sbf0->getNumberOfZCells() );
    auto sbf1 = mesh::createStructuredBlockStorageInsideMesh( distanceOctree, dx, blockSize );
@@ -82,7 +82,7 @@ void testHelperFunctions( const std::string & meshFile, const uint_t numTotalBlo
    auto sbf3 = mesh::createStructuredBlockStorageOutsideMesh( exteriorAabb, distanceOctree, dx, blockSize );
 }
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
diff --git a/tests/mesh/MeshInitilizationTest.cpp b/tests/mesh/MeshInitilizationTest.cpp
index 349ed4b711975a83bbd8cb1daefefaba44a61ec1..3a0f2517d134e21e9fa343d794b6560c2aeea7f0 100644
--- a/tests/mesh/MeshInitilizationTest.cpp
+++ b/tests/mesh/MeshInitilizationTest.cpp
@@ -136,7 +136,7 @@ void test( const std::string & meshFile, const uint_t numProcesses, const uint_t
 #endif
 }
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
diff --git a/tests/mesh/MeshMarshalling.cpp b/tests/mesh/MeshMarshalling.cpp
index 53977eb965c1f288fa5d22da77ec8e94654516a6..2acfdd360f62213b3e07e8b088c642f059620505 100644
--- a/tests/mesh/MeshMarshalling.cpp
+++ b/tests/mesh/MeshMarshalling.cpp
@@ -45,7 +45,7 @@ using UnionT = Union<mesh::pe::ConvexPolyhedron>;
 using UnionID = UnionT *;
 using UnionPtr = std::unique_ptr<UnionT>;
 
-typedef std::tuple<mesh::pe::ConvexPolyhedron, UnionT> BodyTuple ;
+using BodyTuple = std::tuple<mesh::pe::ConvexPolyhedron, UnionT> ;
 
 std::vector<Vector3<real_t>> generateOctahedron( const real_t radius)
 {
diff --git a/tests/mesh/MeshOperationsTest.cpp b/tests/mesh/MeshOperationsTest.cpp
index a17d14c7246b1b8fe59c897ead2fe6abf58d0cc9..fb5091b5d1158324aa7085d870b2d9982908c25d 100644
--- a/tests/mesh/MeshOperationsTest.cpp
+++ b/tests/mesh/MeshOperationsTest.cpp
@@ -144,7 +144,7 @@ void testCube()
 
 }
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
diff --git a/tests/mesh/MeshVTKTest.cpp b/tests/mesh/MeshVTKTest.cpp
index e7efb707c8cc82e80d25ec6680e537c525529b6b..39456d7d56b7c3f6f8231579e03d9938faae069c 100644
--- a/tests/mesh/MeshVTKTest.cpp
+++ b/tests/mesh/MeshVTKTest.cpp
@@ -158,7 +158,7 @@ void test( const std::string & meshFile )
 }
 
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
diff --git a/tests/mesh/NumericIntegrationTest.cpp b/tests/mesh/NumericIntegrationTest.cpp
index da1a550884cec967fcd20941480dbaaa00869f87..083b97f88cedd6a16c799989dc6ff7ece57afff9 100644
--- a/tests/mesh/NumericIntegrationTest.cpp
+++ b/tests/mesh/NumericIntegrationTest.cpp
@@ -45,9 +45,9 @@ template< typename ContainmentT >
 real_t volumeNumeric( const ContainmentT & body, const AABB & aabb, const real_t spacing )
 {
    Vector3<real_t> pointOfReference = aabb.min() + Vector3<real_t>( real_t(0.5) * spacing );
-   
+
    uint_t volume = 0;
-   
+
    for(grid_generator::SCIterator it( aabb, pointOfReference, spacing ); it != grid_generator::SCIterator(); ++it)
    {
       if( body.contains( ContainmentT::toPoint( *it ) ) )
@@ -63,7 +63,7 @@ Vector3<real_t> centroidNumeric( const ContainmentT & body, const AABB & aabb, c
 {
    Vector3<real_t> pointOfReference = aabb.min() + Vector3<real_t>( real_t(0.5) * spacing );
 
-   math::KahanAccumulator<real_t> centroid[3];
+   std::array<math::KahanAccumulator<real_t>, 3> centroid;
    uint_t numPoints = 0;
 
    for(grid_generator::SCIterator it( aabb, pointOfReference, spacing ); it != grid_generator::SCIterator(); ++it)
@@ -86,7 +86,7 @@ Matrix3<real_t> inertiaTensorNumeric( const ContainmentT & body, const AABB & aa
 {
    Vector3<real_t> pointOfReference = aabb.min() + Vector3<real_t>( real_t(0.5) * spacing );
 
-   math::KahanAccumulator<real_t> inertiaTensor[6];
+   std::array<math::KahanAccumulator<real_t>, 6> inertiaTensor;
 
    for(grid_generator::SCIterator it( aabb, pointOfReference, spacing ); it != grid_generator::SCIterator(); ++it)
    {
@@ -165,7 +165,7 @@ void testNumeric( const shared_ptr<MeshType> & mesh )
 }
 
 
-int main( int argc, char * argv[] )
+int main( int argc, char ** argv )
 {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
@@ -192,4 +192,4 @@ int main( int argc, char * argv[] )
 int main( int argc, char * argv[] )
 {
    return walberla::mesh::main( argc, argv );
-}
+}
\ No newline at end of file
diff --git a/tests/mesh/OpenMeshBufferTypeExtensionsTest.cpp b/tests/mesh/OpenMeshBufferTypeExtensionsTest.cpp
index 06b9b25e8616855df40598849751d1b6e58cd379..ebe6c5c0054641d3482bd25cd3e899007294fd1f 100644
--- a/tests/mesh/OpenMeshBufferTypeExtensionsTest.cpp
+++ b/tests/mesh/OpenMeshBufferTypeExtensionsTest.cpp
@@ -45,10 +45,10 @@ void test( const T & in )
    WALBERLA_CHECK_EQUAL( in, out );
 }
 
-int main( int /*argc*/, char * /*argv*/[] )
+int main( int /*argc*/, char ** /*argv*/ )
 {
    debug::enterTestMode();
-   
+
    test( OpenMesh::VertexHandle( 42 ) );
    test( OpenMesh::FaceHandle( 42 ) );
    test( OpenMesh::EdgeHandle( 42 ) );
diff --git a/tests/mesh/PeVTKMeshWriterTest.cpp b/tests/mesh/PeVTKMeshWriterTest.cpp
index 07a288a53db005e2257da1d74cca977b68807bed..604974339a7230c79fd5eb71762f9fefb413e28a 100644
--- a/tests/mesh/PeVTKMeshWriterTest.cpp
+++ b/tests/mesh/PeVTKMeshWriterTest.cpp
@@ -51,7 +51,7 @@ using namespace walberla;
 using namespace walberla::pe;
 using namespace walberla::mesh::pe;
 
-typedef std::tuple<ConvexPolyhedron, Plane> BodyTuple ;
+using BodyTuple = std::tuple<ConvexPolyhedron, Plane> ;
 
 std::vector<Vector3<real_t>> generatePointCloudCube()
 {
@@ -145,7 +145,7 @@ int main( int argc, char ** argv )
    cr.setRelaxationParameter( real_t(0.7) );
    cr.setGlobalLinearAcceleration( Vec3(0,0,5) );
 
-   std::function<void(void)> syncCall = std::bind( pe::syncNextNeighbors<BodyTuple>, std::ref(*forest), storageID, static_cast<WcTimingTree*>(nullptr), real_c(0.0), false );
+   std::function<void(void)> syncCall = [&capture0 = *forest, storageID, capture1 = real_c(0.0)] { pe::syncNextNeighbors<BodyTuple>(capture0, storageID, static_cast<WcTimingTree*>(nullptr), capture1, false); };
 
    using OutputMeshType = mesh::FloatPolyMesh;
    using TesselationType = mesh::pe::DefaultTesselation<OutputMeshType>;
diff --git a/tests/mesh/QHullTest.cpp b/tests/mesh/QHullTest.cpp
index f78677d80741f9c4bc87bada4d66e77afc57b09f..a80f3ca84a35dcb749df0c5164b0ca5935375474 100644
--- a/tests/mesh/QHullTest.cpp
+++ b/tests/mesh/QHullTest.cpp
@@ -47,7 +47,7 @@ class PointCloudDataSource : public vtk::PointDataSource
 public:
    PointCloudDataSource( const std::vector<Vector3<real_t>> & pointCloud ) : pointCloud_( pointCloud ) {}
 
-   std::vector< Attributes > getAttributes() const override { return std::vector< Attributes >(); }
+   std::vector< Attributes > getAttributes() const override { return {}; }
    std::vector< Vector3< real_t > > getPoints() override { return pointCloud_; }
    void configure() override {};
 
@@ -71,23 +71,23 @@ void test( const std::string & testName, const std::vector<Vector3<real_t>> & po
    //   ofs << std::setprecision(16) << p[0] << " " << p[1] << " " << p[2] << "\n";
 
    mesh::QHull<MeshType> qhull( pointCloud );
-   
+
    if( doVTKOutput )
    {
       auto pcds = walberla::make_shared<PointCloudDataSource>( pointCloud );
       vtk::createVTKOutput_PointData(pcds, testName + "PointCloud", 1)->write();
-      qhull.enableDebugVTKOutput( testName );   
+      qhull.enableDebugVTKOutput( testName );
    }
 
    WcTimer timer;
    uint_t iterations = qhull.run();
    timer.end();
-   WALBERLA_LOG_INFO( "QHull on \"" << testName << "\":\n" << 
-                      "   Point cloud size: " << pointCloud.size() << "\n" << 
-                      "   Iterations:       " << iterations << "\n" <<                
-                      "   Num hull points:  " << qhull.mesh().n_vertices() << "\n" << 
-                      "   Num hull faces:   " << qhull.mesh().n_faces() << "\n" << 
-                      "   Time:             " << timer.last() << "s\n" <<                   
+   WALBERLA_LOG_INFO( "QHull on \"" << testName << "\":\n" <<
+                      "   Point cloud size: " << pointCloud.size() << "\n" <<
+                      "   Iterations:       " << iterations << "\n" <<
+                      "   Num hull points:  " << qhull.mesh().n_vertices() << "\n" <<
+                      "   Num hull faces:   " << qhull.mesh().n_faces() << "\n" <<
+                      "   Time:             " << timer.last() << "s\n" <<
                       "   VTK output:       " << (doVTKOutput ? "enabled" : "disabled") );
 
    const MeshType & mesh = qhull.mesh();
@@ -158,7 +158,7 @@ std::vector<Vector3<real_t>> generatePointCloudOctahedron()
 std::vector<Vector3<real_t>> generatePointCloudIcosahedron()
 {
    std::vector<Vector3<real_t>> points;
-   
+
    static const real_t PHI = ( real_t(1) + std::sqrt( real_t(5) ) ) / real_t(2);
 
    for( auto one : {real_t(-1), real_t(1)} )
@@ -193,11 +193,11 @@ std::vector<Vector3<real_t>> generatePointCloudDodecahedron()
 std::vector<Vector3<real_t>> generatePointCloudInAABB( const math::AABB & aabb, const uint_t numPoints )
 {
    std::mt19937 rng(42);
-   
+
    std::vector<Vector3<real_t>> pointCloud( numPoints );
    for( auto & p : pointCloud )
       p = aabb.randomPoint(rng);
-   
+
    return pointCloud;
 }
 
@@ -237,8 +237,7 @@ void runTests( const uint_t numPoints, const bool doVTKOutput )
 }
 
 
-int main( int argc, char * argv[] )
-{
+int main( int argc, char ** argv ) {
    debug::enterTestMode();
    mpi::Environment mpiEnv( argc, argv );
    mpi::MPIManager::instance()->useWorldComm();
@@ -265,7 +264,7 @@ int main( int argc, char * argv[] )
    {
       WALBERLA_ABORT_NO_DEBUG_INFO( "USAGE:\n" << args[0] << " [--vtk] [--floatMesh] NUM_POINTS" );
    }
-   
+
    uint_t numPoints;
    try {
       numPoints = std::stoul( args[1] );
diff --git a/tests/pde/BoundaryTest.cpp b/tests/pde/BoundaryTest.cpp
index acc3c3963399144829a5c1a67966a0f12c3a270a..50b1056cead27a971d4cf636ac33b2476d6c613f 100644
--- a/tests/pde/BoundaryTest.cpp
+++ b/tests/pde/BoundaryTest.cpp
@@ -53,16 +53,16 @@ namespace walberla {
 
 
 
-typedef GhostLayerField< real_t, 1 > Field_T;
-typedef stencil::D2Q5                Stencil_T;
-typedef pde::CGIteration<Stencil_T>::StencilField_T  StencilField_T;
+using Field_T = GhostLayerField<real_t, 1>;
+using Stencil_T = stencil::D2Q5;
+using StencilField_T = pde::CGIteration<Stencil_T>::StencilField_T;
 
-typedef walberla::uint8_t      flag_t;
-typedef FlagField < flag_t >   FlagField_T;
-typedef pde::Dirichlet< Stencil_T, flag_t >  Dirichlet_T;
-typedef pde::Neumann< Stencil_T, flag_t >  Neumann_T;
+using flag_t = walberla::uint8_t;
+using FlagField_T = FlagField<flag_t>;
+using Dirichlet_T = pde::Dirichlet<Stencil_T, flag_t>;
+using Neumann_T = pde::Neumann<Stencil_T, flag_t>;
 
-typedef BoundaryHandling< FlagField_T, Stencil_T, Dirichlet_T, Neumann_T > BoundaryHandling_T;
+using BoundaryHandling_T = BoundaryHandling<FlagField_T, Stencil_T, Dirichlet_T, Neumann_T>;
 
 
 const FlagUID  Domain_Flag( "domain" );
@@ -129,10 +129,10 @@ void initRHS( const shared_ptr< StructuredBlockStorage > & blocks, const BlockDa
    {
       Field_T * rhs = block->getData< Field_T >( rhsId );
       CellInterval xyz = rhs->xyzSize();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
-         rhs->get( *cell ) = real_t(4) * math::pi * math::pi * std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
+         rhs->get( cell ) = real_t(4) * math::pi * math::pi * std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
       }
    }
 }
@@ -145,9 +145,9 @@ void setRHSConstValue( const shared_ptr< StructuredBlockStorage > & blocks, cons
    {
       Field_T * rhs = block->getData< Field_T >( rhsId );
       CellInterval xyz = rhs->xyzSize();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
-         rhs->get( *cell ) = value;
+         rhs->get( cell ) = value;
       }
    }
 }
@@ -174,13 +174,13 @@ void setBoundaryConditionsDirichl( shared_ptr< StructuredBlockForest > & blocks,
       CellInterval north( domainBB.xMin(), domainBB.yMax(), domainBB.zMin(), domainBB.xMax(), domainBB.yMax(), domainBB.zMax() );
 
       // Set north boundary to defined function
-      for( auto cell = north.begin(); cell != north.end(); ++cell )
+      for(auto cell : north)
       {
 
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
          real_t val = std::sin( real_t( 2 ) * math::pi * p[0] ) * std::sinh( real_t( 2 ) * math::pi * p[1] );
 
-         boundaryHandling->forceBoundary( Dirichlet_Flag, cell->x(), cell->y(), cell->z(), pde::Dirichlet< Stencil_T, flag_t >::DirichletBC( val ) );
+         boundaryHandling->forceBoundary( Dirichlet_Flag, cell.x(), cell.y(), cell.z(), pde::Dirichlet< Stencil_T, flag_t >::DirichletBC( val ) );
 
       }
 
@@ -217,20 +217,20 @@ void setBoundaryConditionsMixed( shared_ptr< StructuredBlockForest > & blocks, c
       CellInterval north( domainBB.xMin(), domainBB.yMax(), domainBB.zMin(), domainBB.xMax(), domainBB.yMax(), domainBB.zMax() );
 
       // Set north boundary to large value
-      for( auto cell = north.begin(); cell != north.end(); ++cell )
+      for(auto cell : north)
       {
 
          const real_t val = real_t(2);
-         boundaryHandling->forceBoundary( Dirichlet_Flag, cell->x(), cell->y(), cell->z(), pde::Dirichlet< Stencil_T, flag_t >::DirichletBC( val ) );
+         boundaryHandling->forceBoundary( Dirichlet_Flag, cell.x(), cell.y(), cell.z(), pde::Dirichlet< Stencil_T, flag_t >::DirichletBC( val ) );
 
       }
 
       // Set south boundary to large value
-      for( auto cell = south.begin(); cell != south.end(); ++cell )
+      for(auto cell : south)
       {
 
          const real_t val = real_t(-2);
-         boundaryHandling->forceBoundary( Dirichlet_Flag, cell->x(), cell->y(), cell->z(), pde::Dirichlet< Stencil_T, flag_t >::DirichletBC( val ) );
+         boundaryHandling->forceBoundary( Dirichlet_Flag, cell.x(), cell.y(), cell.z(), pde::Dirichlet< Stencil_T, flag_t >::DirichletBC( val ) );
 
       }
 
diff --git a/tests/pde/CGTest.cpp b/tests/pde/CGTest.cpp
index 810811e693ad4676a04935f4b174a2104aa0662b..1a6ed48185bbc4cb199d07738d234d1c626162e6 100644
--- a/tests/pde/CGTest.cpp
+++ b/tests/pde/CGTest.cpp
@@ -48,7 +48,7 @@ namespace walberla {
 
 
 
-typedef GhostLayerField< real_t, 1 > PdeField_T;
+using PdeField_T = GhostLayerField<real_t, 1>;
 using Stencil_T = stencil::D2Q5;
 using StencilField_T = pde::CGIteration<Stencil_T>::StencilField_T;
 
@@ -63,10 +63,10 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
          PdeField_T * u = block->getData< PdeField_T >( uId );
          CellInterval xyz = u->xyzSizeWithGhostLayer();
          xyz.yMin() = xyz.yMax();
-         for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+         for(auto cell : xyz)
          {
-            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
-            u->get( *cell ) = std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
+            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
+            u->get( cell ) = std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
          }
       }
    }
@@ -80,10 +80,10 @@ void initF( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
    {
       PdeField_T * f = block->getData< PdeField_T >( fId );
       CellInterval xyz = f->xyzSize();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
-         f->get( *cell ) = real_t(4) * math::pi * math::pi * std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
+         f->get( cell ) = real_t(4) * math::pi * math::pi * std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
       }
    }
 }
diff --git a/tests/pde/JacobiTest.cpp b/tests/pde/JacobiTest.cpp
index fda36b2f1dd238108318ecd12d5c91a61782a04f..c2534fc5fa6496ae8042ca70adf8bbad8090f871 100644
--- a/tests/pde/JacobiTest.cpp
+++ b/tests/pde/JacobiTest.cpp
@@ -51,7 +51,7 @@ namespace walberla {
 
 
 
-typedef GhostLayerField< real_t, 1 > PdeField_T;
+using PdeField_T = GhostLayerField<real_t, 1>;
 using Stencil_T = stencil::D2Q5;
 using StencilField_T = pde::Jacobi<Stencil_T>::StencilField_T;
 
@@ -67,11 +67,11 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
          PdeField_T * dst = block->getData< PdeField_T >( dstId );
          CellInterval xyz = src->xyzSizeWithGhostLayer();
          xyz.yMin() = xyz.yMax();
-         for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+         for(auto cell : xyz)
          {
-            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
-            src->get( *cell ) = std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
-            dst->get( *cell ) = std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
+            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
+            src->get( cell ) = std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
+            dst->get( cell ) = std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
          }
       }
    }
@@ -85,10 +85,10 @@ void initF( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
    {
       PdeField_T * f = block->getData< PdeField_T >( fId );
       CellInterval xyz = f->xyzSize();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
-         f->get( *cell ) = real_t(4) * math::pi * math::pi * std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
+         f->get( cell ) = real_t(4) * math::pi * math::pi * std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
       }
    }
 }
diff --git a/tests/pde/MGConvergenceTest.cpp b/tests/pde/MGConvergenceTest.cpp
index a7f3902d1e7ed523d017a2eebe6163d2d7a69332..cb2e15841b2ac17acde8745d1809efd9a6996b79 100644
--- a/tests/pde/MGConvergenceTest.cpp
+++ b/tests/pde/MGConvergenceTest.cpp
@@ -48,7 +48,7 @@ namespace walberla {
 
 
 
-typedef GhostLayerField< real_t, 1 > PdeField_T;
+using PdeField_T = GhostLayerField<real_t, 1>;
 using Stencil_T = stencil::D3Q7;
 using StencilField_T = pde::VCycles<Stencil_T>::StencilField_T;
 
@@ -71,11 +71,11 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
    {
       PdeField_T * u = block->getData< PdeField_T >( uId );
       CellInterval xyz = u->xyzSizeWithGhostLayer();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
          math::seedRandomGenerator( static_cast<unsigned int>( (p[0] * real_t(blocks->getNumberOfXCells()) + p[1]) * real_t(blocks->getNumberOfYCells()) + p[2]) );
-         u->get( *cell ) = math::realRandom( real_t(-10), real_t(10) );
+         u->get( cell ) = math::realRandom( real_t(-10), real_t(10) );
       }
    }
     
@@ -88,9 +88,9 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
     {
         PdeField_T * u = block->getData< PdeField_T >( uId );
         CellInterval xyz = u->xyzSize();
-        for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+        for(auto cell : xyz)
         {
-            sum += u->get( *cell );
+            sum += u->get( cell );
             ++numCells;
         }
     }
@@ -106,9 +106,9 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
     {
         PdeField_T * u = block->getData< PdeField_T >( uId );
         CellInterval xyz = u->xyzSizeWithGhostLayer();
-        for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+        for(auto cell : xyz)
         {
-            u->get( *cell ) -= domainMeanVal;
+            u->get( cell ) -= domainMeanVal;
         }
     }
 
@@ -148,23 +148,23 @@ void initURect( const shared_ptr< StructuredBlockStorage > & blocks, const Block
                     real_t(0.5)*(real_c(globalNumCells[0]) + cuboidSize[0]), real_t(0.5)*(real_c(globalNumCells[1]) + cuboidSize[1]), real_t(0.5)*(real_c(globalNumCells[2]) + cuboidSize[2])
    );
 
-   pde::Zeroize(blocks, uId);
+   pde::Zeroize zeroize_u(blocks, uId);
 
    // Initializing non-zero block with a given value in center of domain, relative to domain extension
    for( auto block = blocks->begin(); block != blocks->end(); ++block )
    {
       PdeField_T * u = block->getData< PdeField_T >( uId );
       CellInterval xyz = u->xyzSize();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
          // get global coordinate of current cell
          Cell globalCoordCell;
-         blocks->transformBlockLocalToGlobalCell( globalCoordCell, *block, *cell );
+         blocks->transformBlockLocalToGlobalCell( globalCoordCell, *block, cell );
 
          // set values in cuboid
          if(cuboidAABB.contains(real_c(globalCoordCell[0]),real_c(globalCoordCell[1]),real_c(globalCoordCell[2]))) {
-            u->get( *cell ) = cuboidValue;
-            sumCuboidValues += u->get( *cell );
+            u->get( cell ) = cuboidValue;
+            sumCuboidValues += u->get( cell );
          }
          ++numCells;
       }
@@ -185,9 +185,9 @@ void initURect( const shared_ptr< StructuredBlockStorage > & blocks, const Block
    {
       PdeField_T * u = block->getData< PdeField_T >( uId );
       CellInterval xyz = u->xyzSize();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
-         u->get( *cell ) -= domainMeanVal;
+         u->get( cell ) -= domainMeanVal;
       }
    }
 
diff --git a/tests/pde/MGTest.cpp b/tests/pde/MGTest.cpp
index 3ab49d9c22976b0c320a9b7a92e5caec86da9fbf..3a8854bc444b913f24fa7de0d7b46bc5e19e6d37 100644
--- a/tests/pde/MGTest.cpp
+++ b/tests/pde/MGTest.cpp
@@ -49,7 +49,7 @@ namespace walberla {
 
 
 
-typedef GhostLayerField< real_t, 1 > PdeField_T;
+using PdeField_T = GhostLayerField<real_t, 1>;
 using Stencil_T = stencil::D3Q7;
 using StencilField_T = pde::VCycles<Stencil_T>::StencilField_T;
 
@@ -63,12 +63,12 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
    {
       PdeField_T * u = block->getData< PdeField_T >( uId );
       CellInterval xyz = u->xyzSizeWithGhostLayer();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
          math::seedRandomGenerator( static_cast<unsigned int>( (p[0] * real_t(blocks->getNumberOfXCells()) + p[1]) * real_t(blocks->getNumberOfYCells()) + p[2] ) );
-         u->get( *cell ) = math::realRandom( real_t(-10), real_t(10) );
-         sum += u->get( *cell );
+         u->get( cell ) = math::realRandom( real_t(-10), real_t(10) );
+         sum += u->get( cell );
       }
    }
    WALBERLA_UNUSED(sum);
@@ -130,9 +130,9 @@ void checkProlongateRestrict( const shared_ptr< StructuredBlockStorage > & block
       f2c( &*block );
       
       CellInterval xyz = coarse->xyzSize();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
-         WALBERLA_CHECK_FLOAT_EQUAL(coarse->get(*cell), orig->get(*cell), "Restrict-after-Prolongate should be an identity operation");
+         WALBERLA_CHECK_FLOAT_EQUAL(coarse->get(cell), orig->get(cell), "Restrict-after-Prolongate should be an identity operation");
       }
    }
 
diff --git a/tests/pde/RBGSTest.cpp b/tests/pde/RBGSTest.cpp
index a3d89f7c57f534ad5d68da4e5ab665edcbac5220..55cb5a97639f84cd4abeb5c03962ea4c6bd2eadc 100644
--- a/tests/pde/RBGSTest.cpp
+++ b/tests/pde/RBGSTest.cpp
@@ -51,7 +51,7 @@ namespace walberla {
 
 
 
-typedef GhostLayerField< real_t, 1 > PdeField_T;
+using PdeField_T = GhostLayerField<real_t, 1>;
 using Stencil_T = stencil::D2Q5;
 using StencilField_T = pde::RBGS<Stencil_T>::StencilField_T;
 
@@ -66,10 +66,10 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
          PdeField_T * u = block->getData< PdeField_T >( uId );
          CellInterval xyz = u->xyzSizeWithGhostLayer();
          xyz.yMin() = xyz.yMax();
-         for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+         for(auto cell : xyz)
          {
-            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
-            u->get( *cell ) = std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
+            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
+            u->get( cell ) = std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
          }
       }
    }
@@ -83,10 +83,10 @@ void initF( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
    {
       PdeField_T * f = block->getData< PdeField_T >( fId );
       CellInterval xyz = f->xyzSize();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
-         f->get( *cell ) = real_t(4) * math::pi * math::pi * std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
+         f->get( cell ) = real_t(4) * math::pi * math::pi * std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
       }
    }
 }
diff --git a/tests/pde/SORTest.cpp b/tests/pde/SORTest.cpp
index df1eedf6ceceec6f0ac7f2fb0a063f400253dfaf..42ec60fb0b0068fdd299bc0c2d5aa6a74364b1f7 100644
--- a/tests/pde/SORTest.cpp
+++ b/tests/pde/SORTest.cpp
@@ -51,7 +51,7 @@ namespace walberla {
 
 
 
-typedef GhostLayerField< real_t, 1 > PdeField_T;
+using PdeField_T = GhostLayerField<real_t, 1>;
 using Stencil_T = stencil::D2Q5;
 using StencilField_T = pde::SOR<Stencil_T>::StencilField_T;
 
@@ -66,10 +66,10 @@ void initU( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
          PdeField_T * u = block->getData< PdeField_T >( uId );
          CellInterval xyz = u->xyzSizeWithGhostLayer();
          xyz.yMin() = xyz.yMax();
-         for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+         for(auto cell : xyz)
          {
-            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
-            u->get( *cell ) = std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
+            const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
+            u->get( cell ) = std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
          }
       }
    }
@@ -83,10 +83,10 @@ void initF( const shared_ptr< StructuredBlockStorage > & blocks, const BlockData
    {
       PdeField_T * f = block->getData< PdeField_T >( fId );
       CellInterval xyz = f->xyzSize();
-      for( auto cell = xyz.begin(); cell != xyz.end(); ++cell )
+      for(auto cell : xyz)
       {
-         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, *cell );
-         f->get( *cell ) = real_t(4) * math::pi * math::pi * std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
+         const Vector3< real_t > p = blocks->getBlockLocalCellCenter( *block, cell );
+         f->get( cell ) = real_t(4) * math::pi * math::pi * std::sin( real_t(2) * math::pi * p[0] ) * std::sinh( real_t(2) * math::pi * p[1] );
       }
    }
 }
diff --git a/tests/postprocessing/SphereTriangulate.cpp b/tests/postprocessing/SphereTriangulate.cpp
index b74985465fa0d1aeef787a0bfc241b8cc8794672..1c1d5de16b82f9d1919a28348d86b0721c1959a0 100644
--- a/tests/postprocessing/SphereTriangulate.cpp
+++ b/tests/postprocessing/SphereTriangulate.cpp
@@ -38,7 +38,7 @@ using namespace postprocessing;
 
 using geometry::TriangleMesh;
 
-typedef GhostLayerField<real_t,1> ScalarField;
+using ScalarField = GhostLayerField<real_t, 1>;
 
 
 template< typename T, uint_t fs>
diff --git a/utilities/CMakeLists.txt b/utilities/CMakeLists.txt
index db4ad89267a86e777e93ffe895423a4a92527656..6fb1d71140a04814fac2e5d908b1459e2b9f8186 100644
--- a/utilities/CMakeLists.txt
+++ b/utilities/CMakeLists.txt
@@ -1 +1 @@
-waLBerla_link_files_to_builddir( filterCompileCommands.py )
+waLBerla_link_files_to_builddir( clang-tidy )
diff --git a/utilities/clang-tidy/README.md b/utilities/clang-tidy/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c5b4d185e6d43be1cbb5b1528a068d420a2cfdc1
--- /dev/null
+++ b/utilities/clang-tidy/README.md
@@ -0,0 +1,81 @@
+# Using clang-tidy on waLBerla
+
+See also the [Clang-Tidy Documentation](https://clang.llvm.org/extra/clang-tidy/).
+
+This document briefly explains how to run a clang-tidy analysis and (auto-)fixing pass on the waLBerla code base.
+
+## tl;dr
+
+ 1. Set up build system: `cmake --preset clang-tidy`
+ 2. Navigate to `build/clang-tidy`
+ 3. Run this command: `python utilities/clang-tidy/analyze.py -p utilities/clang-tidy/analyze.yml -c compile_commands.json -r ../..`
+ 4. Inspect the results
+ 5. Fix the errors; if applicable, use the autofixing feature.
+
+
+## Set up CMake
+
+To run clang-tidy, CMake needs to be configured to emit a compile command data base which clang-tidy
+reads to figure out which files, with which compilation options, it should analyze.
+Also, the build system should be set up in Debug mode with additional debugging features enabled
+such that all debug code paths can be covered.
+
+Here is a sample `CMakeUserPresets.json` with a configure preset called `clang-tidy`, which defines
+a build system that can be used for clang-tidy analysis:
+
+```JSON
+{
+  "version": 6,
+  "cmakeMinimumRequired": {
+    "major": 3,
+    "minor": 23,
+    "patch": 0
+  },
+  "configurePresets": [
+    {
+      "name": "clang-tidy",
+      "generator": "Unix Makefiles",
+      "binaryDir": "${sourceDir}/build/clang-tidy",
+      "cacheVariables": {
+        "CMAKE_EXPORT_COMPILE_COMMANDS": true,
+        "WALBERLA_BUFFER_DEBUG": true,
+        "WALBERLA_BUILD_TESTS": true,
+        "WALBERLA_BUILD_BENCHMARKS": true,
+        "WALBERLA_BUILD_TUTORIALS": true,
+        "WALBERLA_BUILD_TOOLS": true,
+        "WALBERLA_BUILD_WITH_MPI": true,
+        "WALBERLA_BUILD_WITH_OPENMP": true,
+        "CMAKE_BUILD_TYPE": "Debug",
+        "WALBERLA_BUILD_WITH_METIS": true,
+        "WALBERLA_BUILD_WITH_PARMETIS": true,
+        "WALBERLA_BUILD_WITH_OPENMESH": true,
+        "WALBERLA_DOUBLE_ACCURACY": true,
+        "WALBERLA_LOGLEVEL": "DETAIL"
+      }
+    },
+  ]
+}
+```
+
+The above configuration:
+ - requires that *OpenMesh* is installed - if you do not plan on analyzing the `mesh_common` and `mesh` modules,
+   you can set `WALBERLA_BUILD_WITH_OPENMESH` to `false`.
+ - requires that *Metis* and *ParMetis* are installed - if you do not plan to analyze the Metis-dependent code
+   in `core` and `blockforest`, you can set `WALBERLA_BUILD_WITH_METIS` and `WALBERLA_BUILD_WITH_PARMETIS` to `false`.
+ - prepares the build system also for tests, benchmarks and tutorials - if you do not wish to analyze those, you can exlude them.
+
+This preset is contained in the `CMakePresets.json` file. To generate the build system defined by it, run `cmake --preset clang-tidy`.
+
+## Run the Analysis
+
+We provide the `analyze.py` script in this directory to automate the clang-tidy analysis of the waLBerla code base.
+For an overview of its options, run `python analyze.py --help`.
+
+To run the full analysis pass, with your shell located in the waLBerla project root directory, you can use the following command:
+
+```
+python utilities/clang-tidy/analyze.py -p utilities/clang-tidy/analyze.yml -c build/clang-tidy/compile_commands.json
+```
+
+In there, the `-p` option specifies the parameter file, and the `-c` option says where to find the compile database.
+You can specify a custom parameter file to restrict the set of modules and apps to be analyzed.
diff --git a/utilities/clang-tidy/analyze.py b/utilities/clang-tidy/analyze.py
new file mode 100644
index 0000000000000000000000000000000000000000..ff74f2771d73abc910f40882b41a9416a95152f2
--- /dev/null
+++ b/utilities/clang-tidy/analyze.py
@@ -0,0 +1,296 @@
+"""
+Script performing fully automated clang-tidy analysis runs
+on the waLBerla repository.
+"""
+
+import pathlib
+import re
+import sys
+import argparse
+import yaml
+import json
+import shutil
+import subprocess
+from collections import Counter
+from textwrap import indent
+
+
+def removePrecompiler(x):
+    pos = x.find("clang++")
+    if pos != -1:
+        return x[pos:]
+    else:
+        return x
+
+
+def get_directory_filter(include_dirs: list[pathlib.Path]):
+    absolute_dirs: list[pathlib.Path] = []
+    for src_dir in include_dirs:
+        if not src_dir.exists():
+            raise ValueError(f"Source directory {src_dir} does not exist")
+
+        absolute_dirs.append(src_dir.absolute())
+
+    def filter(entry: dict):
+        fp = pathlib.Path(entry["file"])
+        return any(fp.is_relative_to(d) for d in absolute_dirs)
+
+    return filter
+
+
+def remove_duplicate_commands(db: list):
+    seen_files: set[str] = set()
+
+    db_filtered = []
+    for x in db:
+        if x["file"] not in seen_files:
+            seen_files.add(x["file"])
+            db_filtered.append(x)
+    return db_filtered
+
+
+WARNING_PATTERN = re.compile(r"\[[a-z-]+,-warnings-as-errors\]\n")
+TRAILING = len(",-warnings-as-errors]\n")
+
+
+def count_diagnostics(output_file: pathlib.Path) -> Counter:
+    clang_tidy_log = output_file.read_text()
+    matches = WARNING_PATTERN.findall(clang_tidy_log)
+    matches = [m[1:-TRAILING] for m in matches]
+    counts = Counter(matches)
+
+    return counts
+
+
+def print_summary(counts: Counter):
+    counts = sorted(list(counts.items()), key=lambda it: it[1], reverse=True)
+    summary = "\n".join(f"{warning}: {count}" for warning, count in counts)
+    return summary
+
+
+def main():
+    parser = argparse.ArgumentParser("analyze.py")
+
+    parser.add_argument(
+        "-p",
+        "--parameter-file",
+        dest="parameter_file",
+        type=str,
+        default=None,
+        help="Parameter file that defines which modules and apps should be analyzed.",
+    )
+    parser.add_argument(
+        "-m",
+        "--modules",
+        dest="modules",
+        type=str,
+        nargs="*",
+        default=None,
+        help="Modules to be analyzed. Overrides modules listed in the parameter file."
+    )
+    parser.add_argument(
+        "-a",
+        "--apps",
+        dest="apps",
+        type=str,
+        nargs="*",
+        default=None,
+        help="Apps to be analyzed. Overrides apps listed in the parameter file."
+    )
+    parser.add_argument(
+        "-r",
+        "--project-root",
+        dest="project_root",
+        type=str,
+        default=".",
+        help="waLBerla project root directory. If not specified, use the current directory.",
+    )
+    parser.add_argument(
+        "-c",
+        "--compile-database",
+        required=True,
+        dest="compile_database",
+        type=str,
+        help="Path to the CMake compile command data base.",
+    )
+    parser.add_argument(
+        "-o",
+        "--output-directory",
+        dest="output_directory",
+        type=str,
+        default="./clang-tidy-output",
+        help="Folder to which the error streams from clang-tidy should be written.",
+    )
+    parser.add_argument(
+        "--checks",
+        dest="checks",
+        type=str,
+        default=None,
+        nargs="+",
+        help="clang-tidy checks filter. Forwarded to -checks argument of clang-tidy."
+    )
+    parser.add_argument(
+        "--export-fixes",
+        dest="export_fixes",
+        action="store_true",
+        help="Export possible fixes detected by clang-tidy to a YAML file in the output directory"
+    )
+
+    args = parser.parse_args()
+
+    walberla_root = pathlib.Path(args.project_root).resolve()
+    src_dir = walberla_root / "src"
+    tests_dir = walberla_root / "tests"
+    apps_dir = walberla_root / "apps"
+
+    output_dir = pathlib.Path(args.output_directory)
+
+    database_fp = pathlib.Path(args.compile_database)
+    database_backup = database_fp.parent / f"{database_fp.name}.bak"
+    shutil.copy(str(database_fp), str(database_backup))
+
+    success: bool = True
+    total_counts = Counter()
+
+    try:
+        with database_fp.open() as dbfile:
+            orig_db = json.load(dbfile)
+
+        if args.parameter_file is not None:
+            parameter_filepath = pathlib.Path(args.parameter_file)
+            with parameter_filepath.open() as pfile:
+                params = yaml.load(pfile, yaml.SafeLoader)
+        else:
+            params = dict()
+
+        if args.modules:
+            params["modules"] = args.modules
+
+        if args.apps:
+            params["apps"] = args.apps
+
+        build_dir = database_fp.parent
+        clang_tidy_base_args = ["run-clang-tidy", "-p", str(build_dir)]
+
+        def run_clang_tidy(
+            database: list,
+            include_dirs: list[pathlib.Path],
+            header_filter: str | None,
+            output: pathlib.Path,
+            info: str,
+        ):
+            print(f"Analyzing {info}")
+
+            try:
+                dir_filter = get_directory_filter(include_dirs)
+            except ValueError as e:
+                print(e, file=sys.stderr)
+                return False
+
+            cc_filtered = list(filter(dir_filter, database))
+            for x in cc_filtered:
+                x["command"] = removePrecompiler(x["command"])
+
+            cc_filtered = remove_duplicate_commands(cc_filtered)
+
+            print(f"  -- Retained {len(cc_filtered)} compile commands")
+
+            with database_fp.open("w") as db_out:
+                json.dump(cc_filtered, db_out)
+
+            clang_tidy_args = clang_tidy_base_args
+            if header_filter:
+                clang_tidy_args += ["-header-filter", header_filter]
+            if args.checks:
+                checks_str = ",".join(args.checks)
+                clang_tidy_args += [f"-checks={checks_str}"]
+            if args.export_fixes:
+                fixes_file = output.parent / "fixes.yaml"
+                clang_tidy_args += [f"-export-fixes={str(fixes_file)}"]
+            output.parent.mkdir(exist_ok=True, parents=True)
+
+            errfile = output.with_name(output.name + ".err")
+
+            print("  -- Running clang-tidy...")
+            with output.open("w") as ofile:
+                with errfile.open("w") as efile:
+                    subprocess.run(clang_tidy_args, stdout=ofile, stderr=efile)
+
+            print(f"  -- clang-tidy output written to {str(output)}")
+
+            counts = count_diagnostics(output)
+            total_counts.update(counts)
+
+            if counts.total() == 0:
+                print("  -- Success!")
+            else:
+                summary = print_summary(counts)
+
+                print("  -- Summary:")
+                print(indent(summary, "      - "))
+
+            print("\n\n", end="")
+            return counts.total() == 0
+
+        for module_spec in params.get("modules", []):
+            include_paths: list[pathlib.Path] = []
+            module_name: str
+            match module_spec:
+                case str():
+                    module_name = module_spec
+                    include_paths = [src_dir / module_name, tests_dir / module_name]
+                case dict():
+                    module_name, settings = next(iter(module_spec.items()))
+                    include_paths = [src_dir / module_name]
+                    if not settings.get("exclude-tests", False):
+                        include_paths.append(tests_dir / module_name)
+            header_filter = rf".*/src/{module_name}/.*"
+
+            succ = run_clang_tidy(
+                orig_db,
+                include_paths,
+                header_filter,
+                output_dir / "modules" / f"{module_name}.out",
+                f"module {module_name}",
+            )
+            success = succ and success
+
+        for app_spec in params.get("apps", []):
+            include_paths: list[pathlib.Path]
+            app_name: str
+
+            match app_spec:
+                case str():
+                    app_name = app_spec
+                    include_paths = [apps_dir / app_name]
+                case dict():
+                    app_name, settings = next(iter(app_spec.items()))
+                    if (only := settings.get("only", None)) is not None:
+                        include_paths = [apps_dir / app_name / o for o in only]
+                    else:
+                        include_paths = [apps_dir / app_name]
+
+            succ = run_clang_tidy(
+                orig_db,
+                include_paths,
+                None,
+                output_dir / "apps" / f"{app_name}.out",
+                f"application {app_name}",
+            )
+
+            success = succ and success
+
+    finally:
+        #   Restore the backup
+        shutil.move(str(database_backup), str(database_fp))
+
+    print(f"Done. Total number of diagnostics: {total_counts.total()}")
+    print()
+    print("Summary:")
+    print(indent(print_summary(total_counts), "  - "))
+
+    exit(0 if success else 1)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/utilities/clang-tidy/analyze.yml b/utilities/clang-tidy/analyze.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1936ec7a423f33e5390873bd27ff0d94b4080e50
--- /dev/null
+++ b/utilities/clang-tidy/analyze.yml
@@ -0,0 +1,38 @@
+modules:
+  - core
+  - domain_decomposition
+  - blockforest
+  - boundary
+  - communication:
+      exclude-tests: true
+  - field
+  - fft
+  - geometry
+  - gpu
+  - lbm_mesapd_coupling
+  - mesh
+  - mesh_common:
+      exclude-tests: true
+  - postprocessing
+  - sqlite
+  - stencil
+  - timeloop
+  - vtk:
+      exclude-tests: true
+
+apps:
+  - "benchmarks/AdaptiveMeshRefinementFluidParticleCoupling"
+  - "benchmarks/ComplexGeometry"
+  - "benchmarks/CouetteFlow"
+  - "benchmarks/FieldCommunication"
+  - "benchmarks/FluidizedBed"
+  - "benchmarks/Percolation"
+  - "benchmarks/PoiseuilleChannel"
+  - "benchmarks/ProbeVsExtraMessage"
+  - "benchmarks/UniformGridCPU"
+  - "benchmarks/NonUniformGridCPU"
+  - "benchmarks/SchaeferTurek"
+  - "showcases/FluidizedBed"
+  - "showcases/Piping"
+  - "tutorials"
+  # to be extended
\ No newline at end of file
diff --git a/utilities/clang-tidy/clangTidySummary.py b/utilities/clang-tidy/clangTidySummary.py
new file mode 100644
index 0000000000000000000000000000000000000000..21f228b2e842ea6b676085037246233be1564425
--- /dev/null
+++ b/utilities/clang-tidy/clangTidySummary.py
@@ -0,0 +1,22 @@
+from collections import Counter
+from argparse import ArgumentParser
+import pathlib
+import re
+import pprint
+
+# WARNING_PATTERN = re.compile(r"\[([^[]+)(?:,-warnings-as-errors)?\]\n")
+WARNING_PATTERN = re.compile(r"\[[a-z-]+,-warnings-as-errors\]\n")
+TRAILING = len(",-warnings-as-errors]\n")
+
+if __name__ == "__main__":
+    parser = ArgumentParser()
+    parser.add_argument("clang_tidy_output", type=str)
+    args = parser.parse_args()
+
+    output_fp = pathlib.Path(args.clang_tidy_output)
+    clang_tidy_log = output_fp.read_text()
+    matches = WARNING_PATTERN.findall(clang_tidy_log)
+    matches = [m[1:-TRAILING] for m in matches]
+    counter = Counter(matches)
+
+    pprint.pp(counter)
diff --git a/utilities/filterCompileCommands.py b/utilities/clang-tidy/filterCompileCommands.py
similarity index 100%
rename from utilities/filterCompileCommands.py
rename to utilities/clang-tidy/filterCompileCommands.py