diff --git a/src/mesa_pd/kernel/cnt/IntegratedVDWContact.h b/src/mesa_pd/kernel/cnt/IntegratedVDWContact.h
new file mode 100644
index 0000000000000000000000000000000000000000..844887f15c5b472b12830f0e933709f4e69681b1
--- /dev/null
+++ b/src/mesa_pd/kernel/cnt/IntegratedVDWContact.h
@@ -0,0 +1,145 @@
+//======================================================================================================================
+//
+//  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
+//! \author Igor Ostanin <i.ostanin@skoltech.ru>
+//! \author Grigorii Drozdov <drozd013@umn.edu>
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#pragma once
+
+#include <mesa_pd/common/ParticleFunctions.h>
+#include <mesa_pd/data/DataTypes.h>
+#include <mesa_pd/data/IAccessor.h>
+
+#include <core/math/Constants.h>
+#include <core/logging/Logging.h>
+
+#include <vector>
+
+namespace walberla {
+namespace mesa_pd {
+namespace kernel {
+namespace cnt {
+
+/**
+ * vdW Contact with integration
+ */
+class IntegratedVDWContact
+{
+public:
+   template<typename Accessor>
+   void operator()(const size_t p_idx1,
+                   const size_t p_idx2,
+                   Accessor &ac);
+
+   static constexpr real_t R_CNT = 6.78_r; ///< CNT radius
+   static constexpr real_t T = 2_r * R_CNT; ///< Height of a cylindrical segment
+   static constexpr real_t eps = 0.07124_r;
+   static constexpr real_t A = 0.0223_r;
+   static constexpr real_t B = 1.31_r;
+   static constexpr real_t alpha = 9.5_r;
+   static constexpr real_t beta = 4.0_r;
+
+   // vdW adhesion + linear repulsion potential.
+   const real_t r0 = R_CNT * (2_r + std::pow((alpha * A / (beta * B)), 1_r / (alpha - beta)));
+   const real_t u0 = 4_r * eps * (A / std::pow(r0 / R_CNT - 2_r, (alpha)) - B / std::pow(r0 / R_CNT - 2_r, (beta)));
+
+   auto getLastEnergy() const {return energy_;}
+private:
+   real_t energy_; ///< total potential
+};
+
+
+template<typename Accessor>
+inline
+void IntegratedVDWContact::operator()(const size_t p_idx1,
+                                      const size_t p_idx2,
+                                      Accessor &ac)
+{
+   constexpr real_t K_n = 200.0_r; // Good for fabrics modeling
+
+   // particle centers
+   Vec3 O1 = ac.getPosition(p_idx1);
+   Vec3 O2 = ac.getPosition(p_idx2);
+
+   // axial vectors
+   Vec3 b1 = ac.getRotation(p_idx1).getMatrix() * Vec3(1_r, 0_r, 0_r);
+   Vec3 b2 = ac.getRotation(p_idx2).getMatrix() * Vec3(1_r, 0_r, 0_r);
+
+   energy_ = 0_r;
+   Vec3 force12(0);  // Force 12
+   Vec3 force21(0);  // Force 21
+   Vec3 moment12(0); // Total torque 12
+   Vec3 moment21(0); // Total torque 21
+
+   constexpr int Np = 5; // Number of integration points over each axis
+   constexpr real_t Npinv = 1.0_r / real_t(Np);
+   for (int i = 0; i < Np; ++i) // integral dl1
+   {
+      for (int j = 0; j < Np; ++j) // integral dl2
+      {
+         // Levers
+         Vec3 l1 = (-0.5_r * T + (0.5_r + real_t(i)) * T * Npinv) * b1;
+         Vec3 l2 = (-0.5_r * T + (0.5_r + real_t(j)) * T * Npinv) * b2;
+
+         /// radius vector between dl1 and dl2
+         Vec3 R12 = (O2 + l2) - (O1 + l1);
+
+         real_t r12 = R12.length();
+         Vec3 n12 = R12 * (1_r / r12);
+
+         real_t dU = 0_r;
+         Vec3 dforce12(0);
+
+         if (r12 < r0)
+         {
+            // elastic interaction
+            dU = u0 + K_n * (r12 - r0) * (r12 - r0) * Npinv * Npinv;
+            dforce12 = n12 * K_n * (r12 - r0) * Npinv * Npinv;
+         } else
+         {
+            // vdW interaction
+            const real_t normDistance = r12 / R_CNT - 2_r;
+            const real_t powAlpha = std::pow(normDistance, alpha);
+            const real_t powBeta = std::pow(normDistance, beta);
+            dU = 4_r * eps * (A / powAlpha - B / powBeta) * Npinv * Npinv;
+            dforce12 = n12 * 4_r * eps / R_CNT * Npinv * Npinv *
+                       (-(alpha * A) / (powAlpha * normDistance) + (beta * B) / (powBeta * normDistance));
+         }
+
+         Vec3 dmoment12 = l2 % dforce12;
+         Vec3 dmoment21 = l1 % (-dforce12);
+
+         energy_ += dU;
+         force12 += dforce12;
+         force21 -= dforce12;
+         moment12 += dmoment12;
+         moment21 += dmoment21;
+      }
+   }
+
+   addForceAtomic(p_idx1, ac, force12);
+   addForceAtomic(p_idx2, ac, force21);
+   addTorqueAtomic(p_idx1, ac,  -moment21);
+   addTorqueAtomic(p_idx2, ac,  -moment12);
+}
+
+} //namespace cnt
+} //namespace kernel
+} //namespace mesa_pd
+} //namespace walberla
\ No newline at end of file
diff --git a/src/mesa_pd/kernel/cnt/Parameters.h b/src/mesa_pd/kernel/cnt/Parameters.h
index 63f256a04dca173007766af03f3b70256047824f..c265088bab02da9837599fbf333032b795bf2b0d 100644
--- a/src/mesa_pd/kernel/cnt/Parameters.h
+++ b/src/mesa_pd/kernel/cnt/Parameters.h
@@ -79,11 +79,11 @@ constexpr auto M_C = 12.011_r;
 /// Mass of the repetative cell in AMU
 constexpr auto mass_T = ro * T * M_C * 104.397_r;
 
