diff --git a/src/pe_coupling/momentum_exchange_method/restoration/ExtrapolationDirectionFinder.h b/src/pe_coupling/momentum_exchange_method/restoration/ExtrapolationDirectionFinder.h
index 73cf2303eb5f6a6096e9038ff0a85f9e612b830b..65801c09b17d66ac406cdb71903bab97f4feb030 100644
--- a/src/pe_coupling/momentum_exchange_method/restoration/ExtrapolationDirectionFinder.h
+++ b/src/pe_coupling/momentum_exchange_method/restoration/ExtrapolationDirectionFinder.h
@@ -45,7 +45,9 @@ namespace pe_coupling {
 *   Different variants are available:
 *
 *   - FlagFieldNormalExtrapolationDirectionFinder:
-*     Uses information from the direct (N,S,E,W,T,B) neighbors' flags to find the extrapolation direction.
+*     Uses information from the direct (N,S,E,W,T,B) neighbors' flags to find the extrapolation direction
+*     by checking for the domain (here: fluid) flag.
+*     This can lead to incorrect directions in close packing scenarios or in the vicinity of other boundaries.
 *
 *   - SphereNormalExtrapolationDirectionFinder:
 *     Calculates the local normal of the body which is in its current form only correct for spherical bodies.
@@ -138,11 +140,15 @@ void SphereNormalExtrapolationDirectionFinder
    BodyField_T * bodyField = block->getData< BodyField_T >( bodyFieldID_ );
 
    WALBERLA_ASSERT_NOT_NULLPTR( bodyField );
+   WALBERLA_ASSERT_NOT_NULLPTR( (*bodyField)(x,y,z) );
 
    real_t cx, cy, cz;
    blockStorage_->getBlockLocalCellCenter( *block, Cell(x,y,z), cx, cy, cz );
-   Vector3<real_t> bodyVelocity = (*bodyField)(x,y,z)->getPosition();
-   Vector3<real_t> bodyNormal( cx - bodyVelocity[0], cy - bodyVelocity[1], cz - bodyVelocity[2] );
+
+   Vector3<real_t> bodyCenterPosition = (*bodyField)(x,y,z)->getPosition();
+   WALBERLA_ASSERT( !std::isnan(bodyCenterPosition[0]) && !std::isnan(bodyCenterPosition[1]) && !std::isnan(bodyCenterPosition[2]) );
+
+   Vector3<real_t> bodyNormal( cx - bodyCenterPosition[0], cy - bodyCenterPosition[1], cz - bodyCenterPosition[2] );
 
    findCorrespondingLatticeDirection< stencil::D3Q27 >( bodyNormal, extrapolationDirection );
 }
