diff --git a/src/pe/amr/regrid/RegridMinMax.cpp b/src/pe/amr/regrid/RegridMinMax.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..62e9d06f410276eec3194f76de63d862cf3a06d4
--- /dev/null
+++ b/src/pe/amr/regrid/RegridMinMax.cpp
@@ -0,0 +1,85 @@
+//======================================================================================================================
+//
+//  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
+//  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
+//  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/>.
+//
+//! \file RegridMinMax.cpp
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#include "RegridMinMax.h"
+
+namespace walberla {
+namespace pe {
+namespace amr {
+
+void ReGridMinMax::operator()( std::vector< std::pair< const Block *, uint_t > > & minTargetLevels,
+                               std::vector< const Block * > &, const BlockForest & /*forest*/ )
+{
+   for( auto it = minTargetLevels.begin(); it != minTargetLevels.end(); ++it )
+   {
+      const auto infoIt = ic_->find(it->first->getId());
+      WALBERLA_ASSERT_UNEQUAL( infoIt, ic_->end() );
+
+      it->second = it->first->getLevel(); //keep everything as it is
+
+      //check for refinement
+      if (infoIt->second.numberOfLocalBodies > maxBodies_)
+      {
+         it->second = it->first->getLevel() + uint_t(1);
+         continue;
+      }
+
+      //check for coarsening
+      if ((it->first->getLevel() > 0) && (infoIt->second.numberOfLocalBodies < minBodies_))
+      {
+         if (getOrCreateCoarseInfo(it->first->getId())->second.numberOfLocalBodies < maxBodies_)
+         {
+            it->second = it->first->getLevel() - uint_t(1);
+         }
+         continue;
+      }
+   }
+}
+
+InfoCollection::const_iterator ReGridMinMax::getOrCreateCoarseInfo( const blockforest::BlockID& id )
+{
+   auto fatherId = id.getFatherId();
+   auto infoIt   = ic_->find( fatherId );
+   if (infoIt != ic_->end()) return infoIt;
+
+   BlockInfo newWeight( 0, 0);
+   for (uint_t child = 0; child < 8; ++child)
+   {
+      blockforest::BlockID childId(fatherId, child);
+      auto childIt = ic_->find( childId );
+      //meight be not available if not all blocks are on the same level
+      //return giant number to prevent coarsening
+      if (childIt == ic_->end())
+      {
+         newWeight = BlockInfo( std::numeric_limits<uint_t>::max(),
+                                std::numeric_limits<uint_t>::max());
+         break;
+      } else
+      {
+         newWeight += childIt->second;
+      }
+   }
+   WALBERLA_LOG_DETAIL("creating coarse weights (" << newWeight << ")");
+   return ic_->insert( std::make_pair(fatherId, newWeight) ).first;
+}
+
+} // namespace amr
+} // namespace pe
+} // namespace walberla
diff --git a/src/pe/amr/regrid/RegridMinMax.h b/src/pe/amr/regrid/RegridMinMax.h
new file mode 100644
index 0000000000000000000000000000000000000000..47d24349ea07922a90c88e7e2ae5febfb1e4fb22
--- /dev/null
+++ b/src/pe/amr/regrid/RegridMinMax.h
@@ -0,0 +1,56 @@
+//======================================================================================================================
+//
+//  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
+//  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
+//  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/>.
+//
+//! \file RegridMinMax.h
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+#include <pe/Types.h>
+#include <pe/amr/InfoCollection.h>
+
+#include <blockforest/Block.h>
+#include <blockforest/BlockForest.h>
+#include <core/logging/Logging.h>
+#include <domain_decomposition/BlockDataID.h>
+
+namespace walberla {
+namespace pe {
+namespace amr {
+
+class ReGridMinMax
+{
+public:
+
+   ReGridMinMax( const shared_ptr<InfoCollection>& ic, const size_t minBodies, const size_t maxBodies) :
+      ic_( ic ), minBodies_(minBodies), maxBodies_(maxBodies)
+   {}
+
+   void operator()( std::vector< std::pair< const Block *, uint_t > > & minTargetLevels,
+                    std::vector< const Block * > &, const BlockForest & forest );
+
+public:
+   const shared_ptr<InfoCollection> ic_;
+   size_t      minBodies_;
+   size_t      maxBodies_;
+
+   InfoCollection::const_iterator getOrCreateCoarseInfo( const blockforest::BlockID& id );
+};
+
+} // namespace amr
+} // namespace pe
+} // namespace walberla