-// Volume of a capsule
-//double vol = (4./3.) * PII * (R_CNT * R_CNT * R_CNT) + PII * R_CNT * R_CNT * T;
+/// Volume of a capsule
+double vol_capsule = (4_r/3_r) * math::pi * (R_CNT * R_CNT * R_CNT) + math::pi * R_CNT * R_CNT * T;
 
-// Density of a capsule
-//double dens = mass_T / vol;
+/// Density of a capsule
+double dens_capsule = mass_T / vol_capsule;
 
 /// V-bond parameter
 constexpr auto knorm = (En * 0.006242_r) / T;
@@ -97,12 +97,12 @@ constexpr auto outer_radius     = CutoffFactor * R_CNT;
 constexpr auto inner_radius     = 1.5811_r * R_CNT; // Sphere
 
 /// volume of a sphere
-constexpr auto vol = (4_r/3_r) * math::pi * (inner_radius * inner_radius * inner_radius);
+constexpr auto vol_sphere = (4_r/3_r) * math::pi * (inner_radius * inner_radius * inner_radius);
 
 /// density of a sphere
-constexpr auto dens = mass_T / vol;
+constexpr auto dens_sphere = mass_T / vol_sphere;
 
 } //namespace cnt
 } //namespace kernel
 } //namespace mesa_pd
-} //namespace walberla
\ No newline at end of file
+} //namespace walberla
diff --git a/tests/mesa_pd/CMakeLists.txt b/tests/mesa_pd/CMakeLists.txt
index 983cbca6e994be63a8cc4a275d6e8457b501a24a..4e7985268047a837470ea5ed0b2a4793b1785873 100644
--- a/tests/mesa_pd/CMakeLists.txt
+++ b/tests/mesa_pd/CMakeLists.txt
@@ -84,6 +84,9 @@ waLBerla_execute_test( NAME   MESA_PD_DropTestGeneral )
 waLBerla_compile_test( NAME   MESA_PD_Kernel_ClearNextNeighborSync FILES kernel/ClearNextNeighborSync.cpp DEPENDS core )
 waLBerla_execute_test( NAME   MESA_PD_Kernel_ClearNextNeighborSync PROCESSES 2 )
 
+waLBerla_compile_test( NAME   MESA_PD_Kernel_CNT_IntegratedVDWContact FILES kernel/cnt/IntegratedVDWContact.test.cpp DEPENDS core )
+waLBerla_execute_test( NAME   MESA_PD_Kernel_CNT_IntegratedVDWContact )
+
 waLBerla_compile_test( NAME   MESA_PD_Kernel_CNT_IsotropicVDWContact FILES kernel/cnt/IsotropicVDWContact.test.cpp DEPENDS core )
 waLBerla_execute_test( NAME   MESA_PD_Kernel_CNT_IsotropicVDWContact )
 
