diff --git a/Src/Components/FAbstractKernels.hpp b/Src/Components/FAbstractKernels.hpp
index 6b0f7095da834d66957d0de17d6eb517ea0c048b..edf8e7b0749ab216f5948013e80bb1e214421820 100644
--- a/Src/Components/FAbstractKernels.hpp
+++ b/Src/Components/FAbstractKernels.hpp
@@ -81,22 +81,11 @@ public:
     /**
         * P2P
         * Particles to particles
+        * @param inLeafPosition tree coordinate of the leaf
         * @param targets current boxe targets particles
+        * @param sources current boxe sources particles (can be == to targets)
         * @param directNeighborsParticles the particles from direct neighbors (this is an array of list)
-        * @param size the number of direct neighbors (the size of the array directNeighborsParticles)
-        */
-    virtual void P2P(const FTreeCoordinate& inLeafPosition,
-             ContainerClass* const FRestrict targets,
-             ContainerClass* const directNeighborsParticles[27], const int size) = 0;
-
-    /**
-        * P2P
-        * Particles to particles
-        * @param inLeafPosition
-        * @param targets current boxe targets particles
-        * @param sources current boxe sources particles
-        * @param directNeighborsParticles the particles from direct neighbors (this is an array of list)
-        * @param size the number of direct neighbors (the size of the array directNeighborsParticles)
+        * @param size the number of direct neighbors
         */
     virtual void P2P(const FTreeCoordinate& inLeafPosition,
              ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
diff --git a/Src/Components/FBasicKernels.hpp b/Src/Components/FBasicKernels.hpp
index 47b3ae8f6326453dfa77d8d4d8437aef3e94d4f6..ae685f98189b8c7cececdb35a3a16c089ebbf850 100644
--- a/Src/Components/FBasicKernels.hpp
+++ b/Src/Components/FBasicKernels.hpp
@@ -58,12 +58,6 @@ public:
 
     }
 
-    /** Do nothing */
-    virtual void P2P(const FTreeCoordinate& ,
-                     ContainerClass* const FRestrict ,
-                     ContainerClass* const [27], const int ) {
-
-    }
 
     /** Do nothing */
     virtual void P2P(const FTreeCoordinate& ,
diff --git a/Src/Components/FTestKernels.hpp b/Src/Components/FTestKernels.hpp
index 02273c14c7c30f1cb1180a52c074110d685e62be..7643819234a921164f64f996b78af1007a2a2f2c 100644
--- a/Src/Components/FTestKernels.hpp
+++ b/Src/Components/FTestKernels.hpp
@@ -89,28 +89,6 @@ public:
 
     }
 
-    /** After Downward */
-    void P2P(const FTreeCoordinate& ,
-                 ContainerClass* const FRestrict targets,
-                 ContainerClass* const directNeighborsParticles[27], const int ){
-
-        // Each particles targeted is impacted by the particles sources
-        long long int inc = targets->getSize() - 1;
-
-        for(int idx = 0 ; idx < 27 ; ++idx){
-            if( directNeighborsParticles[idx] ){
-                inc += directNeighborsParticles[idx]->getSize();
-            }
-        }
-
-        typename ContainerClass::BasicIterator iter(*targets);
-        while( iter.hasNotFinished() ){
-            iter.data().setDataDown(iter.data().getDataDown() + inc);
-            iter.gotoNext();
-        }
-
-    }
-
 
     /** After Downward */
     void P2P(const FTreeCoordinate& ,
diff --git a/Src/Core/FFmmAlgorithm.hpp b/Src/Core/FFmmAlgorithm.hpp
index 4216b4dbb7dd154a1ecca4961f85242495231b84..3eaa6e324cf54f5c7b03be5724ac513b4de4bb22 100644
--- a/Src/Core/FFmmAlgorithm.hpp
+++ b/Src/Core/FFmmAlgorithm.hpp
@@ -242,7 +242,8 @@ private:
             // need the current particles and neighbors particles
             const int counter = tree->getLeafsNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(),heightMinusOne);
             FDEBUG(computationCounterP2P.tic());
