From 81e22e4495eb9298c2780f27a9fdd98087d85408 Mon Sep 17 00:00:00 2001
From: berenger-bramas <berenger-bramas@2616d619-271b-44dc-8df4-d4a8f33a7222>
Date: Thu, 16 Feb 2012 09:17:52 +0000
Subject: [PATCH] Draft for the serialisation and sendable interface.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@392 2616d619-271b-44dc-8df4-d4a8f33a7222
---
 Src/Components/FBasicCell.hpp               |   9 ++
 Src/Components/FBasicParticle.hpp           |   7 +-
 Src/Components/FFmaParticle.hpp             |   9 +-
 Src/Components/FTestCell.hpp                |  23 +++
 Src/Components/FTestParticle.hpp            |   9 ++
 Src/Containers/FTreeCoordinate.hpp          |  12 ++
 Src/Extensions/FExtendCellType.hpp          |  13 +-
 Src/Extensions/FExtendCoordinate.hpp        |  11 ++
 Src/Extensions/FExtendForces.hpp            |  11 ++
 Src/Extensions/FExtendFullySerializable.hpp |  37 -----
 Src/Extensions/FExtendMortonIndex.hpp       |  10 ++
 Src/Extensions/FExtendParticleType.hpp      |  10 ++
 Src/Extensions/FExtendPhysicalValue.hpp     |  11 ++
 Src/Extensions/FExtendPosition.hpp          |  10 ++
 Src/Extensions/FExtendPotential.hpp         |  10 ++
 Src/Extensions/FExtendVelocity.hpp          |  11 ++
 Src/Files/FTreeIO.hpp                       | 156 ++++++++------------
 Src/Kernels/FSphericalBlasKernel.hpp        |  11 +-
 Src/Kernels/FSphericalBlockBlasKernel.hpp   |  10 +-
 Src/Kernels/FSphericalCell.hpp              |  59 +++++---
 Src/Kernels/FSphericalParticle.hpp          |  28 +++-
 Src/Utils/F3DPosition.hpp                   |  12 ++
 Src/Utils/FAbstractSerializable.hpp         |   3 -
 Src/Utils/FBlas.hpp                         |   2 +-
 Tests/testFmbAlgorithmProc.cpp              |   4 +-
 Tests/testFmmAlgorithmProc.cpp              |  29 ++--
 Tests/testTreeIO.cpp                        |  11 +-
 27 files changed, 324 insertions(+), 204 deletions(-)
 delete mode 100644 Src/Extensions/FExtendFullySerializable.hpp

diff --git a/Src/Components/FBasicCell.hpp b/Src/Components/FBasicCell.hpp
index 634e9873c..d6eedfd99 100644
--- a/Src/Components/FBasicCell.hpp
+++ b/Src/Components/FBasicCell.hpp
@@ -32,6 +32,15 @@ public:
     /** Default destructor */
     virtual ~FBasicCell(){
     }
+
+    void save(FBufferWriter& buffer) const{
+        FExtendMortonIndex::save(buffer);
+        FExtendCoordinate::save(buffer);
+    }
+    void restore(FBufferReader& buffer){
+        FExtendMortonIndex::restore(buffer);
+        FExtendCoordinate::restore(buffer);
+    }
 };
 
 
