diff --git a/.clang-tidy b/.clang-tidy
index 935443d1ec5ae2344604710b3070a1a4abd3812a..910df6702f383cffe304c4d4a1b770670027868b 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -11,6 +11,7 @@ bugprone-*,
 
 misc-*,
 -misc-misplaced-const,
+-misc-no-recursion,
 -misc-non-private-member-variables-in-classes,
 
 modernize-*,
@@ -43,17 +44,21 @@ readability-deleted-default,
 readability-isolate-declaration,
 readability-misleading-indentation,
 readability-misplaced-array-index,
+readability-non-const-parameter,
+readability-redundant-access-specifiers,
 readability-redundant-control-flow,
 readability-redundant-declaration,
 readability-redundant-function-ptr-dereference,
 readability-redundant-preprocessor,
 readability-redundant-smartptr-get,
 readability-redundant-string-cstr,
+readability-simplify-boolean-expr,
 readability-simplify-subscript-expr,
 readability-static-accessed-through-instance,
 readability-static-definition-in-anonymous-namespace,
 readability-string-compare,
-readability-uniqueptr-delete-release
+readability-uniqueptr-delete-release,
+readability-use-anyofallof
 
 '
 WarningsAsErrors: '*'
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5c7bc78b1c2d5c68b3811cd9b7ed1751eb2eedcc..ceef61aeb70cbc54bdbfb88822d2185fc5607fe8 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1959,7 +1959,7 @@ doc:
 ###############################################################################
 
 clang-tidy:
-   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:10.0
+   image: i10git.cs.fau.de:5005/walberla/buildenvs/clang:11.0
    script:
       - $CXX --version
       - clang-tidy -version
@@ -2481,4 +2481,4 @@ benchmark_ClangBuildAnalyzer:
     - docker-benchmark
   only:
      variables:
-        - $ENABLE_NIGHTLY_BUILDS
\ No newline at end of file
+        - $ENABLE_NIGHTLY_BUILDS
diff --git a/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp b/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp
index c5f1df93e544ed8a16f5ae802caa21268fc438a7..631625909b21548fa4f23c7e5b5f5702bcec7960 100644
--- a/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp
+++ b/apps/benchmarks/NonUniformGrid/NonUniformGrid.cpp
@@ -308,7 +308,7 @@ void createSetupBlockForest( blockforest::SetupBlockForest & sforest, const Conf
    const memory_t memoryLimit = configBlock.getParameter< memory_t >( "memoryLimit", numeric_cast< memory_t >(256) );
 
    sforest.balanceLoad( blockforest::StaticLevelwiseCurveBalance(true), numberOfProcesses, bufferProcesses, memoryLimit, true,
-                        (bufferProcesses != uint_t(0)) ? true : false );
+                        bufferProcesses != uint_t(0) );
 
    WALBERLA_LOG_INFO_ON_ROOT( "SetupBlockForest created successfully:\n" << sforest );
 }
diff --git a/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp b/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp
index b72efbdcbfb90a2502523e3fff73122f36f2f65c..f5695a0f50a6fb9736dd19dac9da6671a2e9c217 100644
--- a/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp
+++ b/apps/benchmarks/PoiseuilleChannel/PoiseuilleChannel.cpp
@@ -265,9 +265,7 @@ private:
       {
          const auto d = block.getAABB().sqSignedDistance( forest.getDomain().center() );
          const real_t r = setup_.radius_L + bufferDistance_;
-         if( d > (r * r) )
-            return true;
-         return false;
+         return d > (r * r);
       }
 
       return false;
diff --git a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
index 50c3a9244da51ae3fa5dfec97d5b928ca8f56ced..c49dafff07a5b1ed2c24670d6c2fcc583f143048 100644
--- a/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
+++ b/apps/benchmarks/SchaeferTurek/SchaeferTurek.cpp
@@ -1318,9 +1318,9 @@ public:
                     "cD (real area) [5], cL (real area) [6], cD (discrete area) [7], cL (discrete area) [8], "
                     "pressure difference (in lattice units) [9], pressure difference (in Pa) [10], vortex velocity (in lattice units) [11], "
                     "Strouhal number (real D) [12], Strouhal number (discrete D) [13]" << std::endl;
-            if( setup_.evaluatePressure == false )
+            if( !setup_.evaluatePressure )
                file << "# ATTENTION: pressure was not evaluated, pressure difference is set to zero!" << std::endl;
-            if( setup_.evaluateStrouhal == false )
+            if( !setup_.evaluateStrouhal )
                file << "# ATTENTION: vortex velocities were not evaluated, Strouhal number is set to zero!" << std::endl;
             file.close();
          }