-            kernels->P2P(octreeIterator.getCurrentGlobalCoordinate(),octreeIterator.getCurrentListTargets(), neighbors, counter);
+            kernels->P2P(octreeIterator.getCurrentGlobalCoordinate(),octreeIterator.getCurrentListTargets(),
+                         octreeIterator.getCurrentListSrc(), neighbors, counter);
             FDEBUG(computationCounterP2P.tac());
         } while(octreeIterator.moveRight());
 
diff --git a/Src/Core/FFmmAlgorithmPeriodic.hpp b/Src/Core/FFmmAlgorithmPeriodic.hpp
index 980fab5175cd6ddf48337f1ef3459e0c0589fbca..18a08f961e832a260e84f96d0c5cf87463d67e27 100644
--- a/Src/Core/FFmmAlgorithmPeriodic.hpp
+++ b/Src/Core/FFmmAlgorithmPeriodic.hpp
@@ -240,7 +240,8 @@ private:
             // need the current particles and neighbors particles
             const int counter = tree->getPeriodicLeafsNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(),heightMinusOne);
             FDEBUG(computationCounterP2P.tic());
-            kernels->P2P(octreeIterator.getCurrentGlobalCoordinate(),octreeIterator.getCurrentListTargets(), neighbors, counter);
+            kernels->P2P(octreeIterator.getCurrentGlobalCoordinate(),octreeIterator.getCurrentListTargets(),
+                         octreeIterator.getCurrentListSrc(), neighbors, counter);
             FDEBUG(computationCounterP2P.tac());
         } while(octreeIterator.moveRight());
 
diff --git a/Src/Core/FFmmAlgorithmTask.hpp b/Src/Core/FFmmAlgorithmTask.hpp
index 61d2d6e7d2325833e192373369c048999f329c6a..c1302afbcbd2ff36e06d7bb762f297045d00ecd8 100644
--- a/Src/Core/FFmmAlgorithmTask.hpp
+++ b/Src/Core/FFmmAlgorithmTask.hpp
@@ -324,7 +324,8 @@ private:
                         #pragma omp task
                         {
                             const int counter = tree->getLeafsNeighbors(neighbors, toWork.getCurrentGlobalCoordinate(),heightMinusOne);
-                            myThreadkernels->P2P(toWork.getCurrentGlobalCoordinate(), toWork.getCurrentListTargets(), neighbors, counter);
+                            myThreadkernels->P2P(toWork.getCurrentGlobalCoordinate(), toWork.getCurrentListTargets(),
+                                                 toWork.getCurrentListSrc(), neighbors, counter);
                         }
                     }
 
diff --git a/Src/Core/FFmmAlgorithmThread.hpp b/Src/Core/FFmmAlgorithmThread.hpp
index 2c34c7e14e5586d38502784cdc0e55786a86010d..d243b7881cc8104318fc6f1bbdc8af7018e55df6 100644
--- a/Src/Core/FFmmAlgorithmThread.hpp
+++ b/Src/Core/FFmmAlgorithmThread.hpp
@@ -384,7 +384,8 @@ private:
                     // need the current particles and neighbors particles
                     FDEBUG(if(!omp_get_thread_num()) computationCounterP2P.tic());
                     const int counter = tree->getLeafsNeighbors(neighbors, currentIter.cell->getCoordinate(), LeafIndex);
-                    myThreadkernels.P2P(currentIter.cell->getCoordinate(), currentIter.targets, neighbors, counter);
+                    myThreadkernels.P2P(currentIter.cell->getCoordinate(), currentIter.targets,
+                                        currentIter.sources, neighbors, counter);
                     FDEBUG(if(!omp_get_thread_num()) computationCounterP2P.tac());
                 }
 
diff --git a/Src/Core/FFmmAlgorithmThreadProc.hpp b/Src/Core/FFmmAlgorithmThreadProc.hpp
index b7a9b1a2361f6db76106b22705cab382d79a2fe5..5d3a786cc78e3b0f90e5bd4aeffd5b2077732c2b 100644
--- a/Src/Core/FFmmAlgorithmThreadProc.hpp
+++ b/Src/Core/FFmmAlgorithmThreadProc.hpp
@@ -1133,7 +1133,8 @@ private:
 
                         // need the current particles and neighbors particles
                         const int counter = tree->getLeafsNeighbors(neighbors, currentIter.cell->getCoordinate(), LeafIndex);
