diff --git a/tests/lbm_mesapd_coupling/CMakeLists.txt b/tests/lbm_mesapd_coupling/CMakeLists.txt
index b17481236e6dd024019e83d87ec227f18ca6c7ca..90cf13471fd1488f91a1e52892e96cbceea859d5 100644
--- a/tests/lbm_mesapd_coupling/CMakeLists.txt
+++ b/tests/lbm_mesapd_coupling/CMakeLists.txt
@@ -13,15 +13,15 @@ waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_MovingMapping PROCESSES 3)
 waLBerla_compile_test( NAME LBM_MESAPD_COUPLING_MEM_DragForceSphere FILES momentum_exchange_method/DragForceSphere.cpp DEPENDS core mesa_pd lbm lbm_mesapd_coupling domain_decomposition field vtk )
 waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_DragForceSphere COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_DragForceSphere> --funcTest PROCESSES 2)
 
-waLBerla_compile_test( NAME LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjects FILES momentum_exchange_method/ForceBetweenTwoStationaryObjects.cpp DEPENDS core mesa_pd lbm lbm_mesapd_coupling domain_decomposition field vtk )
-waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjectsSS1 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjects> PROCESSES 1)
-waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjectsSS2 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjects> --useSBB PROCESSES 1)
-waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjectsSS3 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjects> --useCompressible PROCESSES 1)
-waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjectsSS4 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjects> --systemVelocity 0.1 PROCESSES 1)
-waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjectsSW1 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjects> --useSphereWallSetup PROCESSES 1)
-waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjectsSW2 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjects> --useSphereWallSetup --useSBB PROCESSES 1)
-waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjectsSW3 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjects> --useSphereWallSetup --useCompressible PROCESSES 1)
-waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjectsSW4 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceBetweenTwoStationaryObjects> --useSphereWallSetup --systemVelocity 0.1 PROCESSES 1)
+waLBerla_compile_test( NAME LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjs FILES momentum_exchange_method/ForceBetweenTwoStationaryObjects.cpp DEPENDS core mesa_pd lbm lbm_mesapd_coupling domain_decomposition field vtk )
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjsSS1 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjs> PROCESSES 1)
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjsSS2 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjs> --useSBB PROCESSES 1)
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjsSS3 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjs> --useCompressible PROCESSES 1)
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjsSS4 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjs> --systemVelocity 0.1 PROCESSES 1)
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjsSW1 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjs> --useSphereWallSetup PROCESSES 1)
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjsSW2 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjs> --useSphereWallSetup --useSBB PROCESSES 1)
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjsSW3 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjs> --useSphereWallSetup --useCompressible PROCESSES 1)
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjsSW4 COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_ForceTwoStatObjs> --useSphereWallSetup --systemVelocity 0.1 PROCESSES 1)
 
 waLBerla_compile_test( NAME LBM_MESAPD_COUPLING_MEM_SettlingSphere FILES momentum_exchange_method/SettlingSphere.cpp DEPENDS core mesa_pd lbm lbm_mesapd_coupling domain_decomposition field vtk )
 waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_SettlingSphere COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_MEM_SettlingSphere> --funcTest PROCESSES 4)
@@ -32,9 +32,15 @@ waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_PdfReconstruction PROCESSES
 waLBerla_compile_test( NAME LBM_MESAPD_COUPLING_MEM_UpdateParticleMapping FILES momentum_exchange_method/UpdateParticleMapping.cpp DEPENDS core mesa_pd lbm lbm_mesapd_coupling domain_decomposition field vtk)
 waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_MEM_UpdateParticleMapping PROCESSES 1)
 
-waLBerla_compile_test( NAME LBM_MESAPD_COUPLING_UTILITY_LubricationCorrection FILES utility/LubricationCorrection.cpp DEPENDS mesa_pd lbm_mesapd_coupling )
-waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_UTILITY_LubricationCorrection PROCESSES 1 )
+waLBerla_compile_test( NAME LBM_MESAPD_COUPLING_UTIL_LubricationCorrection FILES utility/LubricationCorrection.cpp DEPENDS mesa_pd lbm_mesapd_coupling )
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_UTIL_LubricationCorrection PROCESSES 1 )
 
