diff --git a/.clang-tidy b/.clang-tidy
index f0e5933ad55dc18c06f14f2c6ef06dc3226eda22..82f5bf5e014019d937b0a37a47cfa8feb6a5b264 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -4,16 +4,30 @@ Checks:          '
 -*,
 
 boost-*,
+-boost-use-ranges,
 
 bugprone-*,
 -bugprone-branch-clone,
 -bugprone-exception-escape,
 -bugprone-easily-swappable-parameters,
+-bugprone-crtp-constructor-accessibility,
+-bugprone-implicit-widening-of-multiplication-result,
+-bugprone-macro-parentheses,
+-bugprone-narrowing-conversions,
+-bugprone-switch-missing-default-case,
+-bugprone-assignment-in-if-condition,
+-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,
 
 modernize-*,
 -modernize-use-auto,
@@ -23,12 +37,17 @@ modernize-*,
 -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-macro-to-enum,
 -modernize-avoid-c-arrays,
 -modernize-concat-nested-namespaces,
 -modernize-use-nodiscard,
+-modernize-type-traits,
 
 mpi-*,
 -mpi-type-mismatch,
@@ -38,18 +57,19 @@ openmp-*,
 -openmp-use-default-none,
 
 performance-*,
+-performance-enum-size,
+-performance-noexcept-swap,
+-performance-move-const-arg,
+-performance-unnecessary-value-param,
+-performance-avoid-endl,
 
 portability-*,
 
-readability-const-return-type,
 readability-container-size-empty,
 readability-delete-null-pointer,
 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,
diff --git a/python/pystencils_walberla/templates/CpuPackInfo.tmpl.cpp b/python/pystencils_walberla/templates/CpuPackInfo.tmpl.cpp
index 0191994f3f3a29ef9384b2a2270294be9df59f43..15c5d7bef76b9b51d310ec0a823a4a61c24df833 100644
--- a/python/pystencils_walberla/templates/CpuPackInfo.tmpl.cpp
+++ b/python/pystencils_walberla/templates/CpuPackInfo.tmpl.cpp
@@ -117,7 +117,7 @@ uint_t {{class_name}}::size(stencil::Direction dir, const IBlock * block) const
     CellInterval ci;
     {{field_name}}->getGhostRegion(dir, ci, 1, false);
 
-    uint_t elementsPerCell = 0;
+    uint_t elementsPerCell = uint_t{ 0u };
 
     switch( dir )
     {
@@ -125,11 +125,11 @@ uint_t {{class_name}}::size(stencil::Direction dir, const IBlock * block) const
         {%- for dir in direction_set %}
         case stencil::{{dir}}:
         {%- endfor %}
-            elementsPerCell = {{elements}};
+            elementsPerCell = uint_t{ {{elements}}u };
             break;
         {% endfor %}
         default:
-            elementsPerCell = 0;
+            elementsPerCell = uint_t{ 0u };
     }
     return ci.numCells() * elementsPerCell * sizeof( {{dtype}} );
 }
diff --git a/python/pystencils_walberla/templates/GpuPackInfo.tmpl.cpp b/python/pystencils_walberla/templates/GpuPackInfo.tmpl.cpp
index 48440b5b4366204157b0486cadf5c14295dbfcc0..6a385fa851f525155d5f919c6de14868627aa11a 100644
--- a/python/pystencils_walberla/templates/GpuPackInfo.tmpl.cpp
+++ b/python/pystencils_walberla/templates/GpuPackInfo.tmpl.cpp
@@ -17,6 +17,13 @@
 //! \\author pystencils
 //======================================================================================================================
 
+#include "core/DataTypes.h"
+#include "core/cell/CellInterval.h"
+
+#include "domain_decomposition/IBlock.h"
+
+#include "stencil/Directions.h"
+
 #include "{{class_name}}.h"
 
 {% if target is equalto 'cpu' -%}