diff --git a/Src/Components/FBasicParticle.hpp b/Src/Components/FBasicParticle.hpp
index a7d0b69e7..ca953065e 100644
--- a/Src/Components/FBasicParticle.hpp
+++ b/Src/Components/FBasicParticle.hpp
@@ -27,8 +27,11 @@
 */
 class FBasicParticle : public FExtendPosition{
 public:
-    /** Default destructor */
-    virtual ~FBasicParticle(){
+    void save(FBufferWriter& buffer) const{
+        FExtendPosition::save(buffer);
+    }
+    void restore(FBufferReader& buffer){
+        FExtendPosition::restore(buffer);
     }
 };
 
diff --git a/Src/Components/FFmaParticle.hpp b/Src/Components/FFmaParticle.hpp
index 21b350070..fe915a1dc 100644
--- a/Src/Components/FFmaParticle.hpp
+++ b/Src/Components/FFmaParticle.hpp
@@ -25,8 +25,13 @@
 */
 class FFmaParticle : public FBasicParticle, public FExtendPhysicalValue {
 public:
-    /** Default destructor */
-    virtual ~FFmaParticle(){
+    void save(FBufferWriter& buffer) const{
+        FBasicParticle::save(buffer);
+        FExtendPhysicalValue::save(buffer);
+    }
+    void restore(FBufferReader& buffer){
+        FBasicParticle::restore(buffer);
+        FExtendPhysicalValue::restore(buffer);
     }
 };
 
diff --git a/Src/Components/FTestCell.hpp b/Src/Components/FTestCell.hpp
index cfb6db2ed..44b5f5c03 100644
--- a/Src/Components/FTestCell.hpp
+++ b/Src/Components/FTestCell.hpp
@@ -50,6 +50,29 @@ public:
     void setDataDown(const long long int inData){
         this->dataDown = inData;
     }
+
+    void save(FBufferWriter& buffer) const{
+        FBasicCell::save(buffer);
+        buffer << dataDown << dataUp;
+    }
+    void restore(FBufferReader& buffer){
+        FBasicCell::restore(buffer);
+        buffer >> dataDown >> dataUp;
+    }
+
+    void serializeUp(FBufferWriter& buffer) const {
+        buffer << this->dataUp;
+    }
+    void deserializeUp(FBufferReader& buffer){
+        buffer >> this->dataUp;
+    }
+
+    void serializeDown(FBufferWriter& buffer) const {
+        buffer << this->dataDown;
+    }
+    void deserializeDown(FBufferReader& buffer){
+        buffer >> this->dataDown;
+    }
 };
 
 
diff --git a/Src/Components/FTestParticle.hpp b/Src/Components/FTestParticle.hpp
index 12c9bf3f7..97e39f81c 100644
--- a/Src/Components/FTestParticle.hpp
+++ b/Src/Components/FTestParticle.hpp
@@ -45,6 +45,15 @@ public:
     void setDataDown(const long long int inData){
         this->dataDown = inData;
     }
+
+    void save(FBufferWriter& buffer) const{
+        FBasicParticle::save(buffer);
+        buffer << dataDown;
+    }
+    void restore(FBufferReader& buffer){
+        FBasicParticle::restore(buffer);
+        buffer >> dataDown;
+    }
 };
 
 
diff --git a/Src/Containers/FTreeCoordinate.hpp b/Src/Containers/FTreeCoordinate.hpp
index 7bb8c0700..04af2d3fa 100644
--- a/Src/Containers/FTreeCoordinate.hpp
+++ b/Src/Containers/FTreeCoordinate.hpp
@@ -13,6 +13,9 @@
 
 
 #include "../Utils/FGlobal.hpp"
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
+
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -211,6 +214,15 @@ public:
         return output;  // for multiple << operators.
     }
 
+
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        buffer << x << y << z;
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        buffer >> x >> y >> z;
+    }
 };
 
 
diff --git a/Src/Extensions/FExtendCellType.hpp b/Src/Extensions/FExtendCellType.hpp
index ff4fd7eb0..56b158c90 100644
--- a/Src/Extensions/FExtendCellType.hpp
+++ b/Src/Extensions/FExtendCellType.hpp
@@ -11,7 +11,8 @@
 #ifndef FEXTENDCELLTYPE_HPP
 #define FEXTENDCELLTYPE_HPP
 
-
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -67,6 +68,16 @@ public:
     void setTargetsChildTrue() {
         this->type |= ContainsTargets;
     }
+
+public:
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        buffer << type;
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        buffer >> type;
+    }
 };
 
 
diff --git a/Src/Extensions/FExtendCoordinate.hpp b/Src/Extensions/FExtendCoordinate.hpp
index eba5d0e99..d3b6ffacc 100644
--- a/Src/Extensions/FExtendCoordinate.hpp
+++ b/Src/Extensions/FExtendCoordinate.hpp
@@ -14,6 +14,8 @@
 
 #include "../Utils/FGlobal.hpp"
 #include "../Containers/FTreeCoordinate.hpp"
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -58,6 +60,15 @@ public:
         this->coordinate.setZ(inZ);
     }
 
+
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        coordinate.save(buffer);
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        coordinate.restore(buffer);
+    }
 };
 
 
diff --git a/Src/Extensions/FExtendForces.hpp b/Src/Extensions/FExtendForces.hpp
index 324b9ee9e..419a1706a 100644
--- a/Src/Extensions/FExtendForces.hpp
+++ b/Src/Extensions/FExtendForces.hpp
@@ -14,6 +14,8 @@
 
 #include "../Utils/FGlobal.hpp"
 #include "../Utils/F3DPosition.hpp"
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -63,6 +65,15 @@ public:
     void setForces(const FReal inFx, const FReal inFy, const FReal inFz) {
         this->forces.setPosition(inFx , inFy, inFz);
     }
+
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        forces.save(buffer);
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        forces.restore(buffer);
+    }
 };
 
 
