diff --git a/Addons/CKernelApi/Src/CScalfmmApi.h b/Addons/CKernelApi/Src/CScalfmmApi.h
index 3eac6ca2dc3401caf41a188f8df13f308a109f75..0559961cf7843c589cbe07a419d02861de0c6cd7 100644
--- a/Addons/CKernelApi/Src/CScalfmmApi.h
+++ b/Addons/CKernelApi/Src/CScalfmmApi.h
@@ -488,6 +488,15 @@ typedef void (*Callback_P2M)(void* cellData, void * leafData, FSize nbParticles,
  */
 typedef void (*Callback_M2M)(int level, void* parentCell, int childPosition, void* childCell, void* userData);
 
+/**
+ * @brief Function to be filled by user's M2M
+ * @param level current level in the tree
+ * @prama parentCell cell to be filled
+ * @param userData datas specific to the user's kernel
+ * @param childCell array of cells to be read
+ */
+typedef void (*Callback_M2M_Full)(int level, void* parentCell, void* childCell[8], void* userData);
+
 /**
  * @brief Function to be filled by user's M2L
  * @param level current level in the tree
@@ -529,6 +538,15 @@ typedef void (*Callback_M2LFull)(int level, void* targetCell, const int * neighb
  */
 typedef void (*Callback_L2L)(int level, void* parentCell, int childPosition, void* childCell, void* userData);
 
+/**
+ * @brief Function to be filled by user's L2L
+ * @param level current level in the tree
+ * @prama parentCell cell to be filled
+ * @param userData datas specific to the user's kernel
+ * @param childCell array of cells to be read
+ */
+typedef void (*Callback_L2L_Full)(int level, void* parentCell, void* childCell[8], void* userData);
+
 /**
  * @brief Function to be filled by user's L2P
  * @param cellData cell to be read
@@ -618,10 +636,12 @@ typedef void (*Callback_apply_on_cell)(int level, long long morton_index, int* t
 typedef struct User_Scalfmm_Kernel_Descriptor {
     Callback_P2M p2m;
     Callback_M2M m2m;
+    Callback_M2M_Full m2m_full;
     Callback_M2L m2l;
     Callback_M2L_Ext m2l_ext;
     Callback_M2LFull m2l_full;
     Callback_L2L l2l;
+    Callback_L2L_Full l2l_full;
     Callback_L2P l2p;
     Callback_P2P p2p;
     Callback_P2PFull p2p_full;
diff --git a/Addons/CKernelApi/Src/FUserKernelEngine.hpp b/Addons/CKernelApi/Src/FUserKernelEngine.hpp
index 300bceb954a17414a48ad4d6ae9202c6a21db941..f07661c6635726d9232aaa9df8df5521d299aff9 100644
--- a/Addons/CKernelApi/Src/FUserKernelEngine.hpp
+++ b/Addons/CKernelApi/Src/FUserKernelEngine.hpp
@@ -123,10 +123,18 @@ public:
 
     /** Do nothing */
     virtual void M2M(CellClass* const FRestrict cell, const CellClass*const FRestrict *const FRestrict children, const int level) {
-        if(kernel.m2m){
-            for(int idx = 0 ; idx < 8 ; ++idx){
-                if( children[idx] ){
-                    kernel.m2m(level, cell->getContainer(), idx, children[idx]->getContainer(), userData);
+        if(kernel.m2m_full){
+            std::vector<void *> userCellArray;
+            for(int i=0 ;i<8 ; ++i){
+                userCellArray.push_back(children[i]->getContainer());
+                kernel.m2m_full(level, cell->getContainer(), userCellArray.data(), userData);
+            }
+        }else{
+            if(kernel.m2m){
+                for(int idx = 0 ; idx < 8 ; ++idx){
+                    if( children[idx] ){
+                        kernel.m2m(level, cell->getContainer(), idx, children[idx]->getContainer(), userData);
+                    }
                 }
             }
         }
@@ -144,8 +152,7 @@ public:
             }
             kernel.m2l_full(level,cell->getContainer(),neighborPositions,size,userCellArray.data(),userData);
             FAssertLF("m2l_full temporary disabled ...\n");
-        }
-        else{
+        }else{
             if(kernel.m2l){
                 for(int idx = 0 ; idx < size ; ++idx){
                     const int idxNeigh = neighborPositions[idx];
@@ -157,10 +164,18 @@ public:
 
     /** Do nothing */
     virtual void L2L(const CellClass* const FRestrict cell, CellClass* FRestrict *const FRestrict children, const int level) {
-        if(kernel.l2l){
-            for(int idx = 0 ; idx < 8 ; ++idx){
-                if( children[idx] ){
-                    kernel.l2l(level, cell->getContainer(), idx, children[idx]->getContainer(), userData);
+        if(kernel.l2l_full){
+            std::vector<void *> userCellArray;
+            for(int i=0 ;i<8 ; ++i){
+                userCellArray.push_back(children[i]->getContainer());
+                kernel.l2l_full(level, cell->getContainer(), userCellArray.data(), userData);
+            }
+        }else{
+            if(kernel.l2l){
+                for(int idx = 0 ; idx < 8 ; ++idx){
+                    if( children[idx] ){
+                        kernel.l2l(level, cell->getContainer(), idx, children[idx]->getContainer(), userData);
+                    }
                 }
             }
         }