diff --git a/python/pystencils_walberla/templates/GpuPackInfo.tmpl.h b/python/pystencils_walberla/templates/GpuPackInfo.tmpl.h
index fd8fbd90f70d037722521dc869454775f819adba..820c6b8bec516e12f504230024207804d013fec1 100644
--- a/python/pystencils_walberla/templates/GpuPackInfo.tmpl.h
+++ b/python/pystencils_walberla/templates/GpuPackInfo.tmpl.h
@@ -20,7 +20,6 @@
 #pragma once
 
 #include "core/DataTypes.h"
-#include "core/cell/CellInterval.h"
 
 #include "domain_decomposition/IBlock.h"
 
diff --git a/src/core/Set.h b/src/core/Set.h
index cbc0d5c1196404f4fb71d72492c40a7a326b03c2..de9ca7841336a1282ee99322c0b210830bfa7d46 100644
--- a/src/core/Set.h
+++ b/src/core/Set.h
@@ -130,7 +130,7 @@ public:
 
    inline size_t size() const { return set_.size(); }
 
-   inline void swap( Set<T>& set ) { set_.swap( set.set_ ); }
+   inline void swap( Set<T>& set ) noexcept { set_.swap( set.set_ ); }
 
           void        toStream( std::ostream& os ) const;
    inline std::string toString() const;
diff --git a/src/core/StringUtility.impl.h b/src/core/StringUtility.impl.h
index 02b5f3937216ea5345368505ef8664ec53b1eb34..ac3b298875a0676a5311ca8bac2873f5f1a703d5 100644
--- a/src/core/StringUtility.impl.h
+++ b/src/core/StringUtility.impl.h
@@ -21,8 +21,6 @@
 
 #pragma once
 
-#include "core/StringUtility.h"
-
 #include <algorithm>
 #include <cctype>
 #include <string>
diff --git a/src/core/cell/CellInterval.h b/src/core/cell/CellInterval.h
index 7b766fa3763bb890aca15b5f5c31e6891c54ee7d..6019ac71ce9a188998e7c13e463796f18df0336c 100644
--- a/src/core/cell/CellInterval.h
+++ b/src/core/cell/CellInterval.h
@@ -236,6 +236,7 @@ inline bool CellInterval::overlaps( const CellInterval& other ) const
    if( empty() || other.empty() )
       return false;
 
+   // NOLINTNEXTLINE(readability-simplify-boolean-expr)
    return !(other.min_.x() > max_.x() || other.min_.y() > max_.y() || other.min_.z() > max_.z() ||
        other.max_.x() < min_.x() || other.max_.y() < min_.y() || other.max_.z() < min_.z());
 }
diff --git a/src/core/debug/PrintStacktrace.cpp b/src/core/debug/PrintStacktrace.cpp
index 94f2aa89b34c307b5da5f7b54685f7dc7a4ad0b9..43464e3270503759a7dbc1377bc096227005ead4 100644
--- a/src/core/debug/PrintStacktrace.cpp
+++ b/src/core/debug/PrintStacktrace.cpp
@@ -109,7 +109,7 @@ namespace debug {
 
          os << "\t" << appName << " \t " << demangled << endl;
       }
-      free (strings);
+      free (reinterpret_cast<void*>(strings));
    }
 
 
diff --git a/src/core/math/Matrix2.h b/src/core/math/Matrix2.h
index 308108649ce4d6583194c73521824be91c99d638..3827333a4aef26fe1c2db7599724181b6df78a84 100644
--- a/src/core/math/Matrix2.h
+++ b/src/core/math/Matrix2.h
@@ -323,7 +323,7 @@ inline Matrix2<Type>& Matrix2<Type>::operator=( Type set )
 // Explicit definition of a copy assignment operator for performance reasons.
 */
 template< typename Type >