-waLBerla_compile_test( NAME LBM_MESAPD_COUPLING_UTILITY_InspectionProbe FILES utility/InspectionProbe.cpp DEPENDS core mesa_pd lbm lbm_mesapd_coupling domain_decomposition field )
-waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_UTILITY_InspectionProbe PROCESSES 1 )
+waLBerla_compile_test( NAME LBM_MESAPD_COUPLING_UTIL_InspectionProbe FILES utility/InspectionProbe.cpp DEPENDS core mesa_pd lbm lbm_mesapd_coupling domain_decomposition field )
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_UTIL_InspectionProbe PROCESSES 1 )
+
+waLBerla_compile_test( NAME LBM_MESAPD_COUPLING_UTIL_HydForceMultBlocks FILES utility/HydrodynamicForceOnMultipleBlocks.cpp DEPENDS mesa_pd lbm_mesapd_coupling )
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_UTIL_HydForceMultBlocks_EulerAvg COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_UTIL_HydForceMultBlocks> PROCESSES 4 )
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_UTIL_HydForceMultBlocks_VVAvg COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_UTIL_HydForceMultBlocks> --useVV PROCESSES 4 )
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_UTIL_HydForceMultBlocks_EulerNoAvg COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_UTIL_HydForceMultBlocks> --noForceAveraging PROCESSES 4 )
+waLBerla_execute_test( NAME LBM_MESAPD_COUPLING_UTIL_HydForceMultBlocks_VVNoAvg COMMAND $<TARGET_FILE:LBM_MESAPD_COUPLING_UTIL_HydForceMultBlocks> --noForceAveraging --useVV PROCESSES 4 )
 
diff --git a/tests/lbm_mesapd_coupling/momentum_exchange_method/ForceBetweenTwoStationaryObjects.cpp b/tests/lbm_mesapd_coupling/momentum_exchange_method/ForceBetweenTwoStationaryObjects.cpp
index e244543af014d124057c8b187ef59e7395cb8116..8e994002b926f320cad0d631dbcb61b2ecae61e8 100644
--- a/tests/lbm_mesapd_coupling/momentum_exchange_method/ForceBetweenTwoStationaryObjects.cpp
+++ b/tests/lbm_mesapd_coupling/momentum_exchange_method/ForceBetweenTwoStationaryObjects.cpp
@@ -300,9 +300,10 @@ int main( int argc, char **argv )
    bool useCompressible = false;
    bool useSBB = false;
    bool useSphereWallSetup = false;
-   real_t surfaceDistance = real_t(0.5);
+   real_t surfaceDistance = real_t(0.1);
    real_t systemVelocity = real_t(0);
    uint_t timesteps = uint_t(10);
+   real_t radius = real_t(5);
 
    for( int i = 1; i < argc; ++i )
    {
@@ -311,6 +312,7 @@ int main( int argc, char **argv )
       if( std::strcmp( argv[i], "--useSphereWallSetup"  ) == 0 ) { useSphereWallSetup  = true; continue;}
       if( std::strcmp( argv[i], "--surfaceDistance"    ) == 0 ) { surfaceDistance = real_c(std::atof( argv[++i])); continue;}
       if( std::strcmp( argv[i], "--systemVelocity"    ) == 0 ) { systemVelocity = real_c(std::atof( argv[++i])); continue;}
+      if( std::strcmp( argv[i], "--radius"    ) == 0 ) { radius = real_c(std::atof( argv[++i])); continue;}
       if( std::strcmp( argv[i], "--timesteps"    ) == 0 ) { timesteps = uint_c(std::atof( argv[++i])); continue;}
       WALBERLA_ABORT("Unrecognized command line argument found: " << argv[i]);
    }
@@ -320,8 +322,7 @@ int main( int argc, char **argv )
    // SIMULATION PROPERTIES //
    ///////////////////////////
 
-   const uint_t length = uint_t(32);
-   const real_t radius = real_t(5);
+   const uint_t length = uint_t(real_t(4) * radius);
    const Vector3<real_t> velocity(systemVelocity, real_t(0), real_t(0));
 
    ///////////////////////////
@@ -347,7 +348,7 @@ int main( int argc, char **argv )
    auto accessor = make_shared<ParticleAccessor_T >(ps, ss);
    auto sphereShape = ss->create<mesa_pd::data::Sphere>( radius );
 
-   createPlaneSetup(ps, ss, walberla::math::AABB(real_t(0), real_t(0), real_t(0), length, length, length), velocity);
+   createPlaneSetup(ps, ss, walberla::math::AABB(real_t(0), real_t(0), real_t(0), real_c(length), real_c(length), real_c(length)), velocity);
 
    walberla::id_t sphereID;
    if(useSphereWallSetup)
