From dd7d91e743b63e1007da003169ef9f98d0a237b4 Mon Sep 17 00:00:00 2001
From: Quentin Khan <quentin.khan@inria.fr>
Date: Wed, 18 Mar 2015 15:36:06 +0100
Subject: [PATCH] reorganized loadFMAAndRunFMM

---
 Examples/loadFMAAndRunFMM.cpp      | 116 +++++++++++++----------------
 Examples/loadFMAAndRunFMMArgs.hpp  |  22 ++++--
 Examples/loadFMAAndRunFMMUtils.hpp |  60 +++++++++++++++
 3 files changed, 127 insertions(+), 71 deletions(-)
 create mode 100644 Examples/loadFMAAndRunFMMUtils.hpp

diff --git a/Examples/loadFMAAndRunFMM.cpp b/Examples/loadFMAAndRunFMM.cpp
index b1c1ab02c..8c9d4ce81 100644
--- a/Examples/loadFMAAndRunFMM.cpp
+++ b/Examples/loadFMAAndRunFMM.cpp
@@ -1,37 +1,60 @@
+// ===================================================================================
+// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
+// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
+// This software is a computer program whose purpose is to compute the FMM.
+//
+// This software is governed by the CeCILL-C and LGPL licenses and
+// abiding by the rules of distribution of free software.  
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public and CeCILL-C Licenses for more details.
+// "http://www.cecill.info". 
+// "http://www.gnu.org/licenses".
+// ===================================================================================
+
 #include <fstream>
 #include <memory>
 #include <string>
-#include <sys/ioctl.h>
 
-#include "Utils/FMath.hpp"
-#include "Utils/FParameters.hpp"
-#include "Utils/FParameterNames.hpp"
+
+//#include "Utils/FMath.hpp"
+//#include "Utils/FParameters.hpp"
+//#include "Utils/FParameterNames.hpp"
 #include "Files/FFmaGenericLoader.hpp"
 #include "Core/FFmmAlgorithm.hpp"
+#include "Kernels/Chebyshev/FChebSymKernel.hpp"
 
 #include "Containers/FOctree.hpp"
 #include "Components/FBasicCell.hpp"
 #include "Components/FSimpleLeaf.hpp"
 #include "Components/FBasicParticleContainer.hpp"
-#include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"
 
-#include "FChebBalanceSymKernel.hpp"
 #include "loadFMAAndRunFMMArgs.hpp"
+#include "loadFMAAndRunFMMUtils.hpp"
+#include "FChebBalanceSymKernel.hpp"
 #include "CostZones.hpp"
 
-typedef FCostCell                                       CellClass;
-typedef FBasicParticleContainer<0>                      ContainerClass;
-typedef FSimpleLeaf< ContainerClass >                   LeafClass;
-typedef FOctree< CellClass, ContainerClass, LeafClass > OctreeClass;
-typedef FInterpMatrixKernelR                            MatrixKernelClass;
-typedef FChebBalanceSymKernel<CellClass, 
-                              ContainerClass, 
-                              MatrixKernelClass,
-                              5,
-                              OctreeClass>              KernelClass;
+using CellClass         = FCostCell;
+using ContainerClass    = FBasicParticleContainer<0>;
+using LeafClass         = FSimpleLeaf< ContainerClass >;
+using OctreeClass       = FOctree< CellClass, ContainerClass, LeafClass >;
+using MatrixKernelClass = FInterpMatrixKernelR;
+using BalanceKernelClass= FChebBalanceSymKernel<CellClass, ContainerClass,
+                                                MatrixKernelClass, 5,
+                                                OctreeClass>;
+// using KernelClass       = FChebSymKernel<CellClass, ContainerClass,
+//                                          MatrixKernelClass, 5,
+//                                          OctreeClass>;
+
+template < template <typename...> class T>
+using AlgoClass = T <OctreeClass, CellClass, ContainerClass, BalanceKernelClass, LeafClass >;
+
 
 const FReal epsilon = 1e-4;
 
+
 int main(int argc, char** argv)
 {
     loadFMAAndRunFMMArgs args(argc, argv);
@@ -42,62 +65,25 @@ int main(int argc, char** argv)
                      loader.getBoxWidth(),
                      loader.getCenterOfBox());
 
