From 8067ae8bdfaf662c671702eb33b58ce27de5b1d6 Mon Sep 17 00:00:00 2001
From: Olivier Coulaud <Olivier.Coulaud@inria.fr>
Date: Tue, 12 Jun 2018 11:58:35 +0200
Subject: [PATCH] Remove some errors+warning with gcc 8

---
 Contribs/json.hpp                            |   4 +-
 README.md                                    |  13 +-
 Src/Containers/FBufferReader.hpp             |   2 +
 Src/Core/FFmmAlgorithmThreadProc.hpp         | 136 +++++---
 Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp | 329 ++++++++++---------
 Src/Utils/FAlgorithmTimers.cpp               |   1 +
 Src/Utils/FAlgorithmTimers.hpp               |   5 +-
 Src/Utils/FComplex.hpp                       |   5 +-
 8 files changed, 271 insertions(+), 224 deletions(-)

diff --git a/Contribs/json.hpp b/Contribs/json.hpp
index 6dfc1831f..7c9a17a7c 100644
--- a/Contribs/json.hpp
+++ b/Contribs/json.hpp
@@ -1913,8 +1913,8 @@ class basic_json
 
     @since version 1.0.0
     */
-    basic_json(const value_t value_type)
-        : m_type(value_type), m_value(value_type)
+    basic_json(const value_t value_type1)
+        : m_type(value_type1), m_value(value_type1)
     {
         assert_invariant();
     }