diff --git a/Src/Extensions/FExtendFullySerializable.hpp b/Src/Extensions/FExtendFullySerializable.hpp
deleted file mode 100644
index 324a8aa06..000000000
--- a/Src/Extensions/FExtendFullySerializable.hpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// ===================================================================================
-// Logiciel initial: ScalFmm Version 0.5
-// Co-auteurs : Olivier Coulaud, Bérenger Bramas.
-// Propriétaires : INRIA.
-// Copyright © 2011-2012, diffusé sous les termes et conditions d’une licence propriétaire.
-// Initial software: ScalFmm Version 0.5
-// Co-authors: Olivier Coulaud, Bérenger Bramas.
-// Owners: INRIA.
-// Copyright © 2011-2012, spread under the terms and conditions of a proprietary license.
-// ===================================================================================
-#ifndef FEXTENDFULLYSENDABLE_HPP
-#define FEXTENDFULLYSENDABLE_HPP
-
-#include "../Utils/FAbstractSerializable.hpp"
-
-#include "../Containers/FBufferWriter.hpp"
-#include "../Containers/FBufferReader.hpp"
-
-/** @author Berenger Bramas
-  * This extension MUST be put as the first inherited class!
-  * It copy the memory in the buffer read writer
-  */
-template <class ClassType>
-class FExtendFullySerializable : public FAbstractSerializable {
-public:
-    /** Save current object */
-    void save(FBufferWriter& buffer) const {
-        buffer << (*reinterpret_cast<const ClassType*>(this));
-    }
-    /** Retrieve current object */
-    void restore(FBufferReader& buffer) {
-        buffer >> (*reinterpret_cast<ClassType*>(this));
-    }
-};
-
-
-#endif // FEXTENDFULLYSENDABLE_HPP
diff --git a/Src/Extensions/FExtendMortonIndex.hpp b/Src/Extensions/FExtendMortonIndex.hpp
index 90f9d6ce2..8f08d7dc7 100644
--- a/Src/Extensions/FExtendMortonIndex.hpp
+++ b/Src/Extensions/FExtendMortonIndex.hpp
@@ -14,6 +14,8 @@
 
 #include "../Utils/FGlobal.hpp"
 #include "../Containers/FTreeCoordinate.hpp"
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -51,6 +53,14 @@ public:
         this->mortonIndex = inMortonIndex;
     }
 
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        buffer << mortonIndex;
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        buffer >> mortonIndex;
+    }
 };
 
 