-    FReal  physicalValue;
-    FPoint particlePosition;
-    // insertion
-    for ( int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart ) {
-        loader.fillParticle(&particlePosition, &physicalValue);
-        tree.insert(particlePosition);
-    }
-    
-    KernelClass kernel(&tree, epsilon);
-    FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass >
-        algo(&tree, &kernel);
+    loadTree(tree, loader);
+   
+    BalanceKernelClass kernel(&tree, epsilon);
+    AlgoClass<FFmmAlgorithm> costAlgo(&tree, &kernel);
 
-    algo.execute();
+    costAlgo.execute();
 
-    kernel.printResults(std::cout);
-
-    OctreeClass::Iterator it(&tree);
+    if (args.verboseLevel() > 1) {
+        kernel.printResults(std::cout);
+    }
 
     CostZones<OctreeClass, CellClass> costzones(&tree, args.zoneCount());
     costzones.run();
 
-    // GCC versions before 5.0 have not implemented move constructors to streams
-    std::vector<std::unique_ptr<std::ofstream>> outfiles;
-    for ( int zoneIdx = 0; zoneIdx < args.treeHeight(); zoneIdx++ ) {
-        std::unique_ptr<std::ofstream> out(
-            new std::ofstream( args.outFileName()
-                               + "_" + std::to_string(args.zoneCount()) + "z" 
-                               + "." + std::to_string(zoneIdx)
-                               + args.outFileExt()));
-        *out << "x,y,z,zone" << std::endl;
-        outfiles.push_back(std::move(out));
-    }
+    writeZones(args, costzones);
+    
+//    AlgoClass<FFmmAlgorithmThreadBalanced> fmmAlgo();
+    
     
-    auto zones = costzones.getZones();
-    int zoneIdx = 0;
-    for ( auto zone : zones) {
-        for ( auto cell : zone) {
-            *(outfiles[cell.first]) << cell.second->getCoordinate().getX() << ",";
-            *(outfiles[cell.first]) << cell.second->getCoordinate().getY() << ",";
-            *(outfiles[cell.first]) << cell.second->getCoordinate().getZ() << ",";
-            *(outfiles[cell.first]) << zoneIdx << "," << cell.first << std::endl;
-        }
-        zoneIdx++;
-    }
-
-    auto& zonebounds = costzones.getZoneBounds();
-    zoneIdx = 0;
-    for ( auto zone : zonebounds ) {
-        std::cout << std::endl << "Zone " << zoneIdx << std::endl;
-        int level = 0;
-        for ( auto levelbounds : zone ) {
-            std::cout << "Level" << level << " : [" << levelbounds.first << ":" << levelbounds.second << "]\n";
-            level++;
-        }
-        zoneIdx++;
-    }
 
     return EXIT_SUCCESS;
 }
diff --git a/Examples/loadFMAAndRunFMMArgs.hpp b/Examples/loadFMAAndRunFMMArgs.hpp
index 9019e663e..4d7f2d0d2 100644
--- a/Examples/loadFMAAndRunFMMArgs.hpp
+++ b/Examples/loadFMAAndRunFMMArgs.hpp
@@ -1,6 +1,8 @@
 #ifndef _LOADFMAANDRUNFMMARGS_HPP_
 #define _LOADFMAANDRUNFMMARGS_HPP_
 
+#include <sys/ioctl.h>
+
 #include "tclap/CmdLine.h"
 #include "tclap/LinuxOutput.hpp"
 #include "tclap/CompletionVisitor.h"