diff --git a/apps/showcases/CombinedResolvedUnresolved/CombinedResolvedUnresolved.cpp b/apps/showcases/CombinedResolvedUnresolved/CombinedResolvedUnresolved.cpp
index 8b0779629654e8e34cb856cf81bcd155ffef87f7..5f4336e493e3ee5e0ac73e52d2e621dd6c2b6c33 100644
--- a/apps/showcases/CombinedResolvedUnresolved/CombinedResolvedUnresolved.cpp
+++ b/apps/showcases/CombinedResolvedUnresolved/CombinedResolvedUnresolved.cpp
@@ -265,10 +265,7 @@ bool selectDPMBodies(pe::BodyID bodyID)
 {
    pe::SphereID sphere = static_cast< pe::SphereID >(bodyID);
    real_t radius       = sphere->getRadius();
-   if (radius <= real_t(0.5))
-      return true;
-   else
-      return false;
+   return radius <= real_t(0.5);
 }
 
 bool selectMEMBodies(pe::BodyID bodyID) { return !selectDPMBodies(bodyID); }
diff --git a/src/blockforest/SetupBlock.cpp b/src/blockforest/SetupBlock.cpp
index 391012997f330f75d07c2853354db39f5d6cd625..5b822acc18c5e19f3672c7f25b134594942ff2d9 100644
--- a/src/blockforest/SetupBlock.cpp
+++ b/src/blockforest/SetupBlock.cpp
@@ -37,7 +37,7 @@ void SetupBlock::assembleNeighborhood() {
 
    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 == true )
+         if( neighborhood.insert( neighborhoodSection_[n][i] ).second )
             neighborhood_.push_back( neighborhoodSection_[n][i] );
 }
 
diff --git a/src/core/cell/CellInterval.cpp b/src/core/cell/CellInterval.cpp
index 83ab0e33df531b98fc0505d05213e31ed3066457..c4df1ea31a656338691e4752ca8829150461eda7 100644
--- a/src/core/cell/CellInterval.cpp
+++ b/src/core/cell/CellInterval.cpp
@@ -49,13 +49,10 @@ bool CellInterval::overlaps( const CellVector& cellVector ) const
    if( empty() )
       return false;
 
-   for( const Cell & cell : cellVector )
-   {
-      if( this->contains( cell ) )
-         return true;
-   }
-
-   return false;
+   return std::any_of(cellVector.begin(),
+                      cellVector.end(),
+                      [&](const Cell & cell)
+                      {return contains( cell );});
 }
 
 