diff --git a/Src/Extensions/FExtendParticleType.hpp b/Src/Extensions/FExtendParticleType.hpp
index fdb5792e9..33e78fadd 100644
--- a/Src/Extensions/FExtendParticleType.hpp
+++ b/Src/Extensions/FExtendParticleType.hpp
@@ -11,6 +11,8 @@
 #ifndef FEXTENDPARTICLETYPE_HPP
 #define FEXTENDPARTICLETYPE_HPP
 
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
 
 
 /**
@@ -82,6 +84,14 @@ public:
         this->type = Source;
     }
 
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        buffer << type;
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        buffer >> type;
+    }
 };
 
 
diff --git a/Src/Extensions/FExtendPhysicalValue.hpp b/Src/Extensions/FExtendPhysicalValue.hpp
index 82a81626f..ba48390c6 100644
--- a/Src/Extensions/FExtendPhysicalValue.hpp
+++ b/Src/Extensions/FExtendPhysicalValue.hpp
@@ -13,6 +13,8 @@
 
 
 #include "../Utils/FGlobal.hpp"
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -50,6 +52,15 @@ public:
         this->physicalValue = inphysicalValue;
     }
 
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        buffer << physicalValue;
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        buffer >> physicalValue;
+    }
+
 };
 
 
diff --git a/Src/Extensions/FExtendPosition.hpp b/Src/Extensions/FExtendPosition.hpp
index ab4bcf807..8618a2d9d 100644
--- a/Src/Extensions/FExtendPosition.hpp
+++ b/Src/Extensions/FExtendPosition.hpp
@@ -14,6 +14,8 @@
 
 #include "../Utils/FGlobal.hpp"
 #include "../Utils/F3DPosition.hpp"
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -70,6 +72,14 @@ public:
         this->position.incZ(inPz);
     }
 
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        position.save(buffer);
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        position.restore(buffer);
+    }
 };
 
 
diff --git a/Src/Extensions/FExtendPotential.hpp b/Src/Extensions/FExtendPotential.hpp
index e8c85f4b2..b131acbec 100644
--- a/Src/Extensions/FExtendPotential.hpp
+++ b/Src/Extensions/FExtendPotential.hpp
@@ -13,6 +13,8 @@
 
 
 #include "../Utils/FGlobal.hpp"
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -55,6 +57,14 @@ public:
         this->potential += inPotential;
     }
 
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        buffer << potential;
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        buffer >> potential;
+    }
 };
 
 
diff --git a/Src/Extensions/FExtendVelocity.hpp b/Src/Extensions/FExtendVelocity.hpp
index 7e2f8e2ac..2eacf873b 100644
--- a/Src/Extensions/FExtendVelocity.hpp
+++ b/Src/Extensions/FExtendVelocity.hpp
@@ -15,6 +15,8 @@
 
 #include "../Utils/FGlobal.hpp"
 #include "../Utils/F3DPosition.hpp"
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -64,6 +66,15 @@ public:
     void setVelocity(const FReal inVx, const FReal inVy, const FReal inVz) {
         this->velocity.setPosition(inVx , inVy, inVz);
     }
+
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        buffer << velocity;
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        buffer >> velocity;
+    }
 };
 
 
diff --git a/Src/Files/FTreeIO.hpp b/Src/Files/FTreeIO.hpp
index 04a373921..8c556a9f5 100644
--- a/Src/Files/FTreeIO.hpp
+++ b/Src/Files/FTreeIO.hpp
@@ -14,6 +14,10 @@
 #include <iostream>
 #include <fstream>
 
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
+
+
 /** This class proposes static methods to save and load
   * a tree.
   * It used binary format (so FReal must be the same!)
@@ -27,87 +31,11 @@
   */
 class FTreeIO{
 public:
-    class FAbstractSerial {
-    protected:
-        template <class TypeClass>
-        void save(std::ofstream*const stream, const TypeClass& value) const{
-            stream->write((const char*)&value, sizeof(TypeClass));
-        }
-
-        template <class TypeClass>
-        TypeClass restore(std::ifstream*const stream) const{
-            TypeClass value;
-            stream->read((char*)&value, sizeof(TypeClass));
-            return value;
-        }
-
-        template <class TypeClass>
-        void saveArray(std::ofstream*const stream, const TypeClass*const values, const int size) const{
-            stream->write((const char*)values, sizeof(TypeClass) * size);
-        }
-
-        template <class TypeClass>
-        void restoreArray(std::ifstream*const stream, TypeClass*const values, const int size) const{
-            stream->read((char*)values, sizeof(TypeClass) * size);
-        }
-
-    public:
-
-        virtual void read(std::ifstream*const stream) = 0;
-        virtual void write(std::ofstream*const stream) const = 0;
-    };
-
-
-    /** The serializer class call a method on the particles or cells
-      * So they have to implement the write/read method
-      */
-    template <class CellClass, class ParticleClass>
-    class Serializer {
-    public:
-        static void PutCell(std::ofstream*const stream, const CellClass*const cell) {
-            cell->write(stream);
-        }
-        static void PutParticles(std::ofstream*const stream, const ParticleClass* const particles, const int nbParticles) {
-            for( int idxParticle = 0 ; idxParticle < nbParticles ; ++idxParticle){
-                particles[idxParticle].write(stream);
-            }
-        }
-
-        static void GetCell(std::ifstream*const stream, CellClass* const cell){
-            cell->read(stream);
-        }
-
-        static void GetParticles(std::ifstream*const stream, ParticleClass* const particles, const int nbParticles){
-            for( int idxParticle = 0 ; idxParticle < nbParticles ; ++idxParticle){
-                particles[idxParticle].read(stream);
-            }
-        }
-    };
-
-    /** The copier method simple copy in memory using memcpy
-      */
-    template <class CellClass, class ParticleClass>
-    class Copier {
-    public:
-        static void PutCell(std::ofstream*const stream, const CellClass* const cell) {
-            stream->write((const char*)cell, sizeof(CellClass));
-        }
-        static void PutParticles(std::ofstream*const stream, const ParticleClass* const particles, const int nbParticles) {
-            stream->write((const char*)particles, nbParticles * sizeof(ParticleClass));
-        }
-
-        static void GetCell(std::ifstream*const stream, CellClass* const cell){
-            stream->read((char*)cell, sizeof(CellClass));
-        }
-        static void GetParticles(std::ifstream*const stream, ParticleClass* const particles, const int nbParticles){
-            stream->read((char*)particles, nbParticles * sizeof(ParticleClass));
-        }
-    };
-
     /** To save in memory */
     template <class OctreeClass, class CellClass, class ParticleClass, class ClassProptotype >
     static bool Save(const char filename[], OctreeClass& tree){
         std::ofstream file(filename, std::ofstream::binary | std::ofstream::out );
+        FBufferWriter buffer;
 
         if(!file.good()){
             return false;
@@ -130,11 +58,9 @@ public:
         {
             typename OctreeClass::Iterator octreeIterator(&tree);
 
-            int maxParticlesInLeaf = 0;
             int nbLeaf = 0;
             const std::ofstream::pos_type posNbLeaf = file.tellp();
             file.write((const char*)&nbLeaf,sizeof(int));
-            file.write((const char*)&maxParticlesInLeaf,sizeof(int));
 
             octreeIterator.gotoBottomLeft();
             const bool useTargetSource = (octreeIterator.getCurrentListSrc() != octreeIterator.getCurrentListTargets());
@@ -142,27 +68,50 @@ public:
                 do{
                     const int nbParticlesInLeaf = (octreeIterator.getCurrentListSrc()->getSize() + octreeIterator.getCurrentListTargets()->getSize());
                     file.write((const char*)&nbParticlesInLeaf,sizeof(int));
-                    ClassProptotype::PutParticles( &file, octreeIterator.getCurrentListSrc()->data(), octreeIterator.getCurrentListSrc()->getSize());
-                    ClassProptotype::PutParticles( &file, octreeIterator.getCurrentListTargets()->data(), octreeIterator.getCurrentListTargets()->getSize());
+
+                    buffer.reset();
+                    typename ContainerClass::BasicIterator iterSrc(*octreeIterator.getCurrentListSrc());
+                    while( iterSrc.hasNotFinished() ){
+                        iterSrc.data().save(buffer);
+                        iterSrc.gotoNext();
+                    }
+
+                    typename ContainerClass::BasicIterator iterTarget(*octreeIterator.getCurrentListTargets());
+                    while( iterTarget.hasNotFinished() ){
+                        iterTarget.data().save(buffer);
+                        iterTarget.gotoNext();
+                    }
+
+                    const int sizeOfLeaf = buffer.getSize();
+                    file.write((const char*) &sizeOfLeaf, sizeof(int));
+                    file.write(buffer.data(), buffer.getSize());
 
                     ++nbLeaf;
-                    if( maxParticlesInLeaf < nbParticlesInLeaf) maxParticlesInLeaf = nbParticlesInLeaf;
                 } while(octreeIterator.moveRight());
             }
             else{
                 do{
                     const int nbParticlesInLeaf = octreeIterator.getCurrentListSrc()->getSize();
                     file.write((const char*)&nbParticlesInLeaf,sizeof(int));
-                    ClassProptotype::PutParticles( &file, octreeIterator.getCurrentListSrc()->data(), octreeIterator.getCurrentListSrc()->getSize());
+
+                    buffer.reset();
+                    typename ContainerClass::BasicIterator iter(*octreeIterator.getCurrentListSrc());
+                    while( iter.hasNotFinished() ){
+                        iter.data().save(buffer);
+                        iter.gotoNext();
+                    }
+
+                    const int sizeOfLeaf= buffer.getSize();
+                    file.write((const char*) &sizeOfLeaf, sizeof(int));
+                    file.write(buffer.data(), buffer.getSize());
+
                     ++nbLeaf;
-                    if( maxParticlesInLeaf < nbParticlesInLeaf) maxParticlesInLeaf = nbParticlesInLeaf;
                 } while(octreeIterator.moveRight());
             }
 
             const std::ofstream::pos_type currentPos = file.tellp();
             file.seekp(posNbLeaf);
             file.write((const char*)&nbLeaf,sizeof(int));
-            file.write((const char*)&maxParticlesInLeaf,sizeof(int));
             file.seekp(currentPos);
         }
 
@@ -180,8 +129,14 @@ public:
 
             do{
                 const MortonIndex mindex = octreeIterator.getCurrentGlobalIndex();
-                file.write((const char*)&mindex,sizeof(MortonIndex));;
-                ClassProptotype::PutCell( &file, octreeIterator.getCurrentCell());
+                file.write((const char*)&mindex,sizeof(MortonIndex));
+
+                buffer.reset();
+                octreeIterator.getCurrentCell()->save(buffer);
+                const int sizeOfCell = buffer.getSize();
+                file.write((const char*) &sizeOfCell, sizeof(int));
+                file.write(buffer.data(), buffer.getSize());
+
                 ++nbCells;
             } while(octreeIterator.moveRight());
 
@@ -206,6 +161,7 @@ public:
     template <class OctreeClass, class CellClass, class ParticleClass, class ClassProptotype >
     static bool Load(const char filename[], OctreeClass& tree){
         std::ifstream file(filename, std::ifstream::binary | std::ifstream::in );
+        FBufferReader buffer;
 
         if(!file.good()){
             return false;
@@ -234,21 +190,24 @@ public:
         {
             int nbLeaf = 0;
             file.read((char*)&nbLeaf, sizeof(int));
-            int maxParticlesInLeaf = 0;
-            file.read((char*)&maxParticlesInLeaf, sizeof(int));
 
-            ParticleClass* const particles = new ParticleClass[maxParticlesInLeaf];
+            ParticleClass particle;
 
             for(int idxLeaf = 0 ; idxLeaf < nbLeaf ; ++idxLeaf){
                 int particlesInLeaf = 0;
                 file.read((char*)&particlesInLeaf, sizeof(int));
-                ClassProptotype::GetParticles(&file, particles, particlesInLeaf);
+
+                int sizeOfLeaf = 0;
+                file.read((char*)&sizeOfLeaf, sizeof(int));
+
+                buffer.reserve(sizeOfLeaf);
+                file.read((char*)buffer.data(), sizeOfLeaf);
+
                 for(int idxParticle = 0 ; idxParticle < particlesInLeaf ; ++idxParticle){
-                    tree.insert(particles[idxParticle]);
+                    particle.restore(buffer);
+                    tree.insert(particle);
                 }
             }
-
-            delete[] particles;
         }
 
         // Start from leal level - 1
@@ -270,7 +229,14 @@ public:
                     return false;
                 }
 
-                ClassProptotype::GetCell(&file,octreeIterator.getCurrentCell());
+                int sizeOfCell = 0;
+                file.read((char*)&sizeOfCell, sizeof(int));
+
+                buffer.reserve(sizeOfCell);
+                file.read((char*)buffer.data(), sizeOfCell);
+
+                octreeIterator.getCurrentCell()->restore(buffer);
+
                 --nbCells;
             } while(octreeIterator.moveRight());
 
diff --git a/Src/Kernels/FSphericalBlasKernel.hpp b/Src/Kernels/FSphericalBlasKernel.hpp
index 3a3fa312c..b9f758c31 100644
--- a/Src/Kernels/FSphericalBlasKernel.hpp
+++ b/Src/Kernels/FSphericalBlasKernel.hpp
@@ -183,13 +183,12 @@ public:
         // Get a computable vector
         preExpNExp(temporaryMultiSource);
 
-        FReal alpha_and_beta[2] = {1.0, 0.0};
+        //FReal alpha_and_beta[2] = {1.0, 0.0};
 
-        cblas_gemv<FReal>(CblasColMajor, CblasTrans,
-                          FF_MATRIX_COLUMN_DIM, FF_MATRIX_ROW_DIM,
-                          alpha_and_beta, M2L_Outer_transfer,
-                          FF_MATRIX_COLUMN_DIM, temporaryMultiSource, 1,
-                          alpha_and_beta, local_exp, 1);
+        //CblasTrans
+        FBlas::gemtv(     FF_MATRIX_COLUMN_DIM,FF_MATRIX_ROW_DIM,
+                          FReal(1.0), M2L_Outer_transfer,
+                          temporaryMultiSource, local_exp);
     }
 };
 
