diff --git a/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h b/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h
index 1e461ebbd57c0ddc48e9027d090e66eee0b1d142..3a6ef85a07db100e4f487548c518a0f0d02d63d9 100644
--- a/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h
+++ b/src/pe_coupling/partially_saturated_cells_method/BodyAndVolumeFractionMapping.h
@@ -32,6 +32,9 @@
 
 #include "pe_coupling/geometry/PeOverlapFraction.h"
 #include "pe_coupling/mapping/BodyBBMapping.h"
+#include "pe_coupling/utility/BodySelectorFunctions.h"
+
+#include <boost/function.hpp>
 
 namespace walberla {
 namespace pe_coupling {
@@ -79,6 +82,8 @@ void mapPSMBodyAndVolumeFraction( const pe::BodyID body, IBlock & block, Structu
  *
  * Upon construction, it uses the free mapping function to initialize the fraction and body mapping field.
  *
+ * Whether or not a body is considered by this mapping depends on the return value of 'mappingBodySelectorFct'.
+ *
  * Successive calls try to update this field instead of completely recalculating all volume fractions which is expensive.
  * To do so, the update functionality determines whether bodies have very small velocities, both translational and rotational,
  * (limited with velocityUpdatingEpsilon) or have not traveled very far (limited by positionUpdatingEpsilon) since the last volume fraction recalculation.
@@ -103,13 +108,12 @@ public:
                                  const shared_ptr<pe::BodyStorage> & globalBodyStorage,
                                  const BlockDataID & bodyStorageID,
                                  const BlockDataID & bodyAndVolumeFractionFieldID,
-                                 const bool mapFixedBodies = false,
-                                 const bool mapGlobalBodies = false,
+                                 const boost::function<bool(pe::BodyID)> & mappingBodySelectorFct = selectRegularBodies,
                                  const real_t velocityUpdatingEpsilon = real_t(0),
                                  const real_t positionUpdatingEpsilon = real_t(0),
                                  const uint_t superSamplingDepth = uint_t(4) )
    : blockStorage_( blockStorage), globalBodyStorage_( globalBodyStorage ), bodyStorageID_( bodyStorageID ),
-     bodyAndVolumeFractionFieldID_( bodyAndVolumeFractionFieldID ), mapFixed_( mapFixedBodies ), mapGlobal_( mapGlobalBodies ),
+     bodyAndVolumeFractionFieldID_( bodyAndVolumeFractionFieldID ), mappingBodySelectorFct_( mappingBodySelectorFct ),
      velocityUpdatingEpsilonSquared_( velocityUpdatingEpsilon * velocityUpdatingEpsilon ),
      positionUpdatingEpsilonSquared_( positionUpdatingEpsilon * positionUpdatingEpsilon ),
      superSamplingDepth_( superSamplingDepth )
@@ -127,11 +131,9 @@ public:
 
 private:
 
-   void updatePSMBodyAndVolumeFraction( const pe::BodyID body, IBlock & block,
+   void updatePSMBodyAndVolumeFraction( pe::BodyID body, IBlock & block,
                                         BodyAndVolumeFractionField_T * oldBodyAndVolumeFractionField,
                                         std::map< walberla::id_t, Vector3< real_t > > & tempLastUpdatedPositionMap );
-   void updateGlobalPSMBodyAndVolumeFraction( const pe::BodyID body, IBlock & block,
-                                              BodyAndVolumeFractionField_T * oldBodyAndVolumeFractionField);
 
    shared_ptr<StructuredBlockStorage> blockStorage_;
    shared_ptr<pe::BodyStorage> globalBodyStorage_;
@@ -139,8 +141,7 @@ private:
    const BlockDataID bodyStorageID_;
    const BlockDataID bodyAndVolumeFractionFieldID_;
 
-   const bool        mapFixed_;
-   const bool        mapGlobal_;
+   boost::function<bool(pe::BodyID)> mappingBodySelectorFct_;
 
    shared_ptr<BodyAndVolumeFractionField_T> updatedBodyAndVolumeFractionField_;
    std::map< walberla::id_t, Vector3< real_t > > lastUpdatedPositionMap_;
@@ -177,20 +178,22 @@ void BodyAndVolumeFractionMapping::initialize()
 
       for( auto bodyIt = pe::BodyIterator::begin( *blockIt, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt )
       {
-         // only PSM and finite bodies (no planes, etc.) are mapped
-         if( /*!isPSMBody( *bodyIt ) ||*/ ( bodyIt->isFixed() && !mapFixed_ ) )
-            continue;
-         mapPSMBodyAndVolumeFraction( *bodyIt, *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_ );
-         lastUpdatedPositionMap_.insert( std::pair< walberla::id_t, Vector3< real_t > >( bodyIt->getSystemID(), bodyIt->getPosition() ) );
+         if( mappingBodySelectorFct_(*bodyIt) )
+         {
+            mapPSMBodyAndVolumeFraction( *bodyIt, *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_ );
+            lastUpdatedPositionMap_.insert( std::pair< walberla::id_t, Vector3< real_t > >( bodyIt->getSystemID(), bodyIt->getPosition() ) );
+         }
       }
 
-      if( mapGlobal_ )
+      for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt )
       {
-         for( auto globalBodyIt = globalBodyStorage_->begin(); globalBodyIt != globalBodyStorage_->end(); ++globalBodyIt )
+         if( mappingBodySelectorFct_(*bodyIt) )
          {
-            mapPSMBodyAndVolumeFraction( *globalBodyIt, *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_ );
+            mapPSMBodyAndVolumeFraction(*bodyIt, *blockIt, *blockStorage_, bodyAndVolumeFractionFieldID_);
+            lastUpdatedPositionMap_.insert( std::pair< walberla::id_t, Vector3< real_t > >( bodyIt->getSystemID(), bodyIt->getPosition() ) );
          }
       }
+
    }
 }
 
@@ -204,17 +207,17 @@ void BodyAndVolumeFractionMapping::update()
 
       for( auto bodyIt = pe::BodyIterator::begin( *blockIt, bodyStorageID_); bodyIt != pe::BodyIterator::end(); ++bodyIt )
       {
-         // only PSM and finite bodies (no planes, etc.) are mapped
-         if( /*!isPSMBody( *bodyIt ) ||*/ ( bodyIt->isFixed() && !mapFixed_ ) )
-            continue;
-         updatePSMBodyAndVolumeFraction( *bodyIt, *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap );
+         if( mappingBodySelectorFct_(*bodyIt) )
+         {
+            updatePSMBodyAndVolumeFraction(*bodyIt, *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap);
+         }
       }
 
-      if( mapGlobal_ )
+      for( auto bodyIt = globalBodyStorage_->begin(); bodyIt != globalBodyStorage_->end(); ++bodyIt )
       {
-         for( auto globalBodyIt = globalBodyStorage_->begin(); globalBodyIt != globalBodyStorage_->end(); ++globalBodyIt )
+         if( mappingBodySelectorFct_(*bodyIt) )
          {
-            updateGlobalPSMBodyAndVolumeFraction( *globalBodyIt, *blockIt, bodyAndVolumeFractionField );;
+            updatePSMBodyAndVolumeFraction(*bodyIt, *blockIt, bodyAndVolumeFractionField, tempLastUpdatedPositionMap);
          }
       }
 
@@ -230,7 +233,7 @@ void BodyAndVolumeFractionMapping::update()
    lastUpdatedPositionMap_ = tempLastUpdatedPositionMap;
 }
 