diff --git a/src/core/grid_generator/HCPIterator.cpp b/src/core/grid_generator/HCPIterator.cpp
index 6be206c66dffd3a5c3f346fc1e5d2489a182524d..7d136ef4250ca823fd95ec11d913a85c1577d60b 100644
--- a/src/core/grid_generator/HCPIterator.cpp
+++ b/src/core/grid_generator/HCPIterator.cpp
@@ -168,14 +168,7 @@ bool HCPIterator::operator==(const HCPIterator &rhs) const
 {
    if (ended_ || rhs.ended_)
    {
-      if (ended_ == rhs.ended_)
-      {
-         return true;
-      }
-      else
-      {
-         return false;
-      }
+      return ended_ == rhs.ended_;
    }
 
 //   WALBERLA_ASSERT_FLOAT_EQUAL(aabb_, rhs.aabb_, "Comparing iterators for different starting configurations!");
diff --git a/src/core/grid_generator/SCIterator.cpp b/src/core/grid_generator/SCIterator.cpp
index 6c4399a6489ab85d22d647f3e84516685d07e680..254f97214cdb476bd3b2b882281fe44719a1df91 100644
--- a/src/core/grid_generator/SCIterator.cpp
+++ b/src/core/grid_generator/SCIterator.cpp
@@ -115,14 +115,7 @@ bool SCIterator::operator==(const SCIterator &rhs) const
 {
    if (ended_ || rhs.ended_)
    {
-      if (ended_ == rhs.ended_)
-      {
-         return true;
-      }
-      else
-      {
-         return false;
-      }
+      return ended_ == rhs.ended_;
    }
 
 //   WALBERLA_ASSERT_FLOAT_EQUAL(aabb_, rhs.aabb_, "Comparing iterators for different starting configurations!");
diff --git a/src/mesa_pd/collision_detection/EPA.cpp b/src/mesa_pd/collision_detection/EPA.cpp
index 3fb4ced431d587865cd0e5a454979823c2d31988..ef5f217808f21dd5c23f24d5deb0083e0f69d165 100644
--- a/src/mesa_pd/collision_detection/EPA.cpp
+++ b/src/mesa_pd/collision_detection/EPA.cpp
@@ -362,11 +362,7 @@ bool EPA::doEPA( Support &geom1,
                      penetrationDepth = -supp_dist + real_t(2.0) * margin;
                      retNormal = -ctr;
                      
-                     if(penetrationDepth < contactThreshold){
-                        return true;
-                     }else{
-                        return false;
-                     }
+                     return penetrationDepth < contactThreshold;
                   } else {
                      //Reject sphere
                      removeSupportMargin(epaVolume, supportA, supportB);
@@ -500,12 +496,7 @@ bool EPA::doEPA( Support &geom1,
    std::cerr << "entryHeap[0]->getSqrDist()=" << entryHeap[0]->getSqrDist() << std::endl;*/
    //std::cout << "EPA penetration depth: " << penetrationDepth <<  std::endl;
 
-   if(penetrationDepth < contactThreshold) {
-      return true;
-   }
-
-   //no intersection found!
-   return false;
+   return penetrationDepth < contactThreshold;
 }
 //*************************************************************************************************
 
@@ -722,11 +713,7 @@ inline bool EPA::originInTetrahedron( const Vec3& p0, const Vec3& p1, const Vec3
       return false;
    }
    Vec3 normal3T = (p0 -p3) % (p1-p3);
-   if( (normal3T*p3 > real_t(0.0)) == (normal3T*p2 > real_t(0.0)) ) {
-      return false;
-   }
-
-   return true;
+   return (normal3T*p3 > real_t(0.0)) != (normal3T*p2 > real_t(0.0));
 }
 //*************************************************************************************************
 
diff --git a/src/mesa_pd/domain/BlockForestDomain.cpp b/src/mesa_pd/domain/BlockForestDomain.cpp
index cf530527087b6ac5cf8a487c10f29fec0d392285..c4d15778de5b10e7c38b5c81ad175e7a36643715 100644
--- a/src/mesa_pd/domain/BlockForestDomain.cpp
+++ b/src/mesa_pd/domain/BlockForestDomain.cpp
@@ -127,11 +127,10 @@ bool BlockForestDomain::isContainedInProcessSubdomain(const uint_t rank, const V
 bool   BlockForestDomain::isContainedInLocalSubdomain(const Vec3& pt,
                                                       const real_t& radius) const
 {
-   for (auto& aabb : localAABBs_)
-   {
-      if (isInsideAABB(pt, radius, aabb)) return true;
-   }
-   return false;
+   return std::any_of(localAABBs_.begin(),
+                      localAABBs_.end(),
+                      [&](auto& aabb)
+                      {return isInsideAABB(pt, radius, aabb);});
 }
 
 bool BlockForestDomain::isContainedInProcessSubdomain(const Vec3& pt, const real_t& radius) const
@@ -153,12 +152,11 @@ bool BlockForestDomain::isContainedInProcessSubdomain(const Vec3& pt, const real
    }
 
    //intersects one of the neighboring subdomains?
-   for (auto& subdomain : neighborSubdomains_)
-   {
-      if (sqDistancePointToAABB(pt, subdomain.aabb) < radius*radius) return false;
-   }
-
-   return true;
+   return std::none_of(neighborSubdomains_.begin(),
+                       neighborSubdomains_.end(),
+                       [&](const auto &subdomain) {
+                          return sqDistancePointToAABB(pt, subdomain.aabb) < radius * radius;
+                       });
 }
 
 int BlockForestDomain::findContainingProcessRank(const Vec3& pt) const
diff --git a/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp b/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
index ed500565e0281fed065d40c96126e85dfa0c6cb6..2b505e09bde0060b510ce2e6eb746665358558f1 100644
--- a/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
+++ b/src/mesh/pe/rigid_body/ConvexPolyhedron.cpp
@@ -297,16 +297,17 @@ bool ConvexPolyhedron::containsRelPointImpl( real_t px, real_t py, real_t pz ) c
    if( px * px + py * py + pz * pz > boundingSphereRadius_ * boundingSphereRadius_ )
       return false;
 
-   for(auto fh : mesh_.faces())
-   {
-      const TriangleMesh::Normal & n = mesh_.normal(fh); // Plane normal
-      const TriangleMesh::Point & pp = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(fh))); // Point on plane
-
-      if( n[0] * (px - pp[0]) + n[1] * (py - pp[1]) + n[2] * (pz - pp[2]) >= real_t(0) )
-         return false;
-   }
-
-   return true;
+   return std::none_of(mesh_.faces().begin(),
+                       mesh_.faces().end(),
+                       [&](auto fh)
+                       {
+                          //check if point is on positive side of the face
+                          const TriangleMesh::Normal &n = mesh_.normal(fh); // Plane normal
+                          const TriangleMesh::Point &pp = mesh_.point(
+                                mesh_.to_vertex_handle(mesh_.halfedge_handle(fh))); // Point on plane
+
+                          return (n[0] * (px - pp[0]) + n[1] * (py - pp[1]) + n[2] * (pz - pp[2]) >= real_t(0));
+                       });
 }
 //*************************************************************************************************
 