diff --git a/Src/Kernels/FSphericalBlockBlasKernel.hpp b/Src/Kernels/FSphericalBlockBlasKernel.hpp
index faa4bdb47..ba68d38fe 100644
--- a/Src/Kernels/FSphericalBlockBlasKernel.hpp
+++ b/Src/Kernels/FSphericalBlockBlasKernel.hpp
@@ -184,13 +184,11 @@ public:
         // Get a computable vector
         preExpNExp(temporaryMultiSource);
 
-        FReal alpha_and_beta[2] = {1.0, 0.0};
+        //FReal alpha_and_beta[2] = {1.0, 0.0};
 
-        cblas_gemv<FReal>(CblasColMajor, CblasTrans,
-                          FF_MATRIX_COLUMN_DIM, FF_MATRIX_ROW_DIM,
-                          alpha_and_beta, M2L_Outer_transfer,
-                          FF_MATRIX_COLUMN_DIM, temporaryMultiSource, 1,
-                          alpha_and_beta, local_exp, 1);
+        FBlas::gemtv(     FF_MATRIX_COLUMN_DIM,FF_MATRIX_ROW_DIM,
+                          FReal(1.0), M2L_Outer_transfer,
+                          temporaryMultiSource, local_exp);
     }
 };
 
diff --git a/Src/Kernels/FSphericalCell.hpp b/Src/Kernels/FSphericalCell.hpp
index 50b5cfc4c..137f06e61 100644
--- a/Src/Kernels/FSphericalCell.hpp
+++ b/Src/Kernels/FSphericalCell.hpp
@@ -12,6 +12,7 @@
 #define FSPHERICALCELL_HPP
 
 