@@ -410,10 +411,9 @@ int main( int argc, char **argv )
       auto hydrodynamicForce = accessor->getHydrodynamicForce(idx);
 
       //WALBERLA_LOG_INFO(hydrodynamicForce);
-      for(uint_t comp = 0; comp < 3; ++comp)
-      {
-         WALBERLA_CHECK_FLOAT_EQUAL(hydrodynamicForce[comp], real_t(0), "Found non-zero force in component " << comp);
-      }
+
+      WALBERLA_CHECK_FLOAT_EQUAL(hydrodynamicForce, Vector3<real_t>(real_t(0)), "Found non-zero force");
+
 
       lbm_mesapd_coupling::ResetHydrodynamicForceTorqueKernel resetHydrodynamicForceTorque;
       ps->forEachParticle(false, mesa_pd::kernel::SelectAll(), *accessor, resetHydrodynamicForceTorque, *accessor );
diff --git a/tests/lbm_mesapd_coupling/utility/HydrodynamicForceOnMultipleBlocks.cpp b/tests/lbm_mesapd_coupling/utility/HydrodynamicForceOnMultipleBlocks.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7f0622dbb2650826d0d6b713c39bc2954a14e15a
--- /dev/null
+++ b/tests/lbm_mesapd_coupling/utility/HydrodynamicForceOnMultipleBlocks.cpp
@@ -0,0 +1,327 @@
+//======================================================================================================================
+//
+//  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   HydrodynamicForceOnMultipleBlocks.cpp
+//! \author Christoph Rettinger <christoph.rettinger@fau.de>
+//
+//======================================================================================================================
+
+
+#include "blockforest/Initialization.h"
+
+#include "core/Environment.h"
+#include "core/debug/Debug.h"
+#include "core/debug/TestSubsystem.h"
+#include "core/logging/Logging.h"
+
+#include "lbm_mesapd_coupling/utility/AddHydrodynamicInteractionKernel.h"
+#include "lbm_mesapd_coupling/utility/AverageHydrodynamicForceTorqueKernel.h"
+#include "lbm_mesapd_coupling/utility/InitializeHydrodynamicForceTorqueForAveragingKernel.h"
+#include "lbm_mesapd_coupling/utility/ResetHydrodynamicForceTorqueKernel.h"
+#include "lbm_mesapd_coupling/utility/ParticleFunctions.h"
+
+#include "mesa_pd/common/ParticleFunctions.h"
+#include "mesa_pd/data/ParticleAccessorWithShape.h"
+#include "mesa_pd/data/ParticleStorage.h"
+#include "mesa_pd/data/ShapeStorage.h"
+#include "mesa_pd/data/shape/Sphere.h"
+#include "mesa_pd/domain/BlockForestDomain.h"
+#include "mesa_pd/kernel/DoubleCast.h"
+#include "mesa_pd/kernel/ExplicitEuler.h"
+#include "mesa_pd/kernel/VelocityVerlet.h"
+#include "mesa_pd/kernel/ParticleSelector.h"
+#include "mesa_pd/mpi/SyncNextNeighbors.h"
+#include "mesa_pd/mpi/ReduceProperty.h"
+#include "mesa_pd/mpi/notifications/ForceTorqueNotification.h"
+#include "mesa_pd/mpi/notifications/HydrodynamicForceTorqueNotification.h"
+
+
+namespace hydrodynamic_force_blocks
+{
+
+using namespace walberla;
+
+
+template< typename ParticleAccessor_T>
+class SpherePropertyEvaluator
+{
+public:
+   SpherePropertyEvaluator( const shared_ptr< ParticleAccessor_T > & ac, walberla::id_t sphereUid) :
+         ac_( ac ), sphereUid_( sphereUid )
+   {  }
+
+   void operator()()
+   {
+      Vector3<real_t> pos(real_t(0));
+      Vector3<real_t> transVel(real_t(0));
+      Vector3<real_t> angularVel(real_t(0));
+      Vector3<real_t> force(real_t(0));
+      Vector3<real_t> torque(real_t(0));
+
+      size_t idx = ac_->uidToIdx(sphereUid_);
+      if( idx != ac_->getInvalidIdx())
+      {
+         if(!mesa_pd::data::particle_flags::isSet( ac_->getFlags(idx), mesa_pd::data::particle_flags::GHOST))
+         {
+            pos = ac_->getPosition(idx);
+            transVel = ac_->getLinearVelocity(idx);
+            angularVel = ac_->getAngularVelocity(idx);
+            force = ac_->getForce(idx);
+            torque = ac_->getTorque(idx);
+         }
+      }
+
+      WALBERLA_MPI_SECTION()
+      {
+         mpi::allReduceInplace( pos[0], mpi::SUM );
+         mpi::allReduceInplace( pos[1], mpi::SUM );
+         mpi::allReduceInplace( pos[2], mpi::SUM );
+
+         mpi::allReduceInplace( transVel[0], mpi::SUM );
+         mpi::allReduceInplace( transVel[1], mpi::SUM );
+         mpi::allReduceInplace( transVel[2], mpi::SUM );
+
+         mpi::allReduceInplace( angularVel[0], mpi::SUM );
+         mpi::allReduceInplace( angularVel[1], mpi::SUM );
+         mpi::allReduceInplace( angularVel[2], mpi::SUM );
+
+         mpi::allReduceInplace( force[0], mpi::SUM );
+         mpi::allReduceInplace( force[1], mpi::SUM );
+         mpi::allReduceInplace( force[2], mpi::SUM );
+
+         mpi::allReduceInplace( torque[0], mpi::SUM );
+         mpi::allReduceInplace( torque[1], mpi::SUM );
+         mpi::allReduceInplace( torque[2], mpi::SUM );
+      }
+
+      position_ = pos;
+      linearVel_ = transVel;
+      angularVel_ = angularVel;
+      force_ = force;
+      torque_ = torque;
+   }
+
+   Vector3<real_t> getPosition() const { return position_; }
+   Vector3<real_t> getLinearVel() const { return linearVel_; }
+   Vector3<real_t> getAngularVel() const { return angularVel_; }
+   Vector3<real_t> getForce() const { return force_; }
+   Vector3<real_t> getTorque() const { return torque_; }
+
+
+private:
+
+   shared_ptr< ParticleAccessor_T > ac_;
+   const walberla::id_t sphereUid_;
+
+   Vector3<real_t> position_;
+   Vector3<real_t> linearVel_;
+   Vector3<real_t> angularVel_;
+   Vector3<real_t> force_;
+   Vector3<real_t> torque_;
+};
+
+template< typename ParticleAccessor_T>
+void applyHydrodynamicForceTorqueOnSphere(ParticleAccessor_T & accessor, walberla::id_t sphereUid,
+                                          Vector3<real_t> hydForce, Vector3<real_t> hydTorque)
+{
+
+   uint_t numberOfProcessesWithKnowledgeOfThisSphere = uint_t(0);
+   size_t idx = accessor.uidToIdx(sphereUid);
+   if( idx != accessor.getInvalidIdx())
+   {
+      ++numberOfProcessesWithKnowledgeOfThisSphere;
+   }
+
+   WALBERLA_MPI_SECTION() {
+      mpi::allReduceInplace(numberOfProcessesWithKnowledgeOfThisSphere, mpi::SUM);
+   }
+
+   if( idx != accessor.getInvalidIdx())
+   {
+      accessor.setHydrodynamicForce(idx, hydForce / real_t(numberOfProcessesWithKnowledgeOfThisSphere) );
+      accessor.setHydrodynamicTorque(idx, hydTorque / real_t(numberOfProcessesWithKnowledgeOfThisSphere) );
+   }
+}
+
+
+/*
+ * Two spheres travelling through several blocks. moved by constant (distributed) hydrodynamic force.
+ * This checks setting hydrodynamic forces onto particles and force averaging in parallel setup.
+ * Velocity of both spheres have to be equal throughout the simulation.
+ *
+ */
+int main( int argc, char ** argv )
+{
+   debug::enterTestMode();
+
+   mpi::Environment env( argc, argv );
+
+   const Vector3<uint_t> domainSize( 4 * 32, 32, 32 );
+   const Vector3<uint_t> numberOfBlocksPerDirection(4, 1, 1 );
+   Vector3<uint_t> cellsPerBlockPerDirection( domainSize[0] / numberOfBlocksPerDirection[0],
+                                              domainSize[1] / numberOfBlocksPerDirection[1],
+                                              domainSize[2] / numberOfBlocksPerDirection[2] );
+
+   real_t xPos1 = real_t(0);
+   real_t xPos2 = real_t(45.36281); // random
+
+   real_t radius = real_t(2);
+
+   Vector3<real_t> hydForce( real_t(0.75), 0, 0);
+   Vector3<real_t> hydTorque( real_t(0.75), 0, 0);
+
+   real_t dt = real_t(1);
+   real_t dx = real_t(1);
+   uint_t timesteps = 400;
+
+   bool averageForceTorqueOverTwoTimeSteps = true;
+   bool useVelocityVerlet = false;
+
+
+   for( int i = 1; i < argc; ++i )
+   {
+      if( std::strcmp( argv[i], "--timesteps" )           == 0 ) { timesteps = uint_c( std::atof( argv[++i] ) ); continue; }
+      if( std::strcmp( argv[i], "--noForceAveraging" )    == 0 ) { averageForceTorqueOverTwoTimeSteps = false; continue; }
+      if( std::strcmp( argv[i], "--useVV" )               == 0 ) { useVelocityVerlet = true; continue; }
+      WALBERLA_ABORT("Unrecognized command line argument found: " << argv[i]);
+   }
+
+   // setup as in a coupled simulation even though not needed here for mesa_pd only setup
+   auto blocks = blockforest::createUniformBlockGrid( numberOfBlocksPerDirection[0], numberOfBlocksPerDirection[1], numberOfBlocksPerDirection[2],
+                                                      cellsPerBlockPerDirection[0], cellsPerBlockPerDirection[1], cellsPerBlockPerDirection[2], dx,
+                                                      0, false, false,
+                                                      true, false, false, //periodicity
+                                                      false );
+
+
+   auto rpdDomain = walberla::make_shared<mesa_pd::domain::BlockForestDomain>(blocks->getBlockForestPointer());
+
+   auto ps = walberla::make_shared<mesa_pd::data::ParticleStorage>(2);
+   auto ss = walberla::make_shared<mesa_pd::data::ShapeStorage>();
+   using ParticleAccessor_T = mesa_pd::data::ParticleAccessorWithShape;
+   auto accessor = walberla::make_shared<ParticleAccessor_T >(ps, ss);
+
+   auto sphereShape = ss->create<mesa_pd::data::Sphere>( radius );
+   ss->shapes[sphereShape]->updateMassAndInertia(real_t(1));
+
+   Vector3<real_t> initialPosition1( xPos1, real_t(0.5) * real_c(domainSize[1]), real_t(0.5) * real_c(domainSize[2]));
+   Vector3<real_t> initialPosition2( xPos2, real_t(0.5) * real_c(domainSize[1]), real_t(0.5) * real_c(domainSize[2]));
+
+   walberla::id_t sphereUid1 = 0;
+   if (rpdDomain->isContainedInProcessSubdomain( uint_c(mpi::MPIManager::instance()->rank()), initialPosition1 ))
+   {
+      mesa_pd::data::Particle&& p = *ps->create();
+      p.setPosition(initialPosition1);
+      p.setInteractionRadius(radius);
+      p.setOwner(mpi::MPIManager::instance()->rank());
+      p.setShapeID(sphereShape);
+      sphereUid1 = p.getUid();
+   }
+   mpi::allReduceInplace(sphereUid1, mpi::SUM);
+
+   walberla::id_t sphereUid2 = 0;
+   if (rpdDomain->isContainedInProcessSubdomain( uint_c(mpi::MPIManager::instance()->rank()), initialPosition2 ))
+   {
+      mesa_pd::data::Particle&& p = *ps->create();
+      p.setPosition(initialPosition2);
+      p.setInteractionRadius(radius);
+      p.setOwner(mpi::MPIManager::instance()->rank());
+      p.setShapeID(sphereShape);
+      sphereUid2 = p.getUid();
+   }
+   mpi::allReduceInplace(sphereUid2, mpi::SUM);
+
+
+   // mesa_pd functionality
+   mesa_pd::kernel::VelocityVerletPreForceUpdate  vvIntegratorPreForce( dt );
+   mesa_pd::kernel::VelocityVerletPostForceUpdate vvIntegratorPostForce( dt );
+   mesa_pd::kernel::ExplicitEuler explEulerIntegrator( dt );
+   mesa_pd::mpi::ReduceProperty reduceProperty;
+
+   std::function<void(void)> syncCall = [ps,rpdDomain](){
+      const real_t overlap = real_t( 1.5 );
+      mesa_pd::mpi::SyncNextNeighbors syncNextNeighborFunc;
+      syncNextNeighborFunc(*ps, *rpdDomain, overlap);
+   };
+
+   syncCall();
+
+   // coupling functionality
+   lbm_mesapd_coupling::AddHydrodynamicInteractionKernel addHydrodynamicInteraction;
+   lbm_mesapd_coupling::ResetHydrodynamicForceTorqueKernel resetHydrodynamicForceTorque;
+   lbm_mesapd_coupling::AverageHydrodynamicForceTorqueKernel averageHydrodynamicForceTorque;
+
+   // evaluation functionality
+   SpherePropertyEvaluator<ParticleAccessor_T> sphere1Eval(accessor, sphereUid1);
+   SpherePropertyEvaluator<ParticleAccessor_T> sphere2Eval(accessor, sphereUid2);
+
+   bool useOpenMP = false;
+   for(uint_t t = 0; t < timesteps; ++t) {
+
+      // set hydrodynamic force/torque distributed
+      applyHydrodynamicForceTorqueOnSphere(*accessor, sphereUid1, hydForce, hydTorque);
+      applyHydrodynamicForceTorqueOnSphere(*accessor, sphereUid2, hydForce, hydTorque);
+
+      reduceProperty.operator()<mesa_pd::HydrodynamicForceTorqueNotification>(*ps);
+
+      if (averageForceTorqueOverTwoTimeSteps) {
+         if (t == 0) {
+            lbm_mesapd_coupling::InitializeHydrodynamicForceTorqueForAveragingKernel initializeHydrodynamicForceTorqueForAveragingKernel;
+            ps->forEachParticle(useOpenMP, mesa_pd::kernel::SelectLocal(), *accessor, initializeHydrodynamicForceTorqueForAveragingKernel, *accessor);
+         }
+         ps->forEachParticle(useOpenMP, mesa_pd::kernel::SelectLocal(), *accessor, averageHydrodynamicForceTorque, *accessor);
+      }
+
+      if (useVelocityVerlet) {
+         ps->forEachParticle(useOpenMP, mesa_pd::kernel::SelectLocal(), *accessor, vvIntegratorPreForce, *accessor);
+         syncCall();
+      }
+
+      ps->forEachParticle(useOpenMP, mesa_pd::kernel::SelectLocal(), *accessor, addHydrodynamicInteraction, *accessor);
+
+      reduceProperty.operator()<mesa_pd::ForceTorqueNotification>(*ps);
+
+      // check sphere properties
+      sphere1Eval();
+      sphere2Eval();
+
+      WALBERLA_CHECK_FLOAT_EQUAL(sphere1Eval.getLinearVel()[0], sphere2Eval.getLinearVel()[0], "time step " << t << " mismatch in linear vel[0]");
+      WALBERLA_CHECK_FLOAT_EQUAL(sphere1Eval.getLinearVel()[1], sphere2Eval.getLinearVel()[1], "time step " << t << " mismatch in linear vel[1]");
+      WALBERLA_CHECK_FLOAT_EQUAL(sphere1Eval.getLinearVel()[2], sphere2Eval.getLinearVel()[2], "time step " << t << " mismatch in linear vel[2]");
+
+      WALBERLA_CHECK_FLOAT_EQUAL(sphere1Eval.getAngularVel()[0], sphere2Eval.getAngularVel()[0], "time step " << t << " mismatch in angular vel[0]");
+      WALBERLA_CHECK_FLOAT_EQUAL(sphere1Eval.getAngularVel()[1], sphere2Eval.getAngularVel()[1], "time step " << t << " mismatch in angular vel[1]");
+      WALBERLA_CHECK_FLOAT_EQUAL(sphere1Eval.getAngularVel()[2], sphere2Eval.getAngularVel()[2], "time step " << t << " mismatch in angular vel[2]");
+
+      // particle integration
+      if( useVelocityVerlet ) ps->forEachParticle(useOpenMP, mesa_pd::kernel::SelectLocal(), *accessor, vvIntegratorPostForce, *accessor);
+      else ps->forEachParticle(useOpenMP, mesa_pd::kernel::SelectLocal(), *accessor, explEulerIntegrator, *accessor);
+
+      syncCall();
+
+      ps->forEachParticle(useOpenMP, mesa_pd::kernel::SelectAll(), *accessor, resetHydrodynamicForceTorque, *accessor );
+
+      //WALBERLA_LOG_INFO_ON_ROOT(t << " " << sphere1Eval.getPosition()[0] << " " << sphere1Eval.getLinearVel()[0] << " " << sphere1Eval.getForce()[0] << " " << sphere1Eval.getAngularVel()[0] << " " << sphere1Eval.getTorque()[0] );
+   }
+
+   return EXIT_SUCCESS;
+}
+
+} //namespace hydrodynamic_force_blocks
+
+int main( int argc, char ** argv )
+{
+   return hydrodynamic_force_blocks::main(argc, argv);
+}