diff --git a/src/pe/collision/EPA.cpp b/src/pe/collision/EPA.cpp
index 6e7eb97551070580c1686139876341868d5923d7..171dc85949828e61adb9df099c7141867b6a93fc 100644
--- a/src/pe/collision/EPA.cpp
+++ b/src/pe/collision/EPA.cpp
@@ -350,11 +350,7 @@ bool EPA::doEPA( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec
                      penetrationDepth = -supp_dist + real_t(2.0) * margin;
                      retNormal = -ctr;
                      
-                     if(penetrationDepth < contactThreshold){
-                        return true;
-                     }else{
-                        return false;
-                     }
+                     return penetrationDepth < contactThreshold;
                   } else {
                      //Reject sphere
                      removeSupportMargin(epaVolume, supportA, supportB);
@@ -488,12 +484,7 @@ bool EPA::doEPA( GeomPrimitive &geom1, GeomPrimitive &geom2, const GJK& gjk, Vec
    std::cerr << "entryHeap[0]->getSqrDist()=" << entryHeap[0]->getSqrDist() << std::endl;*/
    //std::cout << "EPA penetration depth: " << penetrationDepth <<  std::endl;
 
-   if(penetrationDepth < contactThreshold) {
-      return true;
-   }
-
-   //no intersection found!
-   return false;
+   return penetrationDepth < contactThreshold;
 }
 //*************************************************************************************************
 
@@ -705,11 +696,7 @@ inline bool EPA::originInTetrahedron( const Vec3& p0, const Vec3& p1, const Vec3
       return false;
    }
    Vec3 normal3T = (p0 -p3) % (p1-p3);
-   if( (normal3T*p3 > real_t(0.0)) == (normal3T*p2 > real_t(0.0)) ) {
-      return false;
-   }
-
-   return true;
+   return (normal3T*p3 > real_t(0.0)) != (normal3T*p2 > real_t(0.0));
 }
 //*************************************************************************************************
 
diff --git a/src/pe/raytracing/Raytracer.cpp b/src/pe/raytracing/Raytracer.cpp
index 631a5dfd3384bba103c8b5cd2381acad40d0cd5d..344b8af9938271e05aa5af4f97fe10b6095642f4 100644
--- a/src/pe/raytracing/Raytracer.cpp
+++ b/src/pe/raytracing/Raytracer.cpp
@@ -31,7 +31,7 @@ namespace walberla {
 namespace pe {
 namespace raytracing {
    
-void BodyIntersectionInfo_Comparator_MPI_OP( BodyIntersectionInfo *in, BodyIntersectionInfo *inout, int *len, MPI_Datatype *dptr) {
+void BodyIntersectionInfo_Comparator_MPI_OP( BodyIntersectionInfo *in, BodyIntersectionInfo *inout, const int *len, MPI_Datatype *dptr) {
    WALBERLA_UNUSED(dptr);
    for (int i = 0; i < *len; ++i) {
       if (in->bodySystemID != 0 && inout->bodySystemID != 0) {
diff --git a/src/vtk/VTKOutput.cpp b/src/vtk/VTKOutput.cpp
index 8d8cf88f14bfa4bf4899629d0d85f787e1b6146d..345d4fda3c980210f4b035867ea23e001017b915 100644
--- a/src/vtk/VTKOutput.cpp
+++ b/src/vtk/VTKOutput.cpp
@@ -458,7 +458,7 @@ void VTKOutput::computeOutputPoints( std::vector<Vector3<real_t> > & points, std
    outputPoint.assign( points.size(), true );
    for( uint_t i = 0; i != points.size(); ++i )
    {
-      bool included = ( aabbInclusionFilters_.empty() ) ? true : false;
+      bool included = aabbInclusionFilters_.empty();
       for( auto aabb = aabbInclusionFilters_.begin(); aabb != aabbInclusionFilters_.end() && !included; ++aabb )
          if( aabb->contains( points[ i ][ 0 ], points[ i ][ 1 ], points[ i ][ 2 ] ) ) included = true;
       if( !included )
@@ -665,7 +665,7 @@ void VTKOutput::computeOutputPolylines( std::vector< std::vector< Vector3< real_
       auto outputPointIt = outputPolylinePointIt->begin();
       for( auto pointIt = polylineIt->begin(); pointIt != polylineIt->end(); ++pointIt, ++outputPointIt )
       {
-         bool included = ( aabbInclusionFilters_.empty() ) ? true : false;
+         bool included = aabbInclusionFilters_.empty();
          for( auto aabb = aabbInclusionFilters_.begin(); aabb != aabbInclusionFilters_.end() && !included; ++aabb )
             if( aabb->contains( ( *pointIt )[ 0 ], ( *pointIt )[ 1 ], ( *pointIt )[ 2 ] ) ) included = true;
          if( !included )