+#include "../Utils/FAbstractSerializable.hpp"
 #include "../Utils/FAbstractSendable.hpp"
 #include "../Utils/FComplexe.hpp"
 #include "../Utils/FMemUtils.hpp"
@@ -104,29 +105,6 @@ public:
     FComplexe* getLocal() {
         return local_exp;
     }
-};
-
-int FSphericalCell::DevP(-1);
-int FSphericalCell::LocalSize(-1);
-int FSphericalCell::PoleSize(-1);
-
-
-/**
-* @author Berenger Bramas (berenger.bramas@inria.fr)
-*/
-class FTypedSphericalCell : public FSphericalCell, public FExtendCellType {
-public:
-};
-
-
-/**
-* @author Berenger Bramas (berenger.bramas@inria.fr)
-*/
-class FSendableSphericalCell : public FSphericalCell , public FAbstractSendable {
-public:
-    static void Init(const int inDevP){
-        FSphericalCell::Init(inDevP);
-    }
 
     ///////////////////////////////////////////////////////
     // to extend FAbstractSendable
@@ -144,9 +122,44 @@ public:
     void deserializeDown(FBufferReader& buffer){
         buffer.fillArray(local_exp, LocalSize);
     }
+
+    ///////////////////////////////////////////////////////
+    // to extend Serializable
+    ///////////////////////////////////////////////////////
+    void save(FBufferWriter& buffer) const{
+        FBasicCell::save(buffer);
+        buffer.write(multipole_exp, PoleSize);
+        buffer.write(multipole_exp, PoleSize);
+    }
+    void restore(FBufferReader& buffer){
+        FBasicCell::restore(buffer);
+        buffer.fillArray(multipole_exp, PoleSize);
+        buffer.fillArray(multipole_exp, PoleSize);
+    }
+};
+
+int FSphericalCell::DevP(-1);
+int FSphericalCell::LocalSize(-1);
+int FSphericalCell::PoleSize(-1);
+
+
+/**
+* @author Berenger Bramas (berenger.bramas@inria.fr)
+*/
+class FTypedSphericalCell : public FSphericalCell, public FExtendCellType {
+public:
+    void save(FBufferWriter& buffer) const{
+        FSphericalCell::save(buffer);
+        FExtendCellType::save(buffer);
+    }
+    void restore(FBufferReader& buffer){
+        FSphericalCell::restore(buffer);
+        FExtendCellType::restore(buffer);
+    }
 };
 
 