diff --git a/tests/mesa_pd/kernel/cnt/IntegratedVDWContact.test.cpp b/tests/mesa_pd/kernel/cnt/IntegratedVDWContact.test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..05bb96c988d9785bce0b12de23ffb327bb762893
--- /dev/null
+++ b/tests/mesa_pd/kernel/cnt/IntegratedVDWContact.test.cpp
@@ -0,0 +1,135 @@
+//======================================================================================================================
+//
+//  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
+//! \author Igor Ostanin <i.ostanin@skoltech.ru>
+//! \author Grigorii Drozdov <drozd013@umn.edu>
+//! \author Sebastian Eibl <sebastian.eibl@fau.de>
+//
+//======================================================================================================================
+
+#include "SphericalSegmentAccessor.h"
+
+#include "mesa_pd/data/Flags.h"
+#include "mesa_pd/data/ParticleStorage.h"
+#include "mesa_pd/kernel/ParticleSelector.h"
+#include "mesa_pd/kernel/cnt/IntegratedVDWContact.h"
+#include "mesa_pd/kernel/cnt/ViscousDamping.h"
+#include "mesa_pd/kernel/cnt/Parameters.h"
+#include "mesa_pd/kernel/VelocityVerlet.h"
+#include "mesa_pd/vtk/ParticleVtkOutput.h"
+
+#include "core/Environment.h"
+#include "core/math/Constants.h"
+#include "vtk/VTKOutput.h"
+
+namespace walberla {
+using namespace walberla::mesa_pd;
+
+int main(int argc, char **argv)
+{
+   Environment env(argc, argv);
+   walberla::mpi::MPIManager::instance()->useWorldComm();
+
+   if (std::is_same<walberla::real_t, float>::value)
+   {
+      WALBERLA_LOG_WARNING("waLBerla build in sp mode: skipping test due to low precision");
+      return EXIT_SUCCESS;
+   }
+
+   logging::Logging::instance()->setStreamLogLevel(logging::Logging::INFO);
+   logging::Logging::instance()->setFileLogLevel(logging::Logging::INFO);
+
+   WALBERLA_LOG_INFO_ON_ROOT("loading configuration parameters");
+   constexpr auto numSimulationSteps = 20000ll;
+   constexpr auto outputInterval = 100ll;
+
+   WALBERLA_LOG_INFO_ON_ROOT("creating initial particle setup");
+   auto ps = std::make_shared<data::ParticleStorage>(10);
+   auto ac = SphericalSegmentAccessor(ps);
+
+   using namespace kernel::cnt;
+   data::Particle &&sp1 = *ps->create();
+   sp1.setPosition(Vec3(0_r, 0_r, 0_r));
+   sp1.setSegmentID(1);
+   sp1.setClusterID(1);
+
+   data::Particle &&sp2 = *ps->create();
+   sp2.setPosition(Vec3(20_r, 20_r, 20_r));
+   sp2.setSegmentID(2);
+   sp2.setClusterID(2);
+
+   WALBERLA_LOG_INFO_ON_ROOT("setting up VTK output");
+   auto vtkOutput       = make_shared<mesa_pd::vtk::ParticleVtkOutput>(ps);
+   vtkOutput->addOutput<data::SelectParticlePosition>("position");
+   auto vtkWriter       = walberla::vtk::createVTKOutput_PointData(vtkOutput,
+                                                                   "cnt",
+                                                                   1,
+                                                                   "vtk_integrated",
+                                                                   "particles",
+                                                                   false,
+                                                                   false);
+
+   WALBERLA_LOG_INFO_ON_ROOT("setting up interaction models");
+   kernel::cnt::IntegratedVDWContact vdW_integrated;
+   kernel::cnt::ViscousDamping viscous_damping(0.1_r * 1052.0_r, 0.1_r * 1052.0_r);
+   kernel::VelocityVerletPreForceUpdate vv_pre(kernel::cnt::dT);
+   kernel::VelocityVerletPostForceUpdate vv_post(kernel::cnt::dT);
+
+   WALBERLA_LOG_INFO_ON_ROOT("running simulation");
+
+   real_t U = 0_r;
+   for (auto i = 0; i < numSimulationSteps; ++i)
+   {
+      ps->forEachParticle(false,
+                          kernel::SelectAll(),
+                          ac,
+                          vv_pre,
+                          ac);
+
+      U = 0_r;
+      ps->forEachParticlePairHalf(false,
+                                  kernel::SelectAll(),
+                                  ac,
+                                  [&](size_t p_idx1, size_t p_idx2)
+                                  {
+                                     vdW_integrated(p_idx1, p_idx2, ac);
+                                     U += vdW_integrated.getLastEnergy();
+                                     viscous_damping(p_idx1, p_idx2, ac);
+                                  });
+
+      ps->forEachParticle(false,
+                          kernel::SelectAll(),
+                          ac,
+                          vv_post,
+                          ac);
+
+      if( i % outputInterval == 0 )
+      {
+//         vtkWriter->write();
+//         WALBERLA_LOG_DEVEL(i << " : " << U);
+      }
+   }
+
+   WALBERLA_CHECK_LESS(U, -8_r)
+
+   return EXIT_SUCCESS;
+}
+} // namespace walberla
+
+int main(int argc, char *argv[])
+{
+   return walberla::main(argc, argv);
+}