diff --git a/README.md b/README.md
index 654ca2af1..a8a8f525e 100644
--- a/README.md
+++ b/README.md
@@ -28,15 +28,14 @@ The following are optional:
   - Custom BLAS, FFT implementations.
   - [StarPU](http://starpu.gforge.inria.fr/) for the relevant FMM implementations.
 
-### To get and Build ScalFMM
-
-To obtain ScalFMM (develop branch) and its git submodules do
+### Get and Build ScalFMM
+To use last development states of ScalFMM, please clone the develop
+  branch. Note that ScalFMM contains a git submodule `morse_cmake`.
+  To get sources please use these commands:
 ``` bash
 git clone --recursive git@gitlab.inria.fr:solverstack/ScalFMM.git -b develop
 ```
-
 or
-
 ```bash
 git clone git@gitlab.inria.fr:solverstack/ScalFMM.git
 cd ScalFMM
@@ -55,9 +54,9 @@ The build may be configured after the first CMake invocation using, for instance
 
 ```bash
 # Still in the Build folder
-ccmake .
+ccmake ../
 # Or
-cmake-gui .
+cmake-gui ../
 ```
 
 The binaries are then compiled calling `make`. They can be found in `scalfmm/Build/Tests/{Release,Debug}/...`
diff --git a/Src/Containers/FBufferReader.hpp b/Src/Containers/FBufferReader.hpp
index b898b2db3..881dd2587 100644
--- a/Src/Containers/FBufferReader.hpp
+++ b/Src/Containers/FBufferReader.hpp
@@ -3,6 +3,7 @@
 #define FBUFFERREADER_HPP
 
 #include <memory>
+#include <algorithm>
 #include "FAbstractBuffer.hpp"
 #include "FBufferWriter.hpp"
 #include "Utils/FAssert.hpp"
@@ -213,6 +214,7 @@ public :
     template <class T>
     void fillArray(T* const inArray, const FSize count){
         FAssertLF(currentIndex + FSize(sizeof(T))*count <= arrayCapacity );
+     //   std::copy(&(array[currentIndex]),&(array[currentIndex])+count, inArray);
         memcpy(inArray, &array[currentIndex], sizeof(T)*count);
         currentIndex += sizeof(T)*count;
     }
diff --git a/Src/Core/FFmmAlgorithmThreadProc.hpp b/Src/Core/FFmmAlgorithmThreadProc.hpp
index 891e4284f..4aca3d4e2 100644
--- a/Src/Core/FFmmAlgorithmThreadProc.hpp
+++ b/Src/Core/FFmmAlgorithmThreadProc.hpp
@@ -4,36 +4,39 @@
 
 #define SCALFMM_DISTRIBUTED_ALGORITHM
 
-#include <omp.h>
+
 #include <algorithm>
+#include <vector>
+#include <memory>
+//#include <sys/time.h>
+
+//
+#ifdef _OPENMP
+#include <omp.h>
+#endif
 //
 #include "Utils/FGlobal.hpp"
 #include "Utils/FAssert.hpp"
 #include "Utils/FLog.hpp"
 
 #include "Utils/FTic.hpp"
-#include "Utils/FAlgorithmTimers.hpp"
 
-#include "Utils/FGlobal.hpp"
-
-#include "../Containers/FBoolArray.hpp"
-#include "../Containers/FOctree.hpp"
-#include "../Containers/FLightOctree.hpp"
 #include "Utils/FEnv.hpp"
+#include "Utils/FMpi.hpp"
 
-#include "../Containers/FBufferWriter.hpp"
-#include "../Containers/FBufferReader.hpp"
-
-#include "../Containers/FVector.hpp"
+#include "Containers/FVector.hpp"
+#include "Containers/FBoolArray.hpp"
+#include "Containers/FOctree.hpp"
+#include "Containers/FLightOctree.hpp"
 
-#include "Utils/FMpi.hpp"
-#include <sys/time.h>
+#include "Containers/FBufferWriter.hpp"
+#include "Containers/FBufferReader.hpp"
 
 #include "FCoreCommon.hpp"
 #include "FP2PExclusion.hpp"
 
-#include <memory>
-#include <vector>
+#include "Utils/FAlgorithmTimers.hpp"
+
 
 /**
  * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -66,21 +69,21 @@ private:
     OctreeClass* const tree;     ///< The octree to work on
     KernelClass** kernels;       ///< The kernels
 
-    const FMpi::FComm comm;      ///< MPI comm
-    FMpi::FComm fcomCompute;
+    const int OctreeHeight;      ///< Tree height
+
 
-    /// Used to store pointers to cells/leafs to work with
-    typename OctreeClass::Iterator* iterArray;
-    /// Used to store pointers to cells/leafs to send/rcv
-    typename OctreeClass::Iterator* iterArrayComm;
+    typename OctreeClass::Iterator* iterArray;  ///<  Used to store pointers to cells/leafs to work with
+    typename OctreeClass::Iterator* iterArrayComm;  ///< Used to store pointers to cells/leafs to send/rcv
+
+    const FMpi::FComm comm;      ///< MPI communicator
+    FMpi::FComm fcomCompute;
 
     int numberOfLeafs;           ///< To store the size at the previous level
     const int MaxThreads;        ///< Max number of thread allowed by openmp
-    const int nbProcessOrig;         ///< Process count
-    const int idProcessOrig;         ///< Current process id
-    int nbProcess;        ///< Process count
-    int idProcess;        ///< Current process id
-    const int OctreeHeight;      ///< Tree height
+          int nbProcess;         ///< Process count
+          int idProcess;         ///< Current process id
+    const int nbProcessOrig;     ///< Process count
+    const int idProcessOrig;     ///< Current process id
 
     const int userChunkSize;
     const int leafLevelSeparationCriteria;
@@ -106,8 +109,6 @@ private:
     const Interval& getWorkingInterval( int level,  int proc) const {
         return workingIntervalsPerLevel[OctreeHeight * proc + level];
     }
-
-
     /// Does \a procIdx have work at given \a idxLevel
     /** i.e. does it hold cells and is responsible of them ? */
     bool procHasWorkAtLevel(const int idxLevel , const int idxProc) const {
@@ -125,21 +126,23 @@ private:
     }
 
 public:
-    /// Get an interval from a process id and tree level
-//    Interval& getWorkingInterval( int level,  int proc){
-//        return workingIntervalsPerLevel[OctreeHeight * proc + level];
-//    }
-//    /// Get an interval from a process id and tree level
-//    const Interval& getWorkingInterval( int level,  int proc) const {
-//        return workingIntervalsPerLevel[OctreeHeight * proc + level];
-//    }
-    /// Get current process interval at given \a level
+    ///
+    /// \brief getWorkingInterval
+    /// \param level level in th tree
+    /// \return the interval from current process at tree level
+    ///
     Interval& getWorkingInterval( int level){
         return getWorkingInterval(level, idProcess);
     }
-    /// Build and dill vector of the  MortonIndex Distribution at Leaf level
-    ///  p = mpi process id then
-    ///  [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p+1] is the morton index shared by process p
+    /// Get the Morton index Distribution at the leaf level
+    ///
+    /// Fill the vector mortonDistribution
+    ///
+    /// p = mpi process id then
+    ///  Processor p owns indexes between [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p]+1]
+    ///
+    /// parameter[out] mortonLeafDistribution
+    ///
     void getMortonLeafDistribution(std::vector<MortonIndex> & mortonLeafDistribution) final {
       mortonLeafDistribution.resize(2*nbProcess) ;
       auto level =  OctreeHeight - 1;
@@ -148,14 +151,48 @@ public:
               mortonLeafDistribution[2*p]   = inter.leftIndex;
               mortonLeafDistribution[2*p+1] = inter.rightIndex;
           }
-
     }
 
+//    /// Build and dill vector of the  MortonIndex Distribution at Leaf level
+//    ///  p = mpi process id then
+//    ///  [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p+1] is the morton index shared by process p
+//    void getMortonLeafDistribution(std::vector<MortonIndex> & mortonLeafDistribution) final {
+//      mortonLeafDistribution.resize(2*nbProcess) ;
+//      auto level =  OctreeHeight - 1;
+//      for (int p=0 ; p< nbProcess ; ++p ){
+//              auto inter = this->getWorkingInterval(level, p  );
+//              mortonLeafDistribution[2*p]   = inter.leftIndex;
+//              mortonLeafDistribution[2*p+1] = inter.rightIndex;
+//          }
+
+//    }
+    ///
+    /// \brief setKernel
+    /// \param inKernels a pointer on the computational kernel used in the algorithm
+    ///
+    /// @todo move it in private section
+    void setKernel(KernelClass*const inKernels){
+      this->kernels = new KernelClass*[MaxThreads]{};
+  #pragma omp parallel num_threads(MaxThreads)
+      {
+  #pragma omp critical (InitFFmmAlgorithmThreadProcPeriodic)
+        {
+          this->kernels[omp_get_thread_num()] = new KernelClass(*inKernels);
+        }
+      }
+    }
+    ///
+    /// \brief getPtrOnMortonIndexAtLeaf
+    /// \return
+    ///
     const MortonIndex * getPtrOnMortonIndexAtLeaf() {
       return &workingIntervalsPerLevel[0].leftIndex ;
     }
-    /// Does the current process has some work at this level ?
-    bool hasWorkAtLevel( int level){
+    ///
+    /// \brief hasWorkAtLevel - Does the current process have some work at this level ?
+    /// \param level
+    /// \return true if the current process have some work at this level
+      bool hasWorkAtLevel( int level){
         return idProcess == 0 || (getWorkingInterval(level, idProcess - 1).rightIndex) < (getWorkingInterval(level, idProcess).rightIndex);
     }
 
@@ -171,17 +208,17 @@ public:
                             const int inLeafLevelSeperationCriteria = 1) :
         tree(inTree),
         kernels(nullptr),
-        comm(inComm),
-        fcomCompute(inComm),
+        OctreeHeight(tree->getHeight()),
         iterArray(nullptr),
         iterArrayComm(nullptr),
+        comm(inComm),
+        fcomCompute(inComm),
         numberOfLeafs(0),
         MaxThreads(FEnv::GetValue("SCALFMM_ALGO_NUM_THREADS",omp_get_max_threads())),
-        nbProcessOrig(inComm.processCount()),
-        idProcessOrig(inComm.processId()),
         nbProcess(0),
         idProcess(0),
-        OctreeHeight(tree->getHeight()),
+        nbProcessOrig(inComm.processCount()),
+        idProcessOrig(inComm.processId()),
         userChunkSize(inUserChunkSize),
         leafLevelSeparationCriteria(inLeafLevelSeperationCriteria),
         intervals(new Interval[inComm.processCount()]),
@@ -189,6 +226,7 @@ public:
         FAssertLF(tree, "tree cannot be null");
         FAssertLF(leafLevelSeparationCriteria < 3, "Separation criteria should be < 3");
 
+    //    this->setKernel(inKernels) ;
         this->kernels = new KernelClass*[MaxThreads];
 #pragma omp parallel num_threads(MaxThreads)
         {
@@ -1703,7 +1741,7 @@ protected:
                 }
             }
 
-            // Wait the come to finish (and the previous computation also)
+            // Wait the communications to finish (and the previous computation also)
 #pragma omp barrier
 
 
diff --git a/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp b/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
index a024ad0b4..b0676205f 100644
--- a/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
+++ b/Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
@@ -8,14 +8,19 @@
 #include <array>
 #include <vector>
 #include <memory>
-
+//
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+//
+#include "Utils/FGlobal.hpp"
 #include "Utils/FAssert.hpp"
 #include "Utils/FLog.hpp"
 
 #include "Utils/FTic.hpp"
-#include "Utils/FGlobal.hpp"
 #include "Utils/FMemUtils.hpp"
 #include "Utils/FEnv.hpp"
+#include "Utils/FMpi.hpp"
 
 #include "Containers/FVector.hpp"
 #include "Containers/FBoolArray.hpp"
@@ -25,13 +30,6 @@
 #include "Containers/FBufferWriter.hpp"
 #include "Containers/FBufferReader.hpp"
 
-#include "Utils/FEnv.hpp"
-
-#include "Utils/FMpi.hpp"
-#ifdef _OPENMP
-#include <omp.h>
-#endif
-
 #include "FCoreCommon.hpp"
 #include "FP2PExclusion.hpp"
 
@@ -61,9 +59,9 @@
 template<class FReal, class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass, class P2PExclusionClass = FP2PMiddleExclusion>
 class FFmmAlgorithmThreadProcPeriodic : public FAbstractAlgorithm, public FAlgorithmTimers {
 
-  using multipole_t = typename CellClass::multipole_t;
+  using multipole_t       = typename CellClass::multipole_t;
   using local_expansion_t = typename CellClass::local_expansion_t;
-  using symbolic_data_t = CellClass;
+  using symbolic_data_t   = CellClass;
 
 
   OctreeClass* const tree;                 ///< The octree to work on
@@ -97,33 +95,10 @@ class FFmmAlgorithmThreadProcPeriodic : public FAbstractAlgorithm, public FAlgor
   /// All processes intervals
   Interval*const workingIntervalsPerLevel;
 
-public:
-
-
-  /// Get the Morton index Distribution at the leaf level
-  ///
-  /// Fill the vector mortonDistribution
-  ///
-  /// p = mpi process id then
-  ///  Processor p owns indexes between [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p]+1]
-  ///
-  /// parameter[out] mortonLeafDistribution
-  ///
-  void getMortonLeafDistribution(std::vector<MortonIndex> & mortonLeafDistribution) final {
-    mortonLeafDistribution.resize(2*nbProcess) ;
-    auto level =  OctreeHeight - 1;
-    for (int p=0 ; p< nbProcess ; ++p ){
-            auto inter = this->getWorkingInterval(level, p  );
-            mortonLeafDistribution[2*p]   = inter.leftIndex;
-            mortonLeafDistribution[2*p+1] = inter.rightIndex;
-        }
-  }
-private:
   /// Get an interval from a process id and tree level
   Interval& getWorkingInterval( int level,  int proc){
     return workingIntervalsPerLevel[OctreeHeight * proc + level];
   }
-
   /// Get an interval from a process id and tree level
   const Interval& getWorkingInterval( int level,  int proc) const {
     return workingIntervalsPerLevel[OctreeHeight * proc + level];
@@ -145,9 +120,41 @@ private:
   }
 
 public:
+  ///
+  /// \brief getWorkingInterval
+  /// \param level level in th tree
+  /// \return the interval from current process at tree level
+  ///
+  Interval& getWorkingInterval( int level){
+      return getWorkingInterval(level, idProcess);
+  }
+  /// Get the Morton index Distribution at the leaf level
+  ///
+  /// Fill the vector mortonDistribution
+  ///
+  /// p = mpi process id then
+  ///  Processor p owns indexes between [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p]+1]
+  ///
+  /// parameter[out] mortonLeafDistribution
+  ///
+  void getMortonLeafDistribution(std::vector<MortonIndex> & mortonLeafDistribution) final {
+    mortonLeafDistribution.resize(2*nbProcess) ;
+    auto level =  OctreeHeight - 1;
+    for (int p=0 ; p< nbProcess ; ++p ){
+            auto inter = this->getWorkingInterval(level, p  );
+            mortonLeafDistribution[2*p]   = inter.leftIndex;
+            mortonLeafDistribution[2*p+1] = inter.rightIndex;
+        }
+  }
 
+  ///
+  /// \brief setKernel
+  /// \param inKernels a pointer on the computational kernel used in the algorithm
+  ///
+  /// @todo move it in private section --> warning we need to extend the box
+  ///
   void setKernel(KernelClass*const inKernels){
-    this->kernels = new KernelClass*[MaxThreads];
+    this->kernels = new KernelClass*[MaxThreads]{};
 #pragma omp parallel num_threads(MaxThreads)
     {
 #pragma omp critical (InitFFmmAlgorithmThreadProcPeriodic)
@@ -156,20 +163,18 @@ public:
       }
     }
   }
-//  /// Build and dill vector of the  MortonIndex Distribution at Leaf level
-//  ///  p = mpi process id then
-//  ///  [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p+1] is the morton index shared by process p
-//  virtual void getAndBuildMortonIndexAtLeaf(std::vector<MortonIndex> & mortonLeafDistribution) {
-//      mortonLeafDistribution.resize(2*nbProcess) ;
-
-
-//  } ;
-
-  Interval& getWorkingInterval(const int level){
-    return getWorkingInterval(level, idProcess);
+  ///
+  /// \brief getPtrOnMortonIndexAtLeaf
+  /// \return
+  ///
+  const MortonIndex * getPtrOnMortonIndexAtLeaf() {
+    return &workingIntervalsPerLevel[0].leftIndex ;
   }
-
-  /// Does the current process have some work at this level ?
+///
+/// \brief hasWorkAtLevel - Does the current process have some work at this level ?
+/// \param level
+/// \return true if the current process have some work at this level
+///
   bool hasWorkAtLevel(int level){
     return idProcess == 0 || (getWorkingInterval(level, idProcess - 1).rightIndex) < (getWorkingInterval(level, idProcess).rightIndex);
   }
@@ -222,120 +227,6 @@ public:
     delete [] workingIntervalsPerLevel;
   }
 
-
-
-
-  long long int theoricalRepetition() const {
-    if( nbLevelsAboveRoot == -1 ){
-        // we know it is 3 (-1;+1)
-        return 3;
-      }
-    // Else we find the repetition in one dir and double it
-    return 6 * (1<<(nbLevelsAboveRoot));
-  }
-  //
-  //
-  //
-  void repetitionsIntervals(FTreeCoordinate*const min, FTreeCoordinate*const max) const {
-    if( nbLevelsAboveRoot == -1 ){
-        // We know it is (-1;1)
-        min->setPosition(-1,-1,-1);
-        max->setPosition(1,1,1);
-      }
-    else{
-        const int halfRepeated = int(theoricalRepetition()/2);
-        min->setPosition(-halfRepeated,-halfRepeated,-halfRepeated);
-        // if we repeat the box 8 times, we go from [-4 to 3]
-        max->setPosition(halfRepeated-1,halfRepeated-1,halfRepeated-1);
-      }
-  }
-
-
-  FReal extendedBoxWidth() const {
-    if( nbLevelsAboveRoot == -1 ){
-        return tree->getBoxWidth()*2;
-      }
-    else{
-        return tree->getBoxWidth() * FReal(4<<(nbLevelsAboveRoot));
-      }
-  }
-
-  FReal extendedBoxWidthBoundary() const {
-    if( nbLevelsAboveRoot == -1 ){
-        return tree->getBoxWidth()*4;
-      }
-    else{
-        return tree->getBoxWidth() * FReal(8<<(nbLevelsAboveRoot));
-      }
-  }
-
-  /** This function has to be used to init the kernel with correct args
-   * It returns the box center seen from a kernel point of view from the periodicity the user ask for
-   * this is computed using the originalBoxWidth and originalBoxCenter given in parameter
-   *
-   * @param originalBoxCenter the real system center
-   * @param originalBoxWidth the real system size
-   *
-   * @return the center the kernel should use
-   */
-  FPoint<FReal> extendedBoxCenter() const {
-    if( nbLevelsAboveRoot == -1 ){
-        const FReal originalBoxWidth            = tree->getBoxWidth();
-        const FPoint<FReal> originalBoxCenter   = tree->getBoxCenter();
-        const FReal originalBoxWidthDiv2        = originalBoxWidth/2.0;
-        return FPoint<FReal>( originalBoxCenter.getX() + originalBoxWidthDiv2,
-                              originalBoxCenter.getY() + originalBoxWidthDiv2,
-                              originalBoxCenter.getZ() + originalBoxWidthDiv2);
-      } else {
-        const FReal originalBoxWidth     = tree->getBoxWidth();
-        const FReal originalBoxWidthDiv2 = originalBoxWidth/2.0;
-        const FPoint<FReal> originalBoxCenter   = tree->getBoxCenter();
-
-        const FReal offset = extendedBoxWidth()/FReal(2.0);
-        return FPoint<FReal>( originalBoxCenter.getX() - originalBoxWidthDiv2 + offset,
-                              originalBoxCenter.getY() - originalBoxWidthDiv2 + offset,
-                              originalBoxCenter.getZ() - originalBoxWidthDiv2 + offset);
-      }
-  }
-
-  FPoint<FReal> extendedBoxCenterBoundary() const {
-    if( nbLevelsAboveRoot == -1 ){
-        const FReal originalBoxWidth            = tree->getBoxWidth();
-        const FPoint<FReal> originalBoxCenter   = tree->getBoxCenter();
-        const FReal originalBoxWidthDiv2        = originalBoxWidth/2.0;
-        return FPoint<FReal>( originalBoxCenter.getX() + originalBoxWidthDiv2,
-                              originalBoxCenter.getY() + originalBoxWidthDiv2,
-                              originalBoxCenter.getZ() + originalBoxWidthDiv2);
-      } else {
-        const FReal originalBoxWidth     = tree->getBoxWidth();
-        const FReal originalBoxWidthDiv2 = originalBoxWidth/2.0;
-        const FPoint<FReal> originalBoxCenter   = tree->getBoxCenter();
-
-        return FPoint<FReal>( originalBoxCenter.getX() + originalBoxWidthDiv2,
-                              originalBoxCenter.getY() + originalBoxWidthDiv2,
-                              originalBoxCenter.getZ() + originalBoxWidthDiv2);
-      }
-  }
-
-  /** This function has to be used to init the kernel with correct args
-   * it returns the tree height seen from a kernel point of view from the periodicity the user ask for
-   * this is computed using the originalTreeHeight given in parameter
-   *
-   * @param originalTreeHeight the real tree heigh
-   *
-   * @return the height the kernel should use
-   */
-  int extendedTreeHeight() const {
-    // The real height
-    return OctreeHeight + offsetRealTree;
-  }
-
-  int extendedTreeHeightBoundary() const {
-    // The real height
-    return OctreeHeight + offsetRealTree + 1;
-  }
-
-
 protected:
   /**
    * To execute the fmm algorithm
@@ -2142,6 +2033,120 @@ protected:
   }
 
 public:
+
+
+
+
+  long long int theoricalRepetition() const {
+    if( nbLevelsAboveRoot == -1 ){
+        // we know it is 3 (-1;+1)
+        return 3;
+      }
+    // Else we find the repetition in one dir and double it
+    return 6 * (1<<(nbLevelsAboveRoot));
+  }
+  //
+  //
+  //
+  void repetitionsIntervals(FTreeCoordinate*const min, FTreeCoordinate*const max) const {
+    if( nbLevelsAboveRoot == -1 ){
+        // We know it is (-1;1)
+        min->setPosition(-1,-1,-1);
+        max->setPosition(1,1,1);
+      }
+    else{
+        const int halfRepeated = int(theoricalRepetition()/2);
+        min->setPosition(-halfRepeated,-halfRepeated,-halfRepeated);
+        // if we repeat the box 8 times, we go from [-4 to 3]
+        max->setPosition(halfRepeated-1,halfRepeated-1,halfRepeated-1);
+      }
+  }
+
+
+  FReal extendedBoxWidth() const {
+    if( nbLevelsAboveRoot == -1 ){
+        return tree->getBoxWidth()*2;
+      }
+    else{
+        return tree->getBoxWidth() * FReal(4<<(nbLevelsAboveRoot));
+      }
+  }
+
+  FReal extendedBoxWidthBoundary() const {
+    if( nbLevelsAboveRoot == -1 ){
+        return tree->getBoxWidth()*4;
+      }
+    else{
+        return tree->getBoxWidth() * FReal(8<<(nbLevelsAboveRoot));
+      }
+  }
+
+  /** This function has to be used to init the kernel with correct args
+   * It returns the box center seen from a kernel point of view from the periodicity the user ask for
+   * this is computed using the originalBoxWidth and originalBoxCenter given in parameter
+   *
+   * @param originalBoxCenter the real system center
+   * @param originalBoxWidth the real system size
+   *
+   * @return the center the kernel should use
+   */
+  FPoint<FReal> extendedBoxCenter() const {
+    if( nbLevelsAboveRoot == -1 ){
+        const FReal originalBoxWidth            = tree->getBoxWidth();
+        const FPoint<FReal> originalBoxCenter   = tree->getBoxCenter();
+        const FReal originalBoxWidthDiv2        = originalBoxWidth/2.0;
+        return FPoint<FReal>( originalBoxCenter.getX() + originalBoxWidthDiv2,
+                              originalBoxCenter.getY() + originalBoxWidthDiv2,
+                              originalBoxCenter.getZ() + originalBoxWidthDiv2);
+      } else {
+        const FReal originalBoxWidth     = tree->getBoxWidth();
+        const FReal originalBoxWidthDiv2 = originalBoxWidth/2.0;
+        const FPoint<FReal> originalBoxCenter   = tree->getBoxCenter();
+
+        const FReal offset = extendedBoxWidth()/FReal(2.0);
+        return FPoint<FReal>( originalBoxCenter.getX() - originalBoxWidthDiv2 + offset,
+                              originalBoxCenter.getY() - originalBoxWidthDiv2 + offset,
+                              originalBoxCenter.getZ() - originalBoxWidthDiv2 + offset);
+      }
+  }
+
+  FPoint<FReal> extendedBoxCenterBoundary() const {
+    if( nbLevelsAboveRoot == -1 ){
+        const FReal originalBoxWidth            = tree->getBoxWidth();
+        const FPoint<FReal> originalBoxCenter   = tree->getBoxCenter();
+        const FReal originalBoxWidthDiv2        = originalBoxWidth/2.0;
+        return FPoint<FReal>( originalBoxCenter.getX() + originalBoxWidthDiv2,
+                              originalBoxCenter.getY() + originalBoxWidthDiv2,
+                              originalBoxCenter.getZ() + originalBoxWidthDiv2);
+      } else {
+        const FReal originalBoxWidth     = tree->getBoxWidth();
+        const FReal originalBoxWidthDiv2 = originalBoxWidth/2.0;
+        const FPoint<FReal> originalBoxCenter   = tree->getBoxCenter();
+
+        return FPoint<FReal>( originalBoxCenter.getX() + originalBoxWidthDiv2,
+                              originalBoxCenter.getY() + originalBoxWidthDiv2,
+                              originalBoxCenter.getZ() + originalBoxWidthDiv2);
+      }
+  }
+
+  /** This function has to be used to init the kernel with correct args
+   * it returns the tree height seen from a kernel point of view from the periodicity the user ask for
+   * this is computed using the originalTreeHeight given in parameter
+   *
+   * @param originalTreeHeight the real tree heigh
+   *
+   * @return the height the kernel should use
+   */
+  int extendedTreeHeight() const {
+    // The real height
+    return OctreeHeight + offsetRealTree;
+  }
+
+  int extendedTreeHeightBoundary() const {
+    // The real height
+    return OctreeHeight + offsetRealTree + 1;
+  }
+
   //
   /// Fill structure for all adjacents cells of the cell center.
   ///
diff --git a/Src/Utils/FAlgorithmTimers.cpp b/Src/Utils/FAlgorithmTimers.cpp
index 48eec9e3d..b30b4e04f 100644
--- a/Src/Utils/FAlgorithmTimers.cpp
+++ b/Src/Utils/FAlgorithmTimers.cpp
@@ -9,3 +9,4 @@ constexpr const char* FAlgorithmTimers::P2PTimer;
 constexpr const char* FAlgorithmTimers::M2PTimer;
 constexpr const char* FAlgorithmTimers::P2LTimer;
 constexpr const char* FAlgorithmTimers::NearTimer;
+constexpr const char* FAlgorithmTimers::FarTimer;
diff --git a/Src/Utils/FAlgorithmTimers.hpp b/Src/Utils/FAlgorithmTimers.hpp
index 0cafc7e17..641d9df67 100644
--- a/Src/Utils/FAlgorithmTimers.hpp
+++ b/Src/Utils/FAlgorithmTimers.hpp
@@ -27,7 +27,8 @@ public:
     static constexpr const char* M2PTimer = "M2P";
     static constexpr const char* P2LTimer = "P2L";
     static constexpr const char* NearTimer = "Near";
-    enum {nbTimers = 9};
+    static constexpr const char* FarTimer = "Far";
+    enum {nbTimers = 10};
 
     /// Timers
     FTimerMap Timers;
@@ -45,7 +46,7 @@ public:
         double res = 0;
         try {
             res = Timers.at(TimerName).elapsed();
-        } catch(std::out_of_range) {
+        } catch(std::out_of_range&) {
             res = 0;
         }
         return res;
diff --git a/Src/Utils/FComplex.hpp b/Src/Utils/FComplex.hpp
index 06b5bc6b9..de0eeda03 100644
--- a/Src/Utils/FComplex.hpp
+++ b/Src/Utils/FComplex.hpp
@@ -15,7 +15,7 @@
 #ifndef FCOMPLEXE_HPP
 #define FCOMPLEXE_HPP
 
-
+#include <array>
 #include "FMath.hpp"
 
 /**
@@ -32,7 +32,8 @@
 */
 template <class FReal>
 class FComplex {
-    FReal complex[2];    //< Real & Imaginary
+  //std::array<FReal,2> complex;    //< Real & Imaginary
+  FReal complex[2];    //< Real & Imaginary
 
 public:
     /** Default Constructor (set complex[0]&imaginary to 0) */
-- 
GitLab