-void BodyAndVolumeFractionMapping::updatePSMBodyAndVolumeFraction( const pe::BodyID body, IBlock & block,
+void BodyAndVolumeFractionMapping::updatePSMBodyAndVolumeFraction( pe::BodyID body, IBlock & block,
                                                                    BodyAndVolumeFractionField_T * oldBodyAndVolumeFractionField,
                                                                    std::map< walberla::id_t, Vector3< real_t > > & tempLastUpdatedPositionMap )
 {
@@ -308,30 +311,6 @@ void BodyAndVolumeFractionMapping::updatePSMBodyAndVolumeFraction( const pe::Bod
    }
 }
 
-void BodyAndVolumeFractionMapping::updateGlobalPSMBodyAndVolumeFraction( const pe::BodyID body, IBlock & block,
-                                                                         BodyAndVolumeFractionField_T * oldBodyAndVolumeFractionField )
-{
-
-   WALBERLA_ASSERT_NOT_NULLPTR( oldBodyAndVolumeFractionField );
-
-   // get bounding box of body
-   CellInterval cellBB = getCellBB( body, block, *blockStorage_, oldBodyAndVolumeFractionField->nrOfGhostLayers() );
-
-   // copy values of global body to new field
-   for( auto cellIt = cellBB.begin(); cellIt != cellBB.end(); ++cellIt )
-   {
-      Cell cell( *cellIt );
-      auto oldVec = oldBodyAndVolumeFractionField->get(cell);
-      for( auto pairIt = oldVec.begin(); pairIt != oldVec.end(); ++pairIt )
-      {
-         if( pairIt->first == body )
-         {
-            updatedBodyAndVolumeFractionField_->get(cell).push_back(*pairIt);
-            break;
-         }
-      }
-   }
-}
 
 } // namespace pe_coupling
 } // namespace walberla
diff --git a/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp b/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp
index f05d9b43db7d971f4364c1daf7fe8faf2d53f1e4..563828ee360da2151c6e5ee36e27d30e9b337a56 100644
--- a/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp
+++ b/tests/pe_coupling/partially_saturated_cells_method/SegreSilberbergPSM.cpp
@@ -550,7 +550,7 @@ int main( int argc, char **argv )
    BlockDataID bodyAndVolumeFractionFieldID = field::addToStorage< BodyAndVolumeFractionField_T >( blocks, "body and volume fraction field",
                                                                                                    std::vector<BodyAndVolumeFraction_T>(), field::zyxf, 0 );
    // map bodies and calculate solid volume fraction initially
-   pe_coupling::BodyAndVolumeFractionMapping bodyMapping( blocks, globalBodyStorage, bodyStorageID, bodyAndVolumeFractionFieldID );
+   pe_coupling::BodyAndVolumeFractionMapping bodyMapping( blocks, globalBodyStorage, bodyStorageID, bodyAndVolumeFractionFieldID, pe_coupling::selectRegularBodies );
    bodyMapping();
 
    // initialize the PDF field for PSM