+
 #endif //FSPHERICALCELL_HPP
 
 
diff --git a/Src/Kernels/FSphericalParticle.hpp b/Src/Kernels/FSphericalParticle.hpp
index fff653ad1..4f0b58b0a 100644
--- a/Src/Kernels/FSphericalParticle.hpp
+++ b/Src/Kernels/FSphericalParticle.hpp
@@ -16,18 +16,38 @@
 #include "../Extensions/FExtendParticleType.hpp"
 #include "../Components/FFmaParticle.hpp"
 
-#include "../Extensions/FExtendFullySerializable.hpp"
+#include "../Utils/FAbstractSerializable.hpp"
 
 class FSphericalParticle : public FExtendForces, public FFmaParticle, public FExtendPotential {
 public:
-};
 
-class FSendableSphericalParticle : public FExtendFullySerializable<FSendableSphericalParticle>, public FSphericalParticle {
-public:
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        FExtendForces::save(buffer);
+        FFmaParticle::save(buffer);
+        FExtendPotential::save(buffer);
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        FExtendForces::restore(buffer);
+        FFmaParticle::restore(buffer);
+        FExtendPotential::restore(buffer);
+    }
 };
 
+
 class FTypedSphericalParticle : public FSphericalParticle, public FExtendParticleType {
 public:
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        FSphericalParticle::save(buffer);
+        FExtendParticleType::save(buffer);
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        FSphericalParticle::restore(buffer);
+        FExtendParticleType::restore(buffer);
+    }
 };
 
 #endif // FSPHERICALPARTICLE_HPP
diff --git a/Src/Utils/F3DPosition.hpp b/Src/Utils/F3DPosition.hpp
index b876a1b43..8852b0eb1 100644
--- a/Src/Utils/F3DPosition.hpp
+++ b/Src/Utils/F3DPosition.hpp
@@ -15,7 +15,10 @@
 // To get memcpy
 #include <cstring>
 #include <iostream>
+
 #include "FGlobal.hpp"
+#include "../Containers/FBufferReader.hpp"
+#include "../Containers/FBufferWriter.hpp"
 
 /**
 * @author Berenger Bramas (berenger.bramas@inria.fr)
@@ -266,6 +269,15 @@ public:
         output << "(" <<  inPosition.getX() << ", " << inPosition.getY() << ", " << inPosition.getZ() <<")";
         return output;  // for multiple << operators.
     }
+
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        buffer << x << y << z;
+    }
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        buffer >> x >> y >> z;
+    }
 };
 
 
diff --git a/Src/Utils/FAbstractSerializable.hpp b/Src/Utils/FAbstractSerializable.hpp
index 483ee525e..959ccc9c1 100644
--- a/Src/Utils/FAbstractSerializable.hpp
+++ b/Src/Utils/FAbstractSerializable.hpp
@@ -16,9 +16,6 @@ class FBufferWriter;
 */
 class FAbstractSerializable {
 protected:
-    /** Empty Destructor */
-    virtual ~FAbstractSerializable(){}
-
     virtual void save(FBufferWriter&) const  = 0;
     virtual void restore(FBufferReader&) = 0;
 };
