diff --git a/Src/GroupTree/FGroupTaskAlgorithm.hpp b/Src/GroupTree/FGroupTaskAlgorithm.hpp
index 042bdb24cccf06381ef357f10903a7205b4a3cff..f79082ef476b0f4f9dd1ae94782bb421ce3ceeec 100644
--- a/Src/GroupTree/FGroupTaskAlgorithm.hpp
+++ b/Src/GroupTree/FGroupTaskAlgorithm.hpp
@@ -198,99 +198,142 @@ protected:
     void transferPass(){
         FLOG( FTic timer; );
         for(int idxLevel = tree->getHeight()-1 ; idxLevel >= 2 ; --idxLevel){
-            typename std::list<CellContainerClass*>::iterator iterCells = tree->cellsBegin(idxLevel);
-            const typename std::list<CellContainerClass*>::iterator endCells = tree->cellsEnd(idxLevel);
+            std::list<std::vector<OutOfBlockInteraction> > allOutsideInteractions;
+            {
+                typename std::list<CellContainerClass*>::iterator iterCells = tree->cellsBegin(idxLevel);
+                const typename std::list<CellContainerClass*>::iterator endCells = tree->cellsEnd(idxLevel);
 
-            while(iterCells != endCells){
-                std::vector<OutOfBlockInteraction> outsideInteractions;
+                while(iterCells != endCells){
+                    allOutsideInteractions.push_back(std::vector<OutOfBlockInteraction>());
+                    std::vector<OutOfBlockInteraction>* outsideInteractions = &allOutsideInteractions.back();
 
-                { // Can be a task(inout:iterCells, out:outsideInteractions)
-                    const MortonIndex blockStartIdx = (*iterCells)->getStartingIndex();
-                    const MortonIndex blockEndIdx = (*iterCells)->getEndingIndex();
+                    CellContainerClass* currentCells = (*iterCells);
 
-                    for(MortonIndex mindex = blockStartIdx ; mindex < blockEndIdx ; ++mindex){
-                        CellClass* cell = (*iterCells)->getCell(mindex);
-                        if(cell){
-                            FAssertLF(cell->getMortonIndex() == mindex);
-                            MortonIndex interactionsIndexes[189];
-                            int interactionsPosition[189];
-                            const FTreeCoordinate coord(cell->getCoordinate());
-                            int counter = coord.getInteractionNeighbors(idxLevel,interactionsIndexes,interactionsPosition);
+                    #pragma omp task default(none) firstprivate(currentCells, outsideInteractions, idxLevel)
+                    { // Can be a task(inout:iterCells, out:outsideInteractions)
+                        const MortonIndex blockStartIdx = currentCells->getStartingIndex();
+                        const MortonIndex blockEndIdx = currentCells->getEndingIndex();
+                        KernelClass*const kernel = kernels[omp_get_thread_num()];
 
-                            const CellClass* interactions[343];
-                            memset(interactions, 0, 343*sizeof(CellClass*));
-                            int counterExistingCell = 0;
+                        for(MortonIndex mindex = blockStartIdx ; mindex < blockEndIdx ; ++mindex){
+                            CellClass* cell = currentCells->getCell(mindex);
+                            if(cell){
+                                FAssertLF(cell->getMortonIndex() == mindex);
+                                MortonIndex interactionsIndexes[189];
+                                int interactionsPosition[189];
+                                const FTreeCoordinate coord(cell->getCoordinate());
+                                int counter = coord.getInteractionNeighbors(idxLevel,interactionsIndexes,interactionsPosition);
 
-                            for(int idxInter = 0 ; idxInter < counter ; ++idxInter){
-                                if( blockStartIdx <= interactionsIndexes[idxInter] && interactionsIndexes[idxInter] < blockEndIdx ){
-                                    CellClass* interCell = (*iterCells)->getCell(interactionsIndexes[idxInter]);
-                                    if(interCell){
-                                        FAssertLF(interCell->getMortonIndex() == interactionsIndexes[idxInter]);
-                                        FAssertLF(interactions[interactionsPosition[idxInter]] == nullptr);
-                                        interactions[interactionsPosition[idxInter]] = interCell;
-                                        counterExistingCell += 1;
+                                const CellClass* interactions[343];
+                                memset(interactions, 0, 343*sizeof(CellClass*));
+                                int counterExistingCell = 0;
+
+                                for(int idxInter = 0 ; idxInter < counter ; ++idxInter){
+                                    if( blockStartIdx <= interactionsIndexes[idxInter] && interactionsIndexes[idxInter] < blockEndIdx ){
+                                        CellClass* interCell = currentCells->getCell(interactionsIndexes[idxInter]);
+                                        if(interCell){
+                                            FAssertLF(interCell->getMortonIndex() == interactionsIndexes[idxInter]);
+                                            FAssertLF(interactions[interactionsPosition[idxInter]] == nullptr);
+                                            interactions[interactionsPosition[idxInter]] = interCell;
+                                            counterExistingCell += 1;
+                                        }
+                                    }
+                                    else if(interactionsIndexes[idxInter] < mindex){
+                                        OutOfBlockInteraction property;
+                                        property.insideIndex = mindex;
+                                        property.outIndex    = interactionsIndexes[idxInter];
+                                        property.outPosition = interactionsPosition[idxInter];
+                                        (*outsideInteractions).push_back(property);
                                     }
                                 }
-                                else if(interactionsIndexes[idxInter] < mindex){
-                                    OutOfBlockInteraction property;
-                                    property.insideIndex = mindex;
-                                    property.outIndex    = interactionsIndexes[idxInter];
-                                    property.outPosition = interactionsPosition[idxInter];
-                                    outsideInteractions.push_back(property);
-                                }
-                            }
 
-                            kernels[0]->M2L( cell , interactions, counterExistingCell, idxLevel);
+                                kernel->M2L( cell , interactions, counterExistingCell, idxLevel);
+                            }
                         }
                     }
+                    ++iterCells;
                 }
+                #pragma omp taskwait
+            }
+            {
+                typename std::list<CellContainerClass*>::iterator iterCells = tree->cellsBegin(idxLevel);
+                const typename std::list<CellContainerClass*>::iterator endCells = tree->cellsEnd(idxLevel);
 
+                typename std::list<std::vector<OutOfBlockInteraction> >::iterator iterInteractions = allOutsideInteractions.begin();
 
-                // Manage outofblock interaction
-                FQuickSort<OutOfBlockInteraction, int>::QsSequential(outsideInteractions.data(),int(outsideInteractions.size()));
+                while(iterCells != endCells){
+                    typename std::vector<OutOfBlockInteraction>* outsideInteractions = &(*iterInteractions);
+#pragma omp task default(none) firstprivate(outsideInteractions)
+                    {
+                        // Manage outofblock interaction
+                        FQuickSort<OutOfBlockInteraction, int>::QsSequential((*outsideInteractions).data(),int((*outsideInteractions).size()));
+                    }
+                    ++iterCells;
+                    ++iterInteractions;
+                }
 
-                typename std::list<CellContainerClass*>::iterator iterLeftCells = tree->cellsBegin(idxLevel);
-                int currentOutInteraction = 0;
-                while(iterLeftCells != iterCells && currentOutInteraction < int(outsideInteractions.size())){
-                    const MortonIndex blockStartIdx = (*iterLeftCells)->getStartingIndex();
-                    const MortonIndex blockEndIdx = (*iterLeftCells)->getEndingIndex();
+#pragma omp taskwait
+            }
+            {
+                typename std::list<CellContainerClass*>::iterator iterCells = tree->cellsBegin(idxLevel);
+                const typename std::list<CellContainerClass*>::iterator endCells = tree->cellsEnd(idxLevel);
 
-                    while(currentOutInteraction < int(outsideInteractions.size()) && outsideInteractions[currentOutInteraction].outIndex < blockStartIdx){
-                        currentOutInteraction += 1;
-                    }
+                typename std::list<std::vector<OutOfBlockInteraction> >::iterator iterInteractions = allOutsideInteractions.begin();
 
-                    int lastOutInteraction = currentOutInteraction;
-                    while(lastOutInteraction < int(outsideInteractions.size()) && outsideInteractions[lastOutInteraction].outIndex < blockEndIdx){
-                        lastOutInteraction += 1;
-                    }
+                while(iterCells != endCells){
+                    CellContainerClass* currentCells = (*iterCells);
 
-                    { // Can be a task(in:currentOutInteraction, in:outsideInteractions, in:lastOutInteraction, inout:iterLeftCells, inout:iterCells)
-                        for(int outInterIdx = currentOutInteraction ; outInterIdx < lastOutInteraction ; ++outInterIdx){
-                            CellClass* interCell = (*iterLeftCells)->getCell(outsideInteractions[outInterIdx].outIndex);
-                            if(interCell){
-                                FAssertLF(interCell->getMortonIndex() == outsideInteractions[outInterIdx].outIndex);
-                                CellClass* cell = (*iterCells)->getCell(outsideInteractions[outInterIdx].insideIndex);
-                                FAssertLF(cell);
-                                FAssertLF(cell->getMortonIndex() == outsideInteractions[outInterIdx].insideIndex);
+                    typename std::vector<OutOfBlockInteraction>* outsideInteractions = &(*iterInteractions);
+                    typename std::list<CellContainerClass*>::iterator iterLeftCells = tree->cellsBegin(idxLevel);
+                    int currentOutInteraction = 0;
+                    while(iterLeftCells != iterCells && currentOutInteraction < int((*outsideInteractions).size())){
+                        CellContainerClass* leftCells = (*iterLeftCells);
+                        const MortonIndex blockStartIdx = (*iterLeftCells)->getStartingIndex();
+                        const MortonIndex blockEndIdx = (*iterLeftCells)->getEndingIndex();
 
-                                const CellClass* interactions[343];
-                                memset(interactions, 0, 343*sizeof(CellClass*));
-                                interactions[outsideInteractions[outInterIdx].outPosition] = interCell;
-                                const int counter = 1;
-                                kernels[0]->M2L( cell , interactions, counter, idxLevel);
+                        while(currentOutInteraction < int((*outsideInteractions).size()) && (*outsideInteractions)[currentOutInteraction].outIndex < blockStartIdx){
+                            currentOutInteraction += 1;
+                        }
+
+                        int lastOutInteraction = currentOutInteraction;
+                        while(lastOutInteraction < int((*outsideInteractions).size()) && (*outsideInteractions)[lastOutInteraction].outIndex < blockEndIdx){
+                            lastOutInteraction += 1;
+                        }
 
-                                interactions[outsideInteractions[outInterIdx].outPosition] = nullptr;
-                                interactions[getOppositeInterIndex(outsideInteractions[outInterIdx].outPosition)] = cell;
-                                kernels[0]->M2L( interCell , interactions, counter, idxLevel);
+                        #pragma omp task default(none) firstprivate(currentCells, leftCells, outsideInteractions, currentOutInteraction, lastOutInteraction, idxLevel)
+                        { // Can be a task(in:currentOutInteraction, in:outsideInteractions, in:lastOutInteraction, inout:iterLeftCells, inout:iterCells)
+                            KernelClass*const kernel = kernels[omp_get_thread_num()];
+
+                            for(int outInterIdx = currentOutInteraction ; outInterIdx < lastOutInteraction ; ++outInterIdx){
+                                CellClass* interCell = leftCells->getCell((*outsideInteractions)[outInterIdx].outIndex);
+                                if(interCell){
+                                    FAssertLF(interCell->getMortonIndex() == (*outsideInteractions)[outInterIdx].outIndex);
+                                    CellClass* cell = currentCells->getCell((*outsideInteractions)[outInterIdx].insideIndex);
+                                    FAssertLF(cell);
+                                    FAssertLF(cell->getMortonIndex() == (*outsideInteractions)[outInterIdx].insideIndex);
+
+                                    const CellClass* interactions[343];
+                                    memset(interactions, 0, 343*sizeof(CellClass*));
+                                    interactions[(*outsideInteractions)[outInterIdx].outPosition] = interCell;
+                                    const int counter = 1;
+                                    kernel->M2L( cell , interactions, counter, idxLevel);
+
+                                    interactions[(*outsideInteractions)[outInterIdx].outPosition] = nullptr;
+                                    interactions[getOppositeInterIndex((*outsideInteractions)[outInterIdx].outPosition)] = cell;
+                                    kernel->M2L( interCell , interactions, counter, idxLevel);
+                                }
                             }
                         }
+
+                        #pragma omp taskwait
+
+                        currentOutInteraction = lastOutInteraction;
+                        ++iterLeftCells;
                     }
 
-                    currentOutInteraction = lastOutInteraction;
-                    ++iterLeftCells;
+                    ++iterCells;
+                    ++iterInteractions;
                 }
-
-                ++iterCells;
             }
 
         }
@@ -382,7 +425,7 @@ protected:
                 typename std::vector<OutOfBlockInteraction>* outsideInteractions = &allOutsideInteractions.back();
                 ParticleGroupClass* containers = (*iterParticles);
 
-                #pragma omp task default(none) firstprivate(containers, outsideInteractions)
+#pragma omp task default(none) firstprivate(containers, outsideInteractions)
                 { // Can be a task(inout:iterCells, out:outsideInteractions)
                     const MortonIndex blockStartIdx = containers->getStartingIndex();
                     const MortonIndex blockEndIdx = containers->getEndingIndex();
@@ -415,7 +458,7 @@ protected:
                                     property.insideIndex = mindex;
                                     property.outIndex    = interactionsIndexes[idxInter];
                                     property.outPosition = interactionsPosition[idxInter];
-                                    outsideInteractions->push_back(property);
+                                    (*outsideInteractions).push_back(property);
                                 }
                             }
 
@@ -425,7 +468,7 @@ protected:
                 }
                 ++iterParticles;
             }
-            #pragma omp taskwait
+#pragma omp taskwait
         }
         {
             typename std::list<ParticleGroupClass*>::iterator iterParticles = tree->leavesBegin();
@@ -435,16 +478,16 @@ protected:
 
             while(iterParticles != endParticles){
                 typename std::vector<OutOfBlockInteraction>* outsideInteractions = &(*iterInteractions);
-                #pragma omp task default(none) firstprivate(outsideInteractions)
+#pragma omp task default(none) firstprivate(outsideInteractions)
                 {
                     // Manage outofblock interaction
-                    FQuickSort<OutOfBlockInteraction, int>::QsSequential(outsideInteractions->data(),int(outsideInteractions->size()));
+                    FQuickSort<OutOfBlockInteraction, int>::QsSequential((*outsideInteractions).data(),int((*outsideInteractions).size()));
                 }
                 ++iterParticles;
                 ++iterInteractions;
             }
 
-            #pragma omp taskwait
+#pragma omp taskwait
         }
         {
             typename std::list<ParticleGroupClass*>::iterator iterParticles = tree->leavesBegin();
@@ -458,21 +501,21 @@ protected:
 
                 typename std::list<ParticleGroupClass*>::iterator iterLeftParticles = tree->leavesBegin();
                 int currentOutInteraction = 0;
-                while(iterLeftParticles != iterParticles && currentOutInteraction < int(outsideInteractions->size())){
+                while(iterLeftParticles != iterParticles && currentOutInteraction < int((*outsideInteractions).size())){
                     ParticleGroupClass* leftContainers = (*iterLeftParticles);
                     const MortonIndex blockStartIdx = leftContainers->getStartingIndex();
                     const MortonIndex blockEndIdx = leftContainers->getEndingIndex();
 
-                    while(currentOutInteraction < int(outsideInteractions->size()) && (*outsideInteractions)[currentOutInteraction].outIndex < blockStartIdx){
+                    while(currentOutInteraction < int((*outsideInteractions).size()) && (*outsideInteractions)[currentOutInteraction].outIndex < blockStartIdx){
                         currentOutInteraction += 1;
                     }
 
                     int lastOutInteraction = currentOutInteraction;
-                    while(lastOutInteraction < int(outsideInteractions->size()) && (*outsideInteractions)[lastOutInteraction].outIndex < blockEndIdx){
+                    while(lastOutInteraction < int((*outsideInteractions).size()) && (*outsideInteractions)[lastOutInteraction].outIndex < blockEndIdx){
                         lastOutInteraction += 1;
                     }
 
-                    #pragma omp task default(none) firstprivate(containers, leftContainers, outsideInteractions, currentOutInteraction, lastOutInteraction)
+#pragma omp task default(none) firstprivate(containers, leftContainers, outsideInteractions, currentOutInteraction, lastOutInteraction)
                     { // Can be a task(in:currentOutInteraction, in:outsideInteractions, in:lastOutInteraction, inout:iterLeftParticles, inout:iterParticles)
                         KernelClass*const kernel = kernels[omp_get_thread_num()];
                         for(int outInterIdx = currentOutInteraction ; outInterIdx < lastOutInteraction ; ++outInterIdx){
@@ -493,7 +536,7 @@ protected:
                         }
                     }
                     // only one task but need to wait for it
-                    #pragma omp taskwait
+#pragma omp taskwait
 
                     currentOutInteraction = lastOutInteraction;
                     ++iterLeftParticles;