-inline Matrix2<Type>& Matrix2<Type>::operator=( const Matrix2& set )
+inline Matrix2<Type>& Matrix2<Type>::operator=( const Matrix2& set ) // NOLINT(bugprone-unhandled-self-assignment)
 {
    // This implementation is faster than the synthesized default copy assignment operator and
    // faster than an implementation with the C library function 'memcpy' in combination with a
@@ -347,7 +347,7 @@ inline Matrix2<Type>& Matrix2<Type>::operator=( const Matrix2& set )
 */
 template< typename Type >
 template< typename Other >
-inline Matrix2<Type>& Matrix2<Type>::operator=( const Matrix2<Other>& set )
+inline Matrix2<Type>& Matrix2<Type>::operator=( const Matrix2<Other>& set ) // NOLINT(bugprone-unhandled-self-assignment)
 {
    // This implementation is faster than the synthesized default copy assignment operator and
    // faster than an implementation with the C library function 'memcpy' in combination with a
diff --git a/src/core/math/extern/exprtk.h b/src/core/math/extern/exprtk.h
index 3173ad3db1dede59b07d9ea01e6470ee00fc5b9a..6ec5d55a179fcdbec935e0e920104157eff4b031 100644
--- a/src/core/math/extern/exprtk.h
+++ b/src/core/math/extern/exprtk.h
@@ -45,6 +45,7 @@
 #include <deque>
 #include <exception>
 #include <functional>
+#include <initializer_list>
 #include <iterator>
 #include <limits>
 #include <list>
@@ -893,13 +894,13 @@ namespace exprtk
             inline T equal_impl(const T v0, const T v1, real_type_tag)
             {
                const T epsilon = epsilon_type<T>::value();
-               return (abs_impl(v0 - v1,real_type_tag()) <= (std::max(T(1),std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? T(1) : T(0);
+               return (abs_impl(v0 - v1,real_type_tag()) <= (std::max({T(1),abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag())}) * epsilon)) ? T(1) : T(0);
             }
 
             inline float equal_impl(const float v0, const float v1, real_type_tag)
             {
                const float epsilon = epsilon_type<float>::value();
-               return (abs_impl(v0 - v1,real_type_tag()) <= (std::max(1.0f,std::max(abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag()))) * epsilon)) ? 1.0f : 0.0f;
+               return (abs_impl(v0 - v1,real_type_tag()) <= (std::max({1.0f,abs_impl(v0,real_type_tag()),abs_impl(v1,real_type_tag())}) * epsilon)) ? 1.0f : 0.0f;
             }
 
             template <typename T>
@@ -929,14 +930,14 @@ namespace exprtk
             {
                typedef real_type_tag rtg;
                const T epsilon = epsilon_type<T>::value();
-               return (abs_impl(v0 - v1,rtg()) > (std::max(T(1),std::max(abs_impl(v0,rtg()),abs_impl(v1,rtg()))) * epsilon)) ? T(1) : T(0);
+               return (abs_impl(v0 - v1,rtg()) > (std::max({T(1),abs_impl(v0,rtg()),abs_impl(v1,rtg())}) * epsilon)) ? T(1) : T(0);
             }
 
             inline float nequal_impl(const float v0, const float v1, real_type_tag)
             {
                typedef real_type_tag rtg;
                const float epsilon = epsilon_type<float>::value();
-               return (abs_impl(v0 - v1,rtg()) > (std::max(1.0f,std::max(abs_impl(v0,rtg()),abs_impl(v1,rtg()))) * epsilon)) ? 1.0f : 0.0f;
+               return (abs_impl(v0 - v1,rtg()) > (std::max({1.0f,abs_impl(v0,rtg()),abs_impl(v1,rtg())}) * epsilon)) ? 1.0f : 0.0f;
             }
 
             template <typename T>
@@ -5208,7 +5209,7 @@ namespace exprtk
             return std::numeric_limits<T>::quiet_NaN();
          }
 
-         inline virtual expression_node<T>* branch(const std::size_t& index = 0) const
+         inline virtual expression_node<T>* branch([[maybe_unused]] const std::size_t& index = 0) const
          {
             return static_cast<expression_ptr>(nullptr);
          }
@@ -6356,7 +6357,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -6416,7 +6417,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -6479,7 +6480,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -6523,7 +6524,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -7796,7 +7797,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(index_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(index_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -12006,7 +12007,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -14888,6 +14889,8 @@ namespace exprtk
       {
       public:
 
+         ~T0oT1oT2oT3_sf4() override = default;
+
          typedef typename details::functor_t<T> functor_t;
          typedef typename functor_t::qfunc_t      qfunc_t;
          typedef T value_type;
@@ -15282,7 +15285,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -15338,7 +15341,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -15405,7 +15408,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -15472,7 +15475,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -16039,7 +16042,7 @@ namespace exprtk
 
          void collect_nodes(typename expression_node<T>::noderef_list_t& node_delete_list) override
          {
-            expression_node<T>::ndb_t::template collect(branch_, node_delete_list);
+            expression_node<T>::ndb_t::template collect<>(branch_, node_delete_list);
          }
 
          std::size_t node_depth() const override
@@ -18084,7 +18087,7 @@ namespace exprtk
             return false;
          else if (symbol_exists(vector_name))
             return false;
-         else if (0 == v.size())
+         else if (v.empty())
             return false;
          else
             return local_data().vector_store.add(vector_name,v);
@@ -18098,7 +18101,7 @@ namespace exprtk
             return false;
          else if (symbol_exists(vector_name))
             return false;
-         else if (0 == v.size())
+         else if (v.empty())
             return false;
          else
             return local_data().vector_store.add(vector_name,v);
@@ -18584,10 +18587,7 @@ namespace exprtk
                }
             }
 
-            if (results)
-            {
-               delete results;
-            }
+            delete results;
          }
 
          static inline control_block* create(expression_ptr e)
@@ -21418,7 +21418,9 @@ namespace exprtk
 
                end_token = current_token();
 
+               #ifdef exprtk_enable_debugging
                const std::string sub_expr = construct_subexpr(begin_token, end_token);
+               #endif
 
                exprtk_debug(("parse_corpus(%02d) Subexpr: %s\n",
                              static_cast<int>(arg_list.size() - 1),
diff --git a/src/core/mpi/BufferSystem.impl.h b/src/core/mpi/BufferSystem.impl.h
index 3715a7ea9f3daf95c0bde6163954ca72159e48d3..b927d242daa869ec294916f0991c6a94e5bce88d 100644
--- a/src/core/mpi/BufferSystem.impl.h
+++ b/src/core/mpi/BufferSystem.impl.h
@@ -165,21 +165,24 @@ GenericBufferSystem<Rb, Sb> & GenericBufferSystem<Rb, Sb>::operator=( const Gene
 {
    WALBERLA_ASSERT( !communicationRunning_, "Can't copy GenericBufferSystem while communication is running" )
 
-   sizeChangesEverytime_ = other.sizeChangesEverytime_;
-   communicationRunning_ = other.communicationRunning_;
-   recvInfos_ = other.recvInfos_;
-   sendInfos_ = other.sendInfos_;
+   if (&other != this)
+   {
+      sizeChangesEverytime_ = other.sizeChangesEverytime_;
+      communicationRunning_ = other.communicationRunning_;
+      recvInfos_ = other.recvInfos_;
+      sendInfos_ = other.sendInfos_;
 
-   if( other.currentComm_ == &other.knownSizeComm_ )
-      currentComm_ = &knownSizeComm_;
-   else if ( other.currentComm_ == &other.unknownSizeComm_ )
-      currentComm_ = &unknownSizeComm_;
-   else if ( other.currentComm_ == &other.unknownSizeCommIProbe_ )
-      currentComm_ = &unknownSizeCommIProbe_;
-   else if ( other.currentComm_ == &other.noMPIComm_ )
-      currentComm_ = &noMPIComm_;
-   else
-      currentComm_ = nullptr; // receiver information not yet set
+      if( other.currentComm_ == &other.knownSizeComm_ )
+         currentComm_ = &knownSizeComm_;
+      else if ( other.currentComm_ == &other.unknownSizeComm_ )
+         currentComm_ = &unknownSizeComm_;
+      else if ( other.currentComm_ == &other.unknownSizeCommIProbe_ )
+         currentComm_ = &unknownSizeCommIProbe_;
+      else if ( other.currentComm_ == &other.noMPIComm_ )
+         currentComm_ = &noMPIComm_;
+      else
+         currentComm_ = nullptr; // receiver information not yet set
+   }
 
    return *this;
 }
diff --git a/src/core/timing/TimingNode.h b/src/core/timing/TimingNode.h
index 0b6326e71096625d30ab69b2c850702473f7c04c..404feb7d5a2308e4f2131f111e0bc8ffd6e87998 100644
--- a/src/core/timing/TimingNode.h
+++ b/src/core/timing/TimingNode.h
@@ -97,8 +97,11 @@ TimingNode<TP>::TimingNode(const TimingNode<TP>& tn)
 template< typename TP >  // Timing policy
 TimingNode<TP>& TimingNode<TP>::operator=(const TimingNode<TP>& tn)
 {
-   TimingNode<TP> tmp (tn);
-   tmp.swap(*this);
+   if (&tn != this)
+   {
+      TimingNode<TP> tmp (tn);
+      tmp.swap(*this);
+   }
    return *this;
 }
 
diff --git a/src/core/uid/UIDGenerators.h b/src/core/uid/UIDGenerators.h
index 265beeaac89babc29eade08b85a6012157f5377d..3d715c9de807582197070fbc64ca87662b812cac 100644
--- a/src/core/uid/UIDGenerators.h
+++ b/src/core/uid/UIDGenerators.h
@@ -275,11 +275,11 @@ public:
 
    static uint_type firstUID() { return 1; }
 
-   static uint_type nextUID( const uint_type /*uid*/ ) { WALBERLA_ASSERT( false ); return 1; }
+   static uint_type nextUID( [[maybe_unused]] const uint_type uid ) { WALBERLA_ASSERT( false ); return 1; }
 
-   static uint_type toIndex( const uint_type uid ) { WALBERLA_ASSERT_EQUAL( uid, 1 ); return 0; }
+   static uint_type toIndex( [[maybe_unused]] const uint_type uid ) { WALBERLA_ASSERT_EQUAL( uid, 1 ); return 0; }
 
-   static uint_type toBitMask( const uint_type uid ) { WALBERLA_ASSERT_EQUAL( uid, 1 ); return 1; }
+   static uint_type toBitMask( [[maybe_unused]] const uint_type uid ) { WALBERLA_ASSERT_EQUAL( uid, 1 ); return 1; }
 
    static const char* getType() { static const char* const type = "singleton generator"; return type; }
 
diff --git a/src/core/waLBerlaBuildInfo.in.cpp b/src/core/waLBerlaBuildInfo.in.cpp
index 65fa8887d9c2dec1d6f6e81a3c3a4295f0c687af..29efeaa8fb012fb0417334602e2071d63eaba622 100644
--- a/src/core/waLBerlaBuildInfo.in.cpp
+++ b/src/core/waLBerlaBuildInfo.in.cpp
@@ -5,6 +5,7 @@
  */
 //======================================================================================================================
 
+#include "core/waLBerlaBuildInfo.h"
 
 namespace walberla {
 namespace core {
diff --git a/src/domain_decomposition/IBlock.h b/src/domain_decomposition/IBlock.h
index ef563cc057b2e9157330420f09beb1ad74050168..c31763eb3a8d686dd6af93ed46775e92cb1fe17f 100644
--- a/src/domain_decomposition/IBlock.h
+++ b/src/domain_decomposition/IBlock.h
@@ -100,8 +100,8 @@ public:
    template< typename U >
    const U* get() const {
       try { thr_(ptr_); }
-      catch ( U* ptr ) { return ptr; }
-      catch (...) {}
+      catch ( U* ptr ) { return ptr; } // NOLINT(misc-throw-by-value-catch-by-reference)
+      catch (...) {} // NOLINT(bugprone-empty-catch)
 #ifndef NDEBUG
       WALBERLA_ABORT( "BlockData access type violation! (The block data you added is of a different type than the block data you are trying to access!)"
                       "\nThe original data type was:       " << debug::demangle( typeInfo_ ) <<
@@ -135,8 +135,8 @@ public:
    template< typename U >
    bool isClassOrSubclassOf() const {
       try { thr_(ptr_); }
-      catch ( U* ) { return true; }
-      catch (...) {}
+      catch ( U* ) { return true; } // NOLINT(misc-throw-by-value-catch-by-reference)
+      catch (...) {} // NOLINT(bugprone-empty-catch)
       return false;
    }
 
@@ -156,7 +156,9 @@ private:
 #  pragma warning( disable : 4670 )
 #  pragma warning( disable : 4673 )
 #endif //_MSC_VER
-   template< typename T > static void thrower( void* ptr ) { throw static_cast< T* >( ptr ); }
+   template< typename T > static void thrower( void* ptr ) {
+      throw static_cast< T* >( ptr ); // NOLINT(misc-throw-by-value-catch-by-reference)
+   }
 #ifdef _MSC_VER
 #  pragma warning(pop)
 #endif //_MSC_VER
diff --git a/src/field/adaptors/GhostLayerFieldAdaptor.h b/src/field/adaptors/GhostLayerFieldAdaptor.h
index 13ac8f0e289b6bf5300ac70647816a44dbb034f1..e7e4d630a6ed1ea327de70709af98ad3588b3c03 100644
--- a/src/field/adaptors/GhostLayerFieldAdaptor.h
+++ b/src/field/adaptors/GhostLayerFieldAdaptor.h
@@ -302,7 +302,7 @@ typename GhostLayerFieldAdaptor<Functor,glD>::const_iterator GhostLayerFieldAdap
 
 template< typename Functor, uint_t glD >
 typename GhostLayerFieldAdaptor<Functor,glD>::const_iterator GhostLayerFieldAdaptor<Functor,glD>::beginGhostLayerOnlyXYZ(
-         stencil::Direction dir, cell_idx_t f ) const
+         stencil::Direction dir, cell_idx_t /*f*/ ) const
 {
    CellInterval ci;
    getGhostRegion(dir,ci);
@@ -326,7 +326,7 @@ typename GhostLayerFieldAdaptor<Functor,glD>::const_iterator GhostLayerFieldAdap
 
 template< typename Functor, uint_t glD >
 typename GhostLayerFieldAdaptor<Functor,glD>::const_iterator GhostLayerFieldAdaptor<Functor,glD>::beginSliceBeforeGhostLayerXYZ(
-         stencil::Direction dir, cell_idx_t width, cell_idx_t f) const
+         stencil::Direction dir, cell_idx_t width, cell_idx_t /*f*/) const
 {
    CellInterval ci;
    getSliceBeforeGhostLayer(dir,ci,width);
diff --git a/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h b/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h
index e154678f0afb0392184d144a8ebe98389cf6bde4..dd5a376ee4649ed4c01a388902c624a23664afc8 100644
--- a/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h
+++ b/src/geometry/initializer/BoundarySetterFlagFieldSpecialization.h
@@ -109,13 +109,13 @@ namespace initializer {
    }
 
    template<typename Flag_T>
-   void BoundarySetter<FlagField<Flag_T> >::setBoundaryConfigBlock( const BoundaryUID & boundaryUID, const Config::BlockHandle & blockHandle )
+   void BoundarySetter<FlagField<Flag_T> >::setBoundaryConfigBlock( [[maybe_unused]] const BoundaryUID & boundaryUID, [[maybe_unused]] const Config::BlockHandle & blockHandle )
    {
       WALBERLA_ABORT("Passed boundary information to an initializer that sets up a pure flag field only");
    }
 
    template<typename Flag_T>
-   void BoundarySetter<FlagField<Flag_T>>::setBoundaryConfig( const BoundaryUID & boundaryUID, const shared_ptr<BoundaryConfiguration> & conf )
+   void BoundarySetter<FlagField<Flag_T>>::setBoundaryConfig( [[maybe_unused]] const BoundaryUID & boundaryUID, [[maybe_unused]] const shared_ptr<BoundaryConfiguration> & conf )
    {
       WALBERLA_ABORT("Passed boundary information to an initializer that sets up a pure flag field only");
    }
diff --git a/src/gpu/DeviceWrapper.h b/src/gpu/DeviceWrapper.h
index 3bdf1be008dbe166565e1f131020f7bb3e53714d..b5270a57c52b9b52092e74340cd185e358a9e00c 100644
--- a/src/gpu/DeviceWrapper.h
+++ b/src/gpu/DeviceWrapper.h
@@ -66,10 +66,12 @@ namespace gpustubs {
                   "available and shouldn't be called!");
 
 #ifndef __CUDACC__
+   //NOLINTBEGIN(bugprone-reserved-identifier)
    #define __device__
    #define __global__
    #define __host__
    #define __forceinline__
+   //NOLINTEND(bugprone-reserved-identifier)
 #endif
 
 using gpuError_t = int;
diff --git a/src/mesa_pd/vtk/ParticleVtkOutput.cpp b/src/mesa_pd/vtk/ParticleVtkOutput.cpp
index 6093eeb30cce7c8fafa526c0c8d52608ae7c41e7..9731e1e68fcc0d9e9b6003f18e1babe689eb2734 100644
--- a/src/mesa_pd/vtk/ParticleVtkOutput.cpp
+++ b/src/mesa_pd/vtk/ParticleVtkOutput.cpp
@@ -27,6 +27,7 @@ namespace vtk {
 std::vector< ParticleVtkOutput::Attributes > ParticleVtkOutput::getAttributes() const
 {
    std::vector< Attributes > attributes;
+   attributes.reserve(selectors_.size());
    for (const auto& s : selectors_)
    {
       attributes.emplace_back( s.second->type_string, s.first, s.second->components );
diff --git a/src/pe/raytracing/Raytracer.h b/src/pe/raytracing/Raytracer.h
index ed4c6c864bdb3f8fc2d80170dd113bafa3c9d681..ad26fb238d29debb866cc3a9684c5471b8a8021b 100644
--- a/src/pe/raytracing/Raytracer.h
+++ b/src/pe/raytracing/Raytracer.h
@@ -614,7 +614,7 @@ void Raytracer::generateImage(const size_t timestep, WcTimingTree* tt) {
          WALBERLA_LOG_WARNING(pixelErrors << " pixel errors found!");
          
          std::stringstream ss;
-         for (auto it: correctToIncorrectBodyIDsMap) {
+         for (auto const &it: correctToIncorrectBodyIDsMap) {
             const BodyID correctBody = it.first;
             if (it.first != nullptr) {
                ss << " correct body: " << correctBody->getID() << "(" << correctBody->getHash() << ")";
diff --git a/src/vtk/Base64Writer.h b/src/vtk/Base64Writer.h
index 43631d2a924381ecbe9a6c14c5ca4de2af349cb4..c9af5528e15ecef564e64419de622745e57228c6 100644
--- a/src/vtk/Base64Writer.h
+++ b/src/vtk/Base64Writer.h
@@ -75,7 +75,7 @@ public:
 
 private:
 
-   void encodeblock( unsigned char in[3], unsigned char out[4], int len )
+   void encodeblock( unsigned char const in[3], unsigned char out[4], int len )
    {
       static const unsigned char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
diff --git a/src/vtk/VTKOutput.cpp b/src/vtk/VTKOutput.cpp
index 42d7d9ef434b92b720a95115ed6dbbdd638905e2..770de6b1a5b923d871a512a1b93fe989d095bcd8 100644
--- a/src/vtk/VTKOutput.cpp
+++ b/src/vtk/VTKOutput.cpp
@@ -1882,7 +1882,7 @@ void VTKOutput::writeVTHBSeries()
    {
       for( std::string line; std::getline(ofs, line); )
       {
-         if( line.find("]") != std::string::npos )
+         if( line.find(']') != std::string::npos )
          {
             WALBERLA_ASSERT_GREATER( ofs.tellg(), 0 );
             pvdEnd_ = ofs.tellg();