diff --git a/Src/Utils/FBlas.hpp b/Src/Utils/FBlas.hpp
index a0ef6af5d..915ddd00a 100644
--- a/Src/Utils/FBlas.hpp
+++ b/Src/Utils/FBlas.hpp
@@ -30,7 +30,7 @@
 #include <mkl_cblas.h>
 #else
 #include <cblas.h>
-#include <clapack.h>
+//#include <clapack.h>
 #endif
 #else
     enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102};
diff --git a/Tests/testFmbAlgorithmProc.cpp b/Tests/testFmbAlgorithmProc.cpp
index f2e8352d6..b8a942c7c 100644
--- a/Tests/testFmbAlgorithmProc.cpp
+++ b/Tests/testFmbAlgorithmProc.cpp
@@ -169,8 +169,8 @@ void ValidateFMMAlgoProc(OctreeClass* const badTree,
 
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FSendableSphericalParticle     ParticleClass;
-    typedef FSendableSphericalCell         CellClass;
+    typedef FSphericalParticle     ParticleClass;
+    typedef FSphericalCell         CellClass;
     typedef FVector<ParticleClass>         ContainerClass;
 
     typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
diff --git a/Tests/testFmmAlgorithmProc.cpp b/Tests/testFmmAlgorithmProc.cpp
index 73033059d..96e5a2810 100644
--- a/Tests/testFmmAlgorithmProc.cpp
+++ b/Tests/testFmmAlgorithmProc.cpp
@@ -283,34 +283,27 @@ void print(OctreeClass* const valideTree){
 /** Fmb class has to extend {FExtendForces,FExtendPotential,FExtendPhysicalValue}
   * Because we use fma loader it needs {FExtendPhysicalValue}
   */
-class TestParticle : public FExtendFullySerializable<TestParticle>, public FTestParticle, public FExtendPhysicalValue {
-};
-
-
-class TestCell : public FTestCell , public FAbstractSendable {
+class TestParticle : public FTestParticle, public FExtendPhysicalValue {
 public:
-
-    void serializeUp(FBufferWriter& buffer) const {
-        buffer << this->dataUp;
+    /** Save current object */
+    void save(FBufferWriter& buffer) const {
+        FTestParticle::save(buffer);
+        FExtendPhysicalValue::save(buffer);
     }
-    void deserializeUp(FBufferReader& buffer){
-        buffer >> this->dataUp;
-    }
-
-    void serializeDown(FBufferWriter& buffer) const {
-        buffer << this->dataDown;
-    }
-    void deserializeDown(FBufferReader& buffer){
-        buffer >> this->dataDown;
+    /** Retrieve current object */
+    void restore(FBufferReader& buffer) {
+        FTestParticle::restore(buffer);
+        FExtendPhysicalValue::restore(buffer);
     }
 };
 
+
 /////////////////////////////////////////////////////////////////////
 // Define the classes to use
 /////////////////////////////////////////////////////////////////////
 
 typedef TestParticle               ParticleClass;
-typedef TestCell                   CellClass;
+typedef FTestCell                  CellClass;
 typedef FVector<ParticleClass>     ContainerClass;
 
 typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
diff --git a/Tests/testTreeIO.cpp b/Tests/testTreeIO.cpp
index 81433e598..62b9bbdfa 100644
--- a/Tests/testTreeIO.cpp
+++ b/Tests/testTreeIO.cpp
@@ -28,10 +28,13 @@
 #include "../Src/Kernels/FSphericalParticle.hpp"
 #include "../Src/Components/FSimpleLeaf.hpp"
 
+
+
+
 // Simply create particles and try the kernels
 int main(int argc, char ** argv){
-    typedef FSphericalParticle             ParticleClass;
-    typedef FSphericalCell                 CellClass;
+    typedef FSerializableSphericalParticle             ParticleClass;
+    typedef FSerializableSphericalCell                 CellClass;
     typedef FVector<ParticleClass>  ContainerClass;
 
     typedef FSimpleLeaf<ParticleClass, ContainerClass >                     LeafClass;
@@ -72,13 +75,13 @@ int main(int argc, char ** argv){
 
     std::cout << "Save tree ..." << std::endl;
 
-    FTreeIO::Save<OctreeClass, CellClass, ParticleClass, FTreeIO::Copier<CellClass, ParticleClass> >("/tmp/tree.data", tree);
+    FTreeIO::Save<OctreeClass, CellClass, ParticleClass >("/tmp/tree.data", tree);
 
     // -----------------------------------------------------
 
     std::cout << "Load tree ..." << std::endl;
 
-    FTreeIO::Load<OctreeClass, CellClass, ParticleClass, FTreeIO::Copier<CellClass, ParticleClass> >("/tmp/tree.data", tree);
+    FTreeIO::Load<OctreeClass, CellClass, ParticleClass >("/tmp/tree.data", tree);
 
     return 0;
 }
-- 
GitLab