diff --git a/src/pe_coupling/momentum_exchange_method/restoration/PDFRestoration.h b/src/pe_coupling/momentum_exchange_method/restoration/PDFReconstruction.h
similarity index 100%
rename from src/pe_coupling/momentum_exchange_method/restoration/PDFRestoration.h
rename to src/pe_coupling/momentum_exchange_method/restoration/PDFReconstruction.h
diff --git a/src/pe_coupling/momentum_exchange_method/restoration/Reconstructor.h b/src/pe_coupling/momentum_exchange_method/restoration/Reconstructor.h
index f6234295821421e268ecf8ab4c44bd889227333e..45e3dca3ce8a5b01a3b8bff26bd8097e8b91b48c 100644
--- a/src/pe_coupling/momentum_exchange_method/restoration/Reconstructor.h
+++ b/src/pe_coupling/momentum_exchange_method/restoration/Reconstructor.h
@@ -56,6 +56,7 @@ namespace pe_coupling {
 *
 *   - ExtrapolationReconstructor:
 *     Extrapolates the PDFs of three or two neighboring cells that lie in extrapolation direction.
+*     Optionally, a special treatment after the extrapolation can be used that sets certain moments directly (only D3Q19).
 *     Defaults to EquilibriumAndNonEquilibriumReconstructor if not enough cells in this direction are available.
 *
 *   EquilibriumAndNonEquilibriumReconstructor and ExtrapolationReconstructor need an extrapolation direction
@@ -139,7 +140,7 @@ real_t EquilibriumReconstructor< LatticeModel_T, BoundaryHandling_T >
    CellInterval localDomain = pdfField->xyzSize();
 
    uint_t nAverage = uint_t(0);
-   real_t averageDensity = real_c(0);
+   real_t averageDensity = real_t(0);
    for( auto neighborDir = stencil::D3Q27::beginNoCenter(); neighborDir != stencil::D3Q27::end(); ++neighborDir )
    {
       Cell neighbor( x + neighborDir.cx(), y + neighborDir.cy(), z + neighborDir.cz() );
@@ -179,6 +180,7 @@ public:
    { }
 
    void operator()( const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z, IBlock * const block );
+   void operator()( const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z, IBlock * const block, const Vector3<cell_idx_t> & extrapolationDirection );
 
 private:
 
@@ -201,11 +203,24 @@ void EquilibriumAndNonEquilibriumReconstructor< LatticeModel_T, BoundaryHandling
 {
    WALBERLA_ASSERT_NOT_NULLPTR( block );
 
-   equilibriumReconstructor_( x, y, z, block );
-
    Vector3<cell_idx_t> extrapolationDirection(0);
    extrapolationDirectionFinder_.getDirection( x, y, z, block, extrapolationDirection );
-   setNonEquilibrium( x, y, z, block, extrapolationDirection);
+
+   (*this)(x, y, z, block, extrapolationDirection);
+}
+
+template< typename LatticeModel_T, typename BoundaryHandling_T, typename ExtrapolationDirectionFinder_T >
+void EquilibriumAndNonEquilibriumReconstructor< LatticeModel_T, BoundaryHandling_T, ExtrapolationDirectionFinder_T >
+::operator()( const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z, IBlock * const block, const Vector3<cell_idx_t> & extrapolationDirection  )
+{
+   WALBERLA_ASSERT_NOT_NULLPTR( block );
+
+   equilibriumReconstructor_( x, y, z, block );
+
+   if( extrapolationDirection != cell_idx_t(0) )
+   {
+      setNonEquilibrium( x, y, z, block, extrapolationDirection);
+   }
 }
 
 template< typename LatticeModel_T, typename BoundaryHandling_T, typename ExtrapolationDirectionFinder_T >
@@ -219,7 +234,6 @@ void EquilibriumAndNonEquilibriumReconstructor< LatticeModel_T, BoundaryHandling
 
    WALBERLA_ASSERT_NOT_NULLPTR( pdfField );
    WALBERLA_ASSERT_NOT_NULLPTR( boundaryHandling );
-   WALBERLA_ASSERT( extrapolationDirection != cell_idx_t(0) );
 
    CellInterval localDomain = pdfField->xyzSize();
    Cell normalNeighbor( x + extrapolationDirection[0], y + extrapolationDirection[1], z + extrapolationDirection[2] );
@@ -246,20 +260,25 @@ class ExtrapolationReconstructor
 {
 public:
 
-   static_assert( (boost::is_same< typename LatticeModel_T::Stencil, stencil::D3Q19 >::value), "Currently only works with D3Q19 stencil for enforcing the no-slip condition!" );
-
    typedef lbm::PdfField< LatticeModel_T > PdfField_T;
    typedef Field< pe::BodyID, 1 >          BodyField_T;
 
    ExtrapolationReconstructor( const shared_ptr<StructuredBlockStorage> blockStorage, const BlockDataID & boundaryHandlingID,
                                const BlockDataID & pdfFieldID, const BlockDataID & bodyFieldID,
-                               const ExtrapolationDirectionFinder_T & extrapolationDirectionFinder )
+                               const ExtrapolationDirectionFinder_T & extrapolationDirectionFinder,
+                               const bool & enforceNoSlipConstraintAfterExtrapolation = false )
    : blockStorage_( blockStorage ), boundaryHandlingID_( boundaryHandlingID ),
      pdfFieldID_( pdfFieldID ), bodyFieldID_( bodyFieldID ),
+     enforceNoSlipConstraintAfterExtrapolation_( enforceNoSlipConstraintAfterExtrapolation ),
      extrapolationDirectionFinder_( extrapolationDirectionFinder ),
      alternativeReconstructor_( EquilibriumAndNonEquilibriumReconstructor< LatticeModel_T, BoundaryHandling_T, ExtrapolationDirectionFinder_T >
       ( blockStorage, boundaryHandlingID, pdfFieldID, bodyFieldID, extrapolationDirectionFinder ) )
-   { }
+   {
+      if( enforceNoSlipConstraintAfterExtrapolation_ ) {
+         WALBERLA_ASSERT((boost::is_same<typename LatticeModel_T::Stencil, stencil::D3Q19>::value),
+                         "Enforcing no-slip constraint after extrapolation currently only works with D3Q19 stencil!")
+      }
+   }
 
    void operator()( const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z, IBlock * const block );
 
@@ -279,6 +298,8 @@ private:
    const BlockDataID pdfFieldID_;
    const BlockDataID bodyFieldID_;
 
+   const bool enforceNoSlipConstraintAfterExtrapolation_;
+
    ExtrapolationDirectionFinder_T extrapolationDirectionFinder_;
    EquilibriumAndNonEquilibriumReconstructor< LatticeModel_T, BoundaryHandling_T, ExtrapolationDirectionFinder_T > alternativeReconstructor_;
 
@@ -296,12 +317,17 @@ void ExtrapolationReconstructor< LatticeModel_T, BoundaryHandling_T, Extrapolati
 
    uint_t numberOfCellsForExtrapolation = getNumberOfExtrapolationCells( x, y, z, block, extrapolationDirection );
 
-   if( numberOfCellsForExtrapolation < uint_c(2) )
+   if( numberOfCellsForExtrapolation < uint_t(2) )
+   {
+      alternativeReconstructor_( x, y, z, block, extrapolationDirection );
+   }
+   else
    {
-      alternativeReconstructor_( x, y, z, block );
-   } else {
       extrapolatePDFs( x, y, z, block, extrapolationDirection, numberOfCellsForExtrapolation );
-      enforceNoSlipConstraint( x, y, z, block );
+      if( enforceNoSlipConstraintAfterExtrapolation_ )
+      {
+         enforceNoSlipConstraint( x, y, z, block );
+      }
    }
 }
 
@@ -318,9 +344,11 @@ uint_t ExtrapolationReconstructor< LatticeModel_T, BoundaryHandling_T, Extrapola
    WALBERLA_ASSERT_NOT_NULLPTR( pdfField );
    WALBERLA_ASSERT_NOT_NULLPTR( boundaryHandling );
 
+   if( extrapolationDirection == cell_idx_t(0) ) return uint_t(0);
+
    CellInterval localDomain = pdfField->xyzSize();
 
-   uint_t desiredCellsInExtrapolationDirection = uint_c(3);
+   uint_t desiredCellsInExtrapolationDirection = uint_t(3);
 
    for( uint_t numCells = uint_t(1); numCells <= desiredCellsInExtrapolationDirection; ++numCells )
    {
@@ -348,20 +376,20 @@ void ExtrapolationReconstructor< LatticeModel_T, BoundaryHandling_T, Extrapolati
 
    WALBERLA_ASSERT_NOT_NULLPTR( pdfField );
 
-   if( numberOfCellsForExtrapolation == uint_c(3) )
+   if( numberOfCellsForExtrapolation == uint_t(3) )
    {
       // quadratic normal extrapolation
       for( auto d = LatticeModel_T::Stencil::begin(); d != LatticeModel_T::Stencil::end(); ++d )
       {
-         pdfField->get( x, y, z, d.toIdx() ) = real_c(3) * pdfField->get( x +   extrapolationDirection[0], y +   extrapolationDirection[1], z +   extrapolationDirection[2], d.toIdx() )
-                                             - real_c(3) * pdfField->get( x + 2*extrapolationDirection[0], y + 2*extrapolationDirection[1], z + 2*extrapolationDirection[2], d.toIdx() )
+         pdfField->get( x, y, z, d.toIdx() ) = real_t(3) * pdfField->get( x +   extrapolationDirection[0], y +   extrapolationDirection[1], z +   extrapolationDirection[2], d.toIdx() )
+                                             - real_t(3) * pdfField->get( x + 2*extrapolationDirection[0], y + 2*extrapolationDirection[1], z + 2*extrapolationDirection[2], d.toIdx() )
                                              +             pdfField->get( x + 3*extrapolationDirection[0], y + 3*extrapolationDirection[1], z + 3*extrapolationDirection[2], d.toIdx() );
       }
    } else { // numberOfCellsForExtrapolation == 2
       // linear normal extrapolation
       for( auto d = LatticeModel_T::Stencil::begin(); d != LatticeModel_T::Stencil::end(); ++d )
       {
-         pdfField->get( x, y, z, d.toIdx() ) = real_c(2) * pdfField->get( x +   extrapolationDirection[0], y +   extrapolationDirection[1], z +   extrapolationDirection[2], d.toIdx() )
+         pdfField->get( x, y, z, d.toIdx() ) = real_t(2) * pdfField->get( x +   extrapolationDirection[0], y +   extrapolationDirection[1], z +   extrapolationDirection[2], d.toIdx() )
                                              -             pdfField->get( x + 2*extrapolationDirection[0], y + 2*extrapolationDirection[1], z + 2*extrapolationDirection[2], d.toIdx() );
       }
    }
@@ -371,6 +399,8 @@ template< typename LatticeModel_T, typename BoundaryHandling_T, typename Extrapo
 void ExtrapolationReconstructor< LatticeModel_T, BoundaryHandling_T, ExtrapolationDirectionFinder_T >
 ::enforceNoSlipConstraint( const cell_idx_t & x, const cell_idx_t & y, const cell_idx_t & z, IBlock * const block )
 {
+   //NOTE: this currently works only for D3Q19 stencils!
+
    WALBERLA_ASSERT_NOT_NULLPTR( block );
 
    PdfField_T *  pdfField  = block->getData< PdfField_T >( pdfFieldID_ );
diff --git a/src/pe_coupling/momentum_exchange_method/restoration/all.h b/src/pe_coupling/momentum_exchange_method/restoration/all.h
index 28229f903f5d77edabf9060e755f431767598a6a..f88dacd21d64f60c5068a63b446580b3713b04e9 100644
--- a/src/pe_coupling/momentum_exchange_method/restoration/all.h
+++ b/src/pe_coupling/momentum_exchange_method/restoration/all.h
@@ -23,5 +23,5 @@
 #pragma once
 
 #include "ExtrapolationDirectionFinder.h"
-#include "PDFRestoration.h"
+#include "PDFReconstruction.h"
 #include "Reconstructor.h"
diff --git a/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp b/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp
index 7bd4e73a2e892b2bf4aceb6b0caa3107adf909c4..752d57d302bea9ca299ad22171f38254154cf704 100644
--- a/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp
+++ b/tests/pe_coupling/momentum_exchange_method/SegreSilberbergMEM.cpp
@@ -713,7 +713,7 @@ int main( int argc, char **argv )
    {
       pe_coupling::FlagFieldNormalExtrapolationDirectionFinder< BoundaryHandling_T > extrapolationFinder( blocks, boundaryHandlingID );
       typedef pe_coupling::ExtrapolationReconstructor< LatticeModel_T, BoundaryHandling_T, pe_coupling::FlagFieldNormalExtrapolationDirectionFinder<BoundaryHandling_T> > Reconstructor_T;
-      Reconstructor_T reconstructor( blocks, boundaryHandlingID, pdfFieldID, bodyFieldID, extrapolationFinder );
+      Reconstructor_T reconstructor( blocks, boundaryHandlingID, pdfFieldID, bodyFieldID, extrapolationFinder, true );
       timeloop.add()
          << Sweep( pe_coupling::PDFReconstruction< LatticeModel_T, BoundaryHandling_T, Reconstructor_T >
                       ( blocks, boundaryHandlingID, bodyStorageID, bodyFieldID, reconstructor, FormerMO_Flag, Fluid_Flag  ), "PDF Restore" );