-                        myThreadkernels.P2P( currentIter.cell->getCoordinate(),currentIter.targets, neighbors, counter);
+                        myThreadkernels.P2P( currentIter.cell->getCoordinate(),currentIter.targets,
+                                             currentIter.sources, neighbors, counter);
                     }
                 }
 
@@ -1221,7 +1222,8 @@ private:
                             }
                         }
 
-                        myThreadkernels.P2P( currentIter.cell->getCoordinate(), currentIter.targets, neighbors, counter);
+                        myThreadkernels.P2P( currentIter.cell->getCoordinate(), currentIter.targets,
+                                             currentIter.sources, neighbors, counter);
                     }
                 }
 
diff --git a/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp b/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
index 616e6631498bafb9a8b862d73eccd28f39f74042..5d80b0c978f2073214ff7f1f2b96838d6623f3f3 100644
--- a/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
+++ b/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
@@ -1210,7 +1210,8 @@ private:
 
                         // need the current particles and neighbors particles
                         const int counter = tree->getPeriodicLeafsNeighbors(neighbors, currentIter.cell->getCoordinate(), LeafIndex);
-                        myThreadkernels.P2P( currentIter.cell->getCoordinate(), currentIter.targets, neighbors, counter);
+                        myThreadkernels.P2P( currentIter.cell->getCoordinate(), currentIter.targets,
+                                             currentIter.sources, neighbors, counter);
                     }
                 }
 
@@ -1305,7 +1306,8 @@ private:
                             }
                         }
 
-                        myThreadkernels.P2P( currentIter.cell->getCoordinate(), currentIter.targets, neighbors, counter);
+                        myThreadkernels.P2P( currentIter.cell->getCoordinate(), currentIter.targets,
+                                             currentIter.sources, neighbors, counter);
                     }
                 }
 
diff --git a/Src/Kernels/FAbstractSphericalKernel.hpp b/Src/Kernels/FAbstractSphericalKernel.hpp
index 7b3b1e0781a7ffe32bb0e1e5e761e0afda6a8c4c..4ee09e3aa2e36f2927472ff6342f3d95eb71ae58 100644
--- a/Src/Kernels/FAbstractSphericalKernel.hpp
+++ b/Src/Kernels/FAbstractSphericalKernel.hpp
@@ -198,6 +198,32 @@ public:
       * neighbors.
       */
     void P2P(const FTreeCoordinate& inLeafPosition,
+                  ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
+                  ContainerClass* const directNeighborsParticles[27], const int size){
+
+        if( targets == sources ){
+            P2PNoTsm(inLeafPosition, targets, directNeighborsParticles, size);
+        }
+        else{
+            P2PTsm(inLeafPosition, targets, sources, directNeighborsParticles, size);
+        }
+    }
+
+private:
+
+    ///////////////////////////////////////////////////////////////////////////////
+    //                                  P2P possibilities
+    ///////////////////////////////////////////////////////////////////////////////
+
+    /** This P2P has to be used when target != sources
+      * It will proceed an direct interation no mutual
+      *
+      * It takes all the target particles from the current leaf,
+      * then it computes the sources/targets interaction in this leaf,
+      * then it computes the sources/targets inteactions between this leaf and the
+      * neighbors.
+      */
+    void P2PTsm(const FTreeCoordinate& inLeafPosition,
                   ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
                   ContainerClass* const directNeighborsParticles[27], const int ){
 
@@ -249,7 +275,7 @@ public:
       * then it computes the  inteactions between this leaf and the
       * neighbors.
       */
-    void P2P(const FTreeCoordinate& inLeafPosition,
+    void P2PNoTsm(const FTreeCoordinate& inLeafPosition,
              ContainerClass* const FRestrict targets,
              ContainerClass* const directNeighborsParticles[27], const int ){
         { // Compute interaction in this leaf
@@ -297,7 +323,7 @@ public:
     ///////////////////////////////////////////////////////////////////////////////
     //                                  Computation
     ///////////////////////////////////////////////////////////////////////////////
-private:
+
 
     /** P2M computation
     * expansion_P2M_add