From 0b6ed9f6415056eada8d4121134d8c6ffeaf8712 Mon Sep 17 00:00:00 2001
From: bramas <berenger.bramas@inria.fr>
Date: Thu, 4 Dec 2014 15:52:16 +0100
Subject: [PATCH] Add a test to do only P2P or L2P in Algorithm

---
 Src/Core/FFmmAlgorithm.hpp                   |  26 +++--
 Src/Core/FFmmAlgorithmPeriodic.hpp           | 107 ++++++++++---------
 Src/Core/FFmmAlgorithmTask.hpp               |  16 +--
 Src/Core/FFmmAlgorithmThread.hpp             |  22 ++--
 Src/Core/FFmmAlgorithmThreadProc.hpp         |  23 ++--
 Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp |  92 ++++++++--------
 Src/Core/FFmmAlgorithmThreadTsm.hpp          |  18 ++--
 Src/Core/FFmmAlgorithmTsm.hpp                |  18 ++--
 8 files changed, 175 insertions(+), 147 deletions(-)

diff --git a/Src/Core/FFmmAlgorithm.hpp b/Src/Core/FFmmAlgorithm.hpp
index cc275c215..783a538d3 100755
--- a/Src/Core/FFmmAlgorithm.hpp
+++ b/Src/Core/FFmmAlgorithm.hpp
@@ -79,7 +79,7 @@ public:
 
         if(operationsToProceed & FFmmL2L) downardPass();
 
-        if( (operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P) ) directPass();
+        if( (operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P) ) directPass((operationsToProceed & FFmmP2P),(operationsToProceed & FFmmL2P));
     }
 
 private:
@@ -236,7 +236,7 @@ private:
     /////////////////////////////////////////////////////////////////////////////
 
     /** P2P */
-    void directPass(){
+    void directPass(const bool p2pEnabled, const bool l2pEnabled){
         FLOG( FLog::Controller.write("\tStart Direct Pass\n").write(FLog::Flush); );
         FLOG(FTic counterTime);
         FLOG(FTic computationCounterL2P);
@@ -250,15 +250,19 @@ private:
         ContainerClass* neighbors[27];
         // for each leafs
         do{
-            FLOG(computationCounterL2P.tic());
-            kernels->L2P(octreeIterator.getCurrentCell(), octreeIterator.getCurrentListTargets());
-            FLOG(computationCounterL2P.tac());
-            // need the current particles and neighbors particles
-            const int counter = tree->getLeafsNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(),heightMinusOne);
-            FLOG(computationCounterP2P.tic());
-            kernels->P2P(octreeIterator.getCurrentGlobalCoordinate(),octreeIterator.getCurrentListTargets(),
-                         octreeIterator.getCurrentListSrc(), neighbors, counter);
-            FLOG(computationCounterP2P.tac());
+            if(l2pEnabled){
+                FLOG(computationCounterL2P.tic());
+                kernels->L2P(octreeIterator.getCurrentCell(), octreeIterator.getCurrentListTargets());
+                FLOG(computationCounterL2P.tac());
+            }
+            if(p2pEnabled){
+                // need the current particles and neighbors particles
+                const int counter = tree->getLeafsNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(),heightMinusOne);
+                FLOG(computationCounterP2P.tic());
+                kernels->P2P(octreeIterator.getCurrentGlobalCoordinate(),octreeIterator.getCurrentListTargets(),
+                             octreeIterator.getCurrentListSrc(), neighbors, counter);
+                FLOG(computationCounterP2P.tac());
+            }
         } while(octreeIterator.moveRight());
 
 
diff --git a/Src/Core/FFmmAlgorithmPeriodic.hpp b/Src/Core/FFmmAlgorithmPeriodic.hpp
index b7fd45da9..b145d8dbe 100755
--- a/Src/Core/FFmmAlgorithmPeriodic.hpp
+++ b/Src/Core/FFmmAlgorithmPeriodic.hpp
@@ -97,7 +97,7 @@ public:
 
         if(operationsToProceed & FFmmL2L) downardPass();
 