@@ -11,6 +13,7 @@ class loadFMAAndRunFMMArgs {
     const int _treeHeightInit = 5;
     const int _subTreeHeightInit = 1;
     const int _zoneCountInit = 4;
+    const int _verboseInit = 0;
     const std::string _inFileNameInit = "";
     const std::string _outFileNameInit = "balancetest";
     const std::string _outFileNameExtInit = "csv";
@@ -28,6 +31,12 @@ class loadFMAAndRunFMMArgs {
             "Show completion arguments",
             _cmd, false, &_compVistor};
 
+    TCLAP::MultiSwitchArg
+    _verboseArg { "v",
+            "verbose",
+            "Activate verbosity",
+            _cmd, _verboseInit};
+    
 
     TCLAP::ValueArg <int>
     _subTreeHeight { "", vs{"subtree-height", "sth"},
@@ -60,12 +69,13 @@ class loadFMAAndRunFMMArgs {
             "Input file name.", true, _inFileNameInit, "filename", _cmd};
     
 public:
-    int treeHeight()    {return _treeHeight.getValue();}
-    int subTreeHeight() {return _subTreeHeight.getValue();}
-    int zoneCount() {return _zoneCount.getValue();}
-    std::string inFileName() {return _inFileName.getValue();} 
-    std::string outFileName() {return _outFileName.getValue();} 
-    std::string outFileExt() {
+    int treeHeight()    const {return _treeHeight.getValue();}
+    int subTreeHeight() const {return _subTreeHeight.getValue();}
+    int zoneCount()     const {return _zoneCount.getValue();}
+    int verboseLevel()  const {return _verboseArg.getValue();}
+    const std::string& inFileName()  const {return _inFileName.getValue();} 
+    const std::string& outFileName() const {return _outFileName.getValue();} 
+    std::string outFileExt() const {
         std::string ext = _outFileExt.getValue();
         if ( ext.at(0) != '.' )
             return '.' + ext;
diff --git a/Examples/loadFMAAndRunFMMUtils.hpp b/Examples/loadFMAAndRunFMMUtils.hpp
new file mode 100644
index 000000000..2c22b1a55
--- /dev/null
+++ b/Examples/loadFMAAndRunFMMUtils.hpp
@@ -0,0 +1,60 @@
+#ifndef _LOADFMAANDRUNFMMUTILS_HPP_
+#define _LOADFMAANDRUNFMMUTILS_HPP_
+
+#include "CostZones.hpp"
+
+template<class OctreeClass, class CellClass>
+void writeZones(const loadFMAAndRunFMMArgs& args, const CostZones <OctreeClass,CellClass>& costzones)
+{
+    // GCC versions before 5.0 have not implemented move constructors to streams
+    std::vector<std::unique_ptr<std::ofstream>> outfiles;
+    for ( int zoneIdx = 0; zoneIdx < args.treeHeight(); zoneIdx++ ) {
+        std::unique_ptr<std::ofstream> out(
+            new std::ofstream( args.outFileName()
+                               + "_" + std::to_string(args.zoneCount()) + "z" 
+                               + "." + std::to_string(zoneIdx)
+                               + args.outFileExt()));
+        *out << "x,y,z,zone" << std::endl;
+        outfiles.push_back(std::move(out));
+    }
+    
+    auto zones = costzones.getZones();
+    int zoneIdx = 0;
+    for ( auto zone : zones) {
+        for ( auto cell : zone) {
+            *(outfiles[cell.first]) << cell.second->getCoordinate().getX() << ",";
+            *(outfiles[cell.first]) << cell.second->getCoordinate().getY() << ",";
+            *(outfiles[cell.first]) << cell.second->getCoordinate().getZ() << ",";
+            *(outfiles[cell.first]) << zoneIdx << "," << cell.first << std::endl;
+        }
+        zoneIdx++;
+    }
+
+    if ( args.verboseLevel() > 0) {        
+        auto& zonebounds = costzones.getZoneBounds();
+        zoneIdx = 0;
+        for ( auto zone : zonebounds ) {
+            std::cout << std::endl << "Zone " << zoneIdx << std::endl;
+            int level = 0;
+            for ( auto levelbounds : zone ) {
+                std::cout << "Level" << level << " : [" << levelbounds.first << ":" << levelbounds.second << "]\n";
+                level++;
+            }
+            zoneIdx++;
+        }
+    }
+}
+
+template <class OctreeClass>
+void loadTree(OctreeClass& tree, FFmaGenericLoader& loader)
+{
+    FReal  physicalValue;
+    FPoint particlePosition;
+    // insertion
+    for ( int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart ) {
+        loader.fillParticle(&particlePosition, &physicalValue);
+        tree.insert(particlePosition);
+    }
+}
+
+#endif
-- 
GitLab