-        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass();
+        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass((operationsToProceed & FFmmP2P),(operationsToProceed & FFmmL2P));
     }
 
 
@@ -247,7 +247,7 @@ public:
     /////////////////////////////////////////////////////////////////////////////
 
     /** P2P */
-    void directPass(){
+    void directPass(const bool p2pEnabled, const bool l2pEnabled){
         FLOG( FLog::Controller.write("\tStart Direct Pass\n").write(FLog::Flush); );
         FLOG(FTic counterTime);
         FLOG(FTic computationCounterL2P);
@@ -264,64 +264,65 @@ public:
         bool hasPeriodicLeaves;
         // for each leafs
         do{
-            FLOG(computationCounterL2P.tic());
-            kernels->L2P(octreeIterator.getCurrentCell(), octreeIterator.getCurrentListTargets());
-            FLOG(computationCounterL2P.tac());
-
-            // need the current particles and neighbors particles
-            const FTreeCoordinate centerOfLeaf = octreeIterator.getCurrentGlobalCoordinate();
-            const int counter = tree->getPeriodicLeafsNeighbors( neighbors, offsets, &hasPeriodicLeaves, centerOfLeaf, heightMinusOne, AllDirs);
-            int periodicNeighborsCounter = 0;
-
-            if(hasPeriodicLeaves){
-                ContainerClass* periodicNeighbors[27];
-                memset(periodicNeighbors, 0, 27 * sizeof(ContainerClass*));
-
-                for(int idxNeig = 0 ; idxNeig < 27 ; ++idxNeig){
-                    if( neighbors[idxNeig] && !offsets[idxNeig].equals(0,0,0) ){
-                        // Put periodic neighbors into other array
-                        periodicNeighbors[idxNeig] = neighbors[idxNeig];
-                        neighbors[idxNeig] = nullptr;
-                        ++periodicNeighborsCounter;
-
-                        FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
-                        FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
-                        FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
-
-                        for(int idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
-                            positionsX[idxPart] += boxWidth * FReal(offsets[idxNeig].getX());
-                            positionsY[idxPart] += boxWidth * FReal(offsets[idxNeig].getY());
-                            positionsZ[idxPart] += boxWidth * FReal(offsets[idxNeig].getZ());
+            if(l2pEnabled){
+                FLOG(computationCounterL2P.tic());
+                kernels->L2P(octreeIterator.getCurrentCell(), octreeIterator.getCurrentListTargets());
+                FLOG(computationCounterL2P.tac());
+            }
+            if(p2pEnabled){
+                // need the current particles and neighbors particles
+                const FTreeCoordinate centerOfLeaf = octreeIterator.getCurrentGlobalCoordinate();
+                const int counter = tree->getPeriodicLeafsNeighbors( neighbors, offsets, &hasPeriodicLeaves, centerOfLeaf, heightMinusOne, AllDirs);
+                int periodicNeighborsCounter = 0;
+
+                if(hasPeriodicLeaves){
+                    ContainerClass* periodicNeighbors[27];
+                    memset(periodicNeighbors, 0, 27 * sizeof(ContainerClass*));
+
+                    for(int idxNeig = 0 ; idxNeig < 27 ; ++idxNeig){
+                        if( neighbors[idxNeig] && !offsets[idxNeig].equals(0,0,0) ){
+                            // Put periodic neighbors into other array
+                            periodicNeighbors[idxNeig] = neighbors[idxNeig];
+                            neighbors[idxNeig] = nullptr;
+                            ++periodicNeighborsCounter;
+
+                            FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
+                            FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
+                            FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
+
+                            for(int idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
+                                positionsX[idxPart] += boxWidth * FReal(offsets[idxNeig].getX());
+                                positionsY[idxPart] += boxWidth * FReal(offsets[idxNeig].getY());
+                                positionsZ[idxPart] += boxWidth * FReal(offsets[idxNeig].getZ());
+                            }
                         }
                     }
-                }
-
-                FLOG(computationCounterP2P.tic());
-                kernels->P2PRemote(octreeIterator.getCurrentGlobalCoordinate(),octreeIterator.getCurrentListTargets(),
-                             octreeIterator.getCurrentListSrc(), periodicNeighbors, periodicNeighborsCounter);
-                FLOG(computationCounterP2P.tac());
-
-                for(int idxNeig = 0 ; idxNeig < 27 ; ++idxNeig){
-                    if( periodicNeighbors[idxNeig] ){
-                        FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
-                        FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
-                        FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
 
-                        for(int idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
-                            positionsX[idxPart] -= boxWidth * FReal(offsets[idxNeig].getX());
-                            positionsY[idxPart] -= boxWidth * FReal(offsets[idxNeig].getY());
-                            positionsZ[idxPart] -= boxWidth * FReal(offsets[idxNeig].getZ());
+                    FLOG(computationCounterP2P.tic());
+                    kernels->P2PRemote(octreeIterator.getCurrentGlobalCoordinate(),octreeIterator.getCurrentListTargets(),
+                                 octreeIterator.getCurrentListSrc(), periodicNeighbors, periodicNeighborsCounter);
+                    FLOG(computationCounterP2P.tac());
+
+                    for(int idxNeig = 0 ; idxNeig < 27 ; ++idxNeig){
+                        if( periodicNeighbors[idxNeig] ){
+                            FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
+                            FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
+                            FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
+
+                            for(int idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
+                                positionsX[idxPart] -= boxWidth * FReal(offsets[idxNeig].getX());
+                                positionsY[idxPart] -= boxWidth * FReal(offsets[idxNeig].getY());
+                                positionsZ[idxPart] -= boxWidth * FReal(offsets[idxNeig].getZ());
+                            }
                         }
                     }
                 }
-            }
-
-            FLOG(computationCounterP2P.tic());
-            kernels->P2P(octreeIterator.getCurrentGlobalCoordinate(),octreeIterator.getCurrentListTargets(),
-                         octreeIterator.getCurrentListSrc(), neighbors, counter - periodicNeighborsCounter);
-            FLOG(computationCounterP2P.tac());
-
 
+                FLOG(computationCounterP2P.tic());
+                kernels->P2P(octreeIterator.getCurrentGlobalCoordinate(),octreeIterator.getCurrentListTargets(),
+                             octreeIterator.getCurrentListSrc(), neighbors, counter - periodicNeighborsCounter);
+                FLOG(computationCounterP2P.tac());
+            }
         } while(octreeIterator.moveRight());
 
 
diff --git a/Src/Core/FFmmAlgorithmTask.hpp b/Src/Core/FFmmAlgorithmTask.hpp
index 4f9ef21cf..a8c03811d 100755
--- a/Src/Core/FFmmAlgorithmTask.hpp
+++ b/Src/Core/FFmmAlgorithmTask.hpp
@@ -94,7 +94,7 @@ public:
 
         if(operationsToProceed & FFmmL2L) downardPass();
 
-        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass();
+        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass((operationsToProceed & FFmmP2P),(operationsToProceed & FFmmL2P));
     }
 
 private:
@@ -281,7 +281,7 @@ private:
     /////////////////////////////////////////////////////////////////////////////
 
     /** P2P */
-    void directPass(){
+    void directPass(const bool p2pEnabled, const bool l2pEnabled){
         FLOG( FLog::Controller.write("\tStart Direct Pass\n").write(FLog::Flush); );
         FLOG(FTic counterTime);
         FLOG(FTic computationCounter);
@@ -317,12 +317,16 @@ private:
                     const int nbLeaf = shapes[idxShape].getSize();
                     for(int iterLeaf = 0 ; iterLeaf < nbLeaf ; ++iterLeaf ){
                         typename OctreeClass::Iterator toWork = shapes[idxShape][iterLeaf];
-                        #pragma omp task firstprivate(neighbors, toWork)
+                        #pragma omp task firstprivate(neighbors, toWork, l2pEnabled, p2pEnabled)
                         {
-                            kernels[omp_get_thread_num()]->L2P(toWork.getCurrentCell(), toWork.getCurrentListTargets());
-                            const int counter = tree->getLeafsNeighbors(neighbors, toWork.getCurrentGlobalCoordinate(),heightMinusOne);
-                            kernels[omp_get_thread_num()]->P2P(toWork.getCurrentGlobalCoordinate(), toWork.getCurrentListTargets(),
+                            if(l2pEnabled){
+                                kernels[omp_get_thread_num()]->L2P(toWork.getCurrentCell(), toWork.getCurrentListTargets());
+                            }
+                            if(p2pEnabled){
+                                const int counter = tree->getLeafsNeighbors(neighbors, toWork.getCurrentGlobalCoordinate(),heightMinusOne);
+                                kernels[omp_get_thread_num()]->P2P(toWork.getCurrentGlobalCoordinate(), toWork.getCurrentListTargets(),
                                                  toWork.getCurrentListSrc(), neighbors, counter);
+                            }
                         }
                     }
 
diff --git a/Src/Core/FFmmAlgorithmThread.hpp b/Src/Core/FFmmAlgorithmThread.hpp
index dd54bc471..084c04dfe 100755
--- a/Src/Core/FFmmAlgorithmThread.hpp
+++ b/Src/Core/FFmmAlgorithmThread.hpp
@@ -119,7 +119,7 @@ public:
 
         if(operationsToProceed & FFmmL2L) downardPass();
 
-        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass();
+        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass((operationsToProceed & FFmmP2P),(operationsToProceed & FFmmL2P));
 
         delete [] iterArray;
         iterArray = nullptr;
@@ -320,7 +320,7 @@ private:
     /////////////////////////////////////////////////////////////////////////////
 
     /** P2P */
-    void directPass(){
+    void directPass(const bool p2pEnabled, const bool l2pEnabled){
         FLOG( FLog::Controller.write("\tStart Direct Pass\n").write(FLog::Flush); );
         FLOG(FTic counterTime);
         FLOG(FTic computationCounter);
@@ -396,13 +396,17 @@ private:
                 #pragma omp for schedule(dynamic, chunkSize)
                 for(int idxLeafs = previous ; idxLeafs < endAtThisShape ; ++idxLeafs){
                     LeafData& currentIter = leafsDataArray[idxLeafs];
-                    myThreadkernels.L2P(currentIter.cell, currentIter.targets);
-                    // need the current particles and neighbors particles
-                    FLOG(if(!omp_get_thread_num()) computationCounterP2P.tic());
-                    const int counter = tree->getLeafsNeighbors(neighbors, currentIter.cell->getCoordinate(), LeafIndex);
-                    myThreadkernels.P2P(currentIter.cell->getCoordinate(), currentIter.targets,
-                                        currentIter.sources, neighbors, counter);
-                    FLOG(if(!omp_get_thread_num()) computationCounterP2P.tac());
+                    if(l2pEnabled){
+                        myThreadkernels.L2P(currentIter.cell, currentIter.targets);
+                    }
+                    if(p2pEnabled){
+                        // need the current particles and neighbors particles
+                        FLOG(if(!omp_get_thread_num()) computationCounterP2P.tic());
+                        const int counter = tree->getLeafsNeighbors(neighbors, currentIter.cell->getCoordinate(), LeafIndex);
+                        myThreadkernels.P2P(currentIter.cell->getCoordinate(), currentIter.targets,
+                                            currentIter.sources, neighbors, counter);
+                        FLOG(if(!omp_get_thread_num()) computationCounterP2P.tac());
+                    }
                 }
 
                 previous = endAtThisShape;
diff --git a/Src/Core/FFmmAlgorithmThreadProc.hpp b/Src/Core/FFmmAlgorithmThreadProc.hpp
index a4491049b..c5f702389 100644
--- a/Src/Core/FFmmAlgorithmThreadProc.hpp
+++ b/Src/Core/FFmmAlgorithmThreadProc.hpp
@@ -247,7 +247,7 @@ public:
 
         if(operationsToProceed & FFmmL2L) downardPass();
 
-        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass();
+        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass((operationsToProceed & FFmmP2P),(operationsToProceed & FFmmL2P));
 
 
         // delete array
@@ -1082,7 +1082,7 @@ private:
 
 
     /** P2P */
-    void directPass(){
+    void directPass(const bool p2pEnabled, const bool l2pEnabled){
         FLOG( FLog::Controller.write("\tStart Direct Pass\n").write(FLog::Flush); );
         FLOG( FTic counterTime);
         FLOG( FTic prepareCounter);
@@ -1139,7 +1139,7 @@ private:
 #pragma omp parallel
         {
 #pragma omp master // MUST WAIT to fill leafsNeedOther
-            {
+            if(p2pEnabled){
                 // Copy leafs
                 {
                     typename OctreeClass::Iterator octreeIterator(tree);
@@ -1203,7 +1203,7 @@ private:
 #pragma omp barrier
 
 #pragma omp master // nowait
-            {
+            if(p2pEnabled){
                 //Share to all processus globalReceiveMap
                 FLOG(gatherCounter.tic());
                 FMpi::MpiAssert( MPI_Allgather( partsToSend, nbProcess, MPI_INT, globalReceiveMap, nbProcess, MPI_INT, comm.getComm()),  __LINE__ );
@@ -1338,12 +1338,15 @@ private:
 
                                 for(int idxTaskLeaf = idxLeafs ; idxTaskLeaf < (idxLeafs + nbLeavesInTask) ; ++idxTaskLeaf){
                                     LeafData& currentIter = leafsDataArray[idxTaskLeaf];
-                                    myThreadkernels->L2P(currentIter.cell, currentIter.targets);
-
-                                    // need the current particles and neighbors particles
-                                    const int counter = tree->getLeafsNeighbors(neighbors, currentIter.coord, LeafIndex);
-                                    myThreadkernels->P2P( currentIter.coord,currentIter.targets,
+                                    if(l2pEnabled){
+                                        myThreadkernels->L2P(currentIter.cell, currentIter.targets);
+                                    }
+                                    if(p2pEnabled){
+                                        // need the current particles and neighbors particles
+                                        const int counter = tree->getLeafsNeighbors(neighbors, currentIter.coord, LeafIndex);
+                                        myThreadkernels->P2P( currentIter.coord,currentIter.targets,
                                                           currentIter.sources, neighbors, counter);
+                                    }
                                 }
                             }
                         }
@@ -1365,7 +1368,7 @@ private:
 #pragma omp master
             { FLOG( computation2Counter.tic() ); }
 
-            {
+            if(p2pEnabled){
                 KernelClass& myThreadkernels = (*kernels[omp_get_thread_num()]);
                 // There is a maximum of 26 neighbors
                 ContainerClass* neighbors[27];
diff --git a/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp b/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
index 505005dda..96d4fe8e6 100755
--- a/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
+++ b/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
@@ -246,7 +246,7 @@ public:
 
         if(operationsToProceed & FFmmL2L) downardPass();
 
-        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass();
+        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass((operationsToProceed & FFmmP2P),(operationsToProceed & FFmmL2P));
 
 
         // delete array
@@ -1204,7 +1204,7 @@ private:
 
 
     /** P2P */
-    void directPass(){
+    void directPass(const bool p2pEnabled, const bool l2pEnabled){
         FLOG( FLog::Controller.write("\tStart Direct Pass\n").write(FLog::Flush); );
         FLOG( FTic counterTime);
         FLOG( FTic prepareCounter);
@@ -1261,7 +1261,7 @@ private:
 #pragma omp parallel
         {
 #pragma omp master // MUST WAIT to fill leafsNeedOther
-            {
+            if(p2pEnabled){
                 // Copy leafs
                 {
                     typename OctreeClass::Iterator octreeIterator(tree);
@@ -1327,7 +1327,7 @@ private:
 #pragma omp barrier
 
 #pragma omp master // nowait
-            {
+            if(p2pEnabled){
                 //Share to all processus globalReceiveMap
                 FLOG(gatherCounter.tic());
                 FMpi::MpiAssert( MPI_Allgather( partsToSend, nbProcess, MPI_INT, globalReceiveMap, nbProcess, MPI_INT, comm.getComm()),  __LINE__ );
@@ -1465,55 +1465,59 @@ private:
                                 bool hasPeriodicLeaves;
                                 for(int idxTaskLeaf = idxLeafs ; idxTaskLeaf < (idxLeafs + nbLeavesInTask) ; ++idxTaskLeaf){
                                     LeafData& currentIter = leafsDataArray[idxTaskLeaf];
-                                    myThreadkernels->L2P(currentIter.cell, currentIter.targets);
-                                    // need the current particles and neighbors particles
-                                    const int counter = tree->getPeriodicLeafsNeighbors(neighbors, offsets, &hasPeriodicLeaves,
-                                                                                        currentIter.coord, LeafIndex, AllDirs);
-                                    int periodicNeighborsCounter = 0;
-
-                                    if(hasPeriodicLeaves){
-                                        ContainerClass* periodicNeighbors[27];
-                                        memset(periodicNeighbors, 0, 27 * sizeof(ContainerClass*));
-
-                                        for(int idxNeig = 0 ; idxNeig < 27 ; ++idxNeig){
-                                            if( neighbors[idxNeig] && !offsets[idxNeig].equals(0,0,0) ){
-                                                // Put periodic neighbors into other array
-                                                periodicNeighbors[idxNeig] = neighbors[idxNeig];
-                                                neighbors[idxNeig] = nullptr;
-                                                ++periodicNeighborsCounter;
-
-                                                FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
-                                                FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
-                                                FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
-
-                                                for(int idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
-                                                    positionsX[idxPart] += boxWidth * FReal(offsets[idxNeig].getX());
-                                                    positionsY[idxPart] += boxWidth * FReal(offsets[idxNeig].getY());
-                                                    positionsZ[idxPart] += boxWidth * FReal(offsets[idxNeig].getZ());
+                                    if(l2pEnabled){
+                                        myThreadkernels->L2P(currentIter.cell, currentIter.targets);
+                                    }
+                                    if(p2pEnabled){
+                                        // need the current particles and neighbors particles
+                                        const int counter = tree->getPeriodicLeafsNeighbors(neighbors, offsets, &hasPeriodicLeaves,
+                                                                                            currentIter.coord, LeafIndex, AllDirs);
+                                        int periodicNeighborsCounter = 0;
+
+                                        if(hasPeriodicLeaves){
+                                            ContainerClass* periodicNeighbors[27];
+                                            memset(periodicNeighbors, 0, 27 * sizeof(ContainerClass*));
+
+                                            for(int idxNeig = 0 ; idxNeig < 27 ; ++idxNeig){
+                                                if( neighbors[idxNeig] && !offsets[idxNeig].equals(0,0,0) ){
+                                                    // Put periodic neighbors into other array
+                                                    periodicNeighbors[idxNeig] = neighbors[idxNeig];
+                                                    neighbors[idxNeig] = nullptr;
+                                                    ++periodicNeighborsCounter;
+
+                                                    FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
+                                                    FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
+                                                    FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
+
+                                                    for(int idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
+                                                        positionsX[idxPart] += boxWidth * FReal(offsets[idxNeig].getX());
+                                                        positionsY[idxPart] += boxWidth * FReal(offsets[idxNeig].getY());
+                                                        positionsZ[idxPart] += boxWidth * FReal(offsets[idxNeig].getZ());
+                                                    }
                                                 }
                                             }
-                                        }
 
-                                        myThreadkernels->P2PRemote(currentIter.coord,currentIter.targets,
-                                                                   currentIter.sources, periodicNeighbors, periodicNeighborsCounter);
+                                            myThreadkernels->P2PRemote(currentIter.coord,currentIter.targets,
+                                                                       currentIter.sources, periodicNeighbors, periodicNeighborsCounter);
 
-                                        for(int idxNeig = 0 ; idxNeig < 27 ; ++idxNeig){
-                                            if( periodicNeighbors[idxNeig] ){
-                                                FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
-                                                FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
-                                                FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
+                                            for(int idxNeig = 0 ; idxNeig < 27 ; ++idxNeig){
+                                                if( periodicNeighbors[idxNeig] ){
+                                                    FReal*const positionsX = periodicNeighbors[idxNeig]->getWPositions()[0];
+                                                    FReal*const positionsY = periodicNeighbors[idxNeig]->getWPositions()[1];
+                                                    FReal*const positionsZ = periodicNeighbors[idxNeig]->getWPositions()[2];
 
-                                                for(int idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
-                                                    positionsX[idxPart] -= boxWidth * FReal(offsets[idxNeig].getX());
-                                                    positionsY[idxPart] -= boxWidth * FReal(offsets[idxNeig].getY());
-                                                    positionsZ[idxPart] -= boxWidth * FReal(offsets[idxNeig].getZ());
+                                                    for(int idxPart = 0; idxPart < periodicNeighbors[idxNeig]->getNbParticles() ; ++idxPart){
+                                                        positionsX[idxPart] -= boxWidth * FReal(offsets[idxNeig].getX());
+                                                        positionsY[idxPart] -= boxWidth * FReal(offsets[idxNeig].getY());
+                                                        positionsZ[idxPart] -= boxWidth * FReal(offsets[idxNeig].getZ());
+                                                    }
                                                 }
                                             }
                                         }
-                                    }
 
-                                    myThreadkernels->P2P( currentIter.coord, currentIter.targets,
+                                        myThreadkernels->P2P( currentIter.coord, currentIter.targets,
                                                           currentIter.sources, neighbors, counter - periodicNeighborsCounter);
+                                    }
                                 }
 
                             }
@@ -1537,7 +1541,7 @@ private:
 #pragma omp master
         { FLOG( computation2Counter.tic() ); }
 
-        {
+        if(p2pEnabled){
             KernelClass& myThreadkernels = (*kernels[omp_get_thread_num()]);
             // There is a maximum of 26 neighbors
             ContainerClass* neighbors[27];
diff --git a/Src/Core/FFmmAlgorithmThreadTsm.hpp b/Src/Core/FFmmAlgorithmThreadTsm.hpp
index 40b3729ac..b9b64ecc3 100755
--- a/Src/Core/FFmmAlgorithmThreadTsm.hpp
+++ b/Src/Core/FFmmAlgorithmThreadTsm.hpp
@@ -107,7 +107,7 @@ public:
 
         if(operationsToProceed & FFmmL2L) downardPass();
 
-        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass();
+        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass((operationsToProceed & FFmmP2P),(operationsToProceed & FFmmL2P));
 
         delete [] iterArray;
         iterArray = nullptr;
@@ -339,7 +339,7 @@ public:
 
 
     /** P2P */
-    void directPass(){
+    void directPass(const bool p2pEnabled, const bool l2pEnabled){
         FLOG( FLog::Controller.write("\tStart Direct Pass\n").write(FLog::Flush); );
         FLOG(FTic counterTime);
 
@@ -367,12 +367,16 @@ public:
             #pragma omp for schedule(dynamic, chunkSize) nowait
             for(int idxLeafs = 0 ; idxLeafs < numberOfLeafs ; ++idxLeafs){
                 if( iterArray[idxLeafs].getCurrentCell()->hasTargetsChild() ){
-                    myThreadkernels->L2P(iterArray[idxLeafs].getCurrentCell(), iterArray[idxLeafs].getCurrentListTargets());
-                    // need the current particles and neighbors particles
-                    const int counter = tree->getLeafsNeighbors(neighbors, iterArray[idxLeafs].getCurrentGlobalCoordinate(),heightMinusOne);
-                    neighbors[13] = iterArray[idxLeafs].getCurrentListSrc();
-                    myThreadkernels->P2PRemote( iterArray[idxLeafs].getCurrentGlobalCoordinate(), iterArray[idxLeafs].getCurrentListTargets(),
+                    if(l2pEnabled){
+                        myThreadkernels->L2P(iterArray[idxLeafs].getCurrentCell(), iterArray[idxLeafs].getCurrentListTargets());
+                    }
+                    if(p2pEnabled){
+                        // need the current particles and neighbors particles
+                        const int counter = tree->getLeafsNeighbors(neighbors, iterArray[idxLeafs].getCurrentGlobalCoordinate(),heightMinusOne);
+                        neighbors[13] = iterArray[idxLeafs].getCurrentListSrc();
+                        myThreadkernels->P2PRemote( iterArray[idxLeafs].getCurrentGlobalCoordinate(), iterArray[idxLeafs].getCurrentListTargets(),
                                       iterArray[idxLeafs].getCurrentListSrc() , neighbors, counter + 1);
+                    }
                 }
             }
         }
diff --git a/Src/Core/FFmmAlgorithmTsm.hpp b/Src/Core/FFmmAlgorithmTsm.hpp
index 63abd81fb..f14763e61 100755
--- a/Src/Core/FFmmAlgorithmTsm.hpp
+++ b/Src/Core/FFmmAlgorithmTsm.hpp
@@ -82,7 +82,7 @@ public:
 
         if(operationsToProceed & FFmmL2L) downardPass();
 
-        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass();
+        if((operationsToProceed & FFmmP2P) || (operationsToProceed & FFmmL2P)) directPass((operationsToProceed & FFmmP2P),(operationsToProceed & FFmmL2P));
     }
 
     /** P2M */
@@ -276,7 +276,7 @@ public:
 
 
     /** P2P */
-    void directPass(){
+    void directPass(const bool p2pEnabled, const bool l2pEnabled){
         FLOG( FLog::Controller.write("\tStart Direct Pass\n").write(FLog::Flush); );
         FLOG( counterTime.tic() );
         FLOG( double totalComputation = 0 );
@@ -291,12 +291,16 @@ public:
         do{
             if( octreeIterator.getCurrentCell()->hasTargetsChild() ){
                 FLOG(computationCounter.tic());
-                kernels->L2P(octreeIterator.getCurrentCell(), octreeIterator.getCurrentListTargets());
-                // need the current particles and neighbors particles
-                const int counter = tree->getLeafsNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), heightMinusOne);
-                neighbors[13] = octreeIterator.getCurrentListSrc();
-                kernels->P2PRemote( octreeIterator.getCurrentGlobalCoordinate(), octreeIterator.getCurrentListTargets(),
+                if(l2pEnabled){
+                    kernels->L2P(octreeIterator.getCurrentCell(), octreeIterator.getCurrentListTargets());
+                }
+                if(p2pEnabled){
+                    // need the current particles and neighbors particles
+                    const int counter = tree->getLeafsNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), heightMinusOne);
+                    neighbors[13] = octreeIterator.getCurrentListSrc();
+                    kernels->P2PRemote( octreeIterator.getCurrentGlobalCoordinate(), octreeIterator.getCurrentListTargets(),
                               octreeIterator.getCurrentListSrc() , neighbors, counter + 1);
+                }
                 FLOG(computationCounter.tac());
                 FLOG(totalComputation += computationCounter.elapsed());
             }
-- 
GitLab