Commit abe74a81 authored by COULAUD Olivier's avatar COULAUD Olivier
Browse files

Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/scalfmm/scalfmm

# By bramas
# Via bramas
* 'master' of git+ssh://scm.gforge.inria.fr//gitroot/scalfmm/scalfmm:
  include test file in doc
  move cheb test in kernel
  Put the source into the documentation
  Remove commented line in the changeFormat
  Put the logo in the generated doc
  Update the read me
  Move test parameters file
  Add kernel API C pdf doc
  Update documentation
  Move local parameters into the mains
  update the doc
  just remove some typos in the doc
  Add a system to manage the execs parameters more cleanly
parents 14902d42 14fbc1c4
This diff is collapsed.
......@@ -23,7 +23,7 @@
* <li> Pierre Blanchard </li>
* </ul>
* Old contributors
* Previous contributors
*
* <ul>
* <li> Matthias Messner </li>
......
......@@ -166,4 +166,11 @@ html/files.html
<li> utestOctree.cpp : this tests the octree validation. </li>
</ul>
* \section makeyourown Create your own application using ScalFMM
* In you compile ScalFMM and enabled the Tests (by passing a parameter to CMake or by using ccmake)
* any cpp file that will put into the Tests/ directories will be compiled and linked to ScalFMM.
* Therefore it can be a quick way to create and test with scalfmm without creating your own project and
* thinking about the compilation and link stages.
* Put your file in the test directories, enable the Tests in the cmake, be sure that the CMake is generated (type cmake.. again
* in the build dir), and then make your_cpp_file_without_extension
*/
......@@ -3,8 +3,16 @@
* \section Periodic-1 Periodicity in usual FMM
* Our periodicity is kernel independant but is not a real/usual periodicity.
* We simply repeat the simulation box a high number of times which means that if
* needed the simulation box can be repeated a million times in each direction.
* In order to enable this feature nothing special is needed, any ScalFMM kernel can
* be used with this periodicity.
* Moreover the usual FMM garantees apply here because we are doing nothing more than a FMM.
* Please refer to the Periodic example to know more and test the degree of repetition based on
* the "-per" parameter.
* \subsection limitation
* support only cubic box
* \subsection Limitation
* Our periodic system supports only cubic box for now (it is not possible to choose in wich directions the periodicity
* applies.
*/
......@@ -10,7 +10,7 @@
* <li> Mix capital and normal letter to write names (IAmAStaticName, iAmAName) no underscore (but if you have several variables that looks the same be careful: thisIsAXVariable thisIsAYVariable) </li>
* <li> Put const every where it is possible (method, value, pointer etc.) </li>
* <li> Declare variables usually as late as possible (we are not in old C so do not declare every thing at the beginning of a function). Of course, variable that are used in a loop but with always the same value can be declared at the function beginning. </li>
* <li> Declare index in the for loop where they are used (and their names should start with "idx") </li>
* <li> Declare index inside the for loop where they are used (and their names should start with "idx" if appropriate) </li>
* <li> Use pre-inc if possible (even if the compiler will optimized post-inc for native type) </li>
* <li> If a parameter is changed by a function use pointer else use const ref (if the size of object is less than 20 Bytes you can pass it by value, moreover if it is intensively used!)</li>
* <li> Please do not name variables with one letter (except if it is related to a mathematical formula but then this one should be in the comment in latex format)</li>
......@@ -29,7 +29,7 @@
* First of all, many classes are Templates and so, even if it is possible to split declaration and implementation
* of templates in different files such approach is not supported by all compiler, it then better
* for templates to stay in their hpp.
* For other class the debate is more open.
* For other classes the debate is more open.
* Even if it is not a argument, it is interesting to notice that all modern languages are one file per class (C#, Java, Ruby, Python, ...).
* \subsection cons Cons
......@@ -59,6 +59,6 @@
* In our project we have plenty of templates.
* Our project is not that big and many people arrived to work on it, and for now, all of them finally like to have all in the hpp when they discovered the project.
* It someone wants to know what a class is proposing, then it can do as it is usual, he looks to the doc (who is looking to Qt header to know QVector methods??).
* If someone wants to know what a class is proposing, then he can do as it is usual, he looks to the doc (who looks to Qt header to know QVector methods??).
**/
......@@ -45,6 +45,8 @@
#include "Core/FFmmAlgorithm.hpp"
#endif
#include "../Src/Utils/FParameterNames.hpp"
/**
* This program runs the FMM Algorithm with the Chebyshev kernel and compares the results with a direct computation.
*/
......@@ -54,40 +56,25 @@
//! \authors B. Bramas, O. Coulaud
//!
//! This code is a short example to use the Chebyshev Interpolation approach for the 1/r kernel
//!
//!@Algorithm
//! <b> General arguments:</b>
//! \param -help(-h) to see the parameters available in this driver
//! \param -depth The depth of the octree
//! \param -subdepth Specifies the size of the sub octree
//! \param -t The number of threads
//!
//! \param -f name Name of the particles file with extension (.fma or .bfma). The data in file have to be in our FMA format
//!
//
void usage() {
std::cout << "Driver for Chebyshev interpolation kernel (1/r kernel)" << std::endl;
std::cout << "Options "<< std::endl
<< " -help to see the parameters " << std::endl
<< " -depth the depth of the octree "<< std::endl
<< " -subdepth specifies the size of the sub octree " << std::endl
<< " -f name name specifies the name of the particle distribution" << std::endl
<< " -t n specifies the number of threads used in the computations" << std::endl;
}
// Simply create particles and try the kernels
int main(int argc, char* argv[])
{
FHelpDescribeAndExit(argc, argv,
"Driver for Chebyshev interpolation kernel (1/r kernel).",
FParameterDefinitions::InputFile, FParameterDefinitions::OctreeHeight,
FParameterDefinitions::OctreeSubHeight, FParameterDefinitions::InputFile,
FParameterDefinitions::NbThreads);
const std::string defaultFile(/*SCALFMMDataPath+*/"../Data/test20k.fma" );
const std::string filename = FParameters::getStr(argc,argv,"-f", defaultFile.c_str());
const unsigned int TreeHeight = FParameters::getValue(argc, argv, "-depth", 5);
const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, "-subdepth", 2);
const unsigned int NbThreads = FParameters::getValue(argc, argv, "-t", 1);
if(FParameters::existParameter(argc, argv, "-h")||FParameters::existParameter(argc, argv, "-help")){
usage() ;
exit(EXIT_SUCCESS);
}
const std::string filename = FParameters::getStr(argc,argv,FParameterDefinitions::InputFile.options, defaultFile.c_str());
const unsigned int TreeHeight = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 5);
const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeSubHeight.options, 2);
const unsigned int NbThreads = FParameters::getValue(argc, argv, FParameterDefinitions::NbThreads.options, 1);
#ifdef _OPENMP
omp_set_num_threads(NbThreads);
std::cout << "\n>> Using " << omp_get_max_threads() << " threads.\n" << std::endl;
......
......@@ -44,6 +44,7 @@
#include "../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "../Src/Utils/FParameters.hpp"
#include "../Src/Utils/FParameterNames.hpp"
/// \file ChebyshevInterpolationMPIFMM
......@@ -52,41 +53,25 @@
//! \authors B. Bramas, O. Coulaud
//!
//! This code is a short example to use the FMM Algorithm Proc with Chebyshev Interpolation for the 1/r kernel
//!
//!
//! <b> General arguments:</b>
//! \param -help(-h) to see the parameters available in this driver
//! \param -depth The depth of the octree
//! \param -subdepth Specifies the size of the sub octree
//! \param -t The number of threads
//!
//! \param -f name Name of the particles file with extension (.fma or .bfma). The data in file have to be in our FMA format
//!
//
void usage() {
std::cout << "Driver for Chebyshev Interpolation kernel using MPI (1/r kernel)" << std::endl;
std::cout << "Options "<< std::endl
<< " -help to see the parameters " << std::endl
<< " -depth the depth of the octree "<< std::endl
<< " -subdepth specifies the size of the sub octree " << std::endl
<< " -f name name specifies the name of the particle distribution" << std::endl
<< " -t n specifies the number of threads used in the computations" << std::endl
<< " CMD >> mpirun -np nb_proc_needed ./ChebyshevInterpolationAlgorithm ....." << std::endl;
}
// Simply create particles and try the kernels
int main(int argc, char* argv[])
{
FHelpDescribeAndExit(argc, argv,
"Driver for Chebyshev Interpolation kernel using MPI (1/r kernel). "
"Usully run using : mpirun -np nb_proc_needed ./ChebyshevInterpolationAlgorithm [params].",
FParameterDefinitions::InputFile, FParameterDefinitions::OctreeHeight,
FParameterDefinitions::OctreeSubHeight, FParameterDefinitions::InputFile,
FParameterDefinitions::NbThreads);
const std::string defaultFile(/*SCALFMMDataPath+*/"../Data/test20k.fma");
const std::string filename = FParameters::getStr(argc,argv,"-f", defaultFile.c_str());
const unsigned int TreeHeight = FParameters::getValue(argc, argv, "-depth", 5);
const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, "-subdepth", 2);
const unsigned int NbThreads = FParameters::getValue(argc, argv, "-t", 1);
if(FParameters::existParameter(argc, argv, "-h")||FParameters::existParameter(argc, argv, "-help")){
usage() ;
exit(-1);
}
const std::string filename = FParameters::getStr(argc,argv,FParameterDefinitions::InputFile.options, defaultFile.c_str());
const unsigned int TreeHeight = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 5);
const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeSubHeight.options, 2);
const unsigned int NbThreads = FParameters::getValue(argc, argv, FParameterDefinitions::NbThreads.options, 1);
#ifdef _OPENMP
omp_set_num_threads(NbThreads);
std::cout << "\n>> Using " << omp_get_max_threads() << " threads.\n" << std::endl;
......
......@@ -31,7 +31,7 @@
#include "Kernels/P2P/FP2P.hpp"
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "../Src/Utils/FParameterNames.hpp"
//
/// \file DirectComputation.cpp
//!
......@@ -49,26 +49,20 @@
// Simply create particles and try the kernels
int main(int argc, char ** argv){
//
///////////////////////What we do/////////////////////////////
if( FParameters::existParameter(argc, argv, "-help" ) || argc < 4){
std::cout << ">> This executable has to be used to compute interaction either for periodic or non periodic system.\n";
std::cout << ">> Example -fin filenameIN.{fma or bfma) -fout filenameOUT{fma or bfma) \n";
std::cout << ">> Default input file : ../Data/unitCubeXYZQ20k.fma\n";
std::cout << " Options " << std::endl;
std::cout << " -verbose : print index x y z Q V fx fy fz " << std::endl;
std::cout << " -fin filename. Extension specifies if the file is binary or not. " << std::endl;
std::cout << " Only our FMA (.bma, .bfma) is allowed " << std::endl;
std::cout << " -fout filenameOUT output file with extension (default output.bfma)" << std::endl;
exit(-1);
}
FHelpDescribeAndExit(argc, argv,
">> This executable has to be used to compute interaction either for periodic or non periodic system.\n"
">> Example -fin filenameIN.{fma or bfma) -fout filenameOUT{fma or bfma) \n"
">> Default input file : ../Data/unitCubeXYZQ20k.fma\n"
">> Only our FMA (.bma, .bfma) is allowed as input.\n"
">> Output file with extension (default output.bfma).",
FParameterDefinitions::InputFile, FParameterDefinitions::OutputFile,
FParameterDefinitions::EnabledVerbose);
//////////////////////////////////////////////////////////////
const std::string defaultFile(/*SCALFMMDataPath+*/"../Data/unitCubeXYZQ20k.fma");
const std::string filenameIn(FParameters::getStr(argc,argv,"-fin", defaultFile.c_str()));
const std::string filenameOut(FParameters::getStr(argc,argv,"-fout", "output.bfma"));
const std::string filenameIn(FParameters::getStr(argc,argv,FParameterDefinitions::InputFile.options, defaultFile.c_str()));
const std::string filenameOut(FParameters::getStr(argc,argv,FParameterDefinitions::OutputFile.options, "output.bfma"));
//
FTic counter;
......@@ -187,7 +181,7 @@ int main(int argc, char ** argv){
// end generate
// -----------------------------------------------------
//
if(FParameters::existParameter(argc, argv, "-verbose")){
if(FParameters::existParameter(argc, argv, FParameterDefinitions::EnabledVerbose.options)){
denergy = 0 ;
for(int idx = 0 ; idx < nbParticles ; ++idx){
std::cout << ">> index " << idx << std::endl;
......
......@@ -43,6 +43,8 @@
#include "Core/FFmmAlgorithm.hpp"
#endif
#include "../Src/Utils/FParameterNames.hpp"
/// \file RotationFMM.cpp
//!
//! \brief This program runs the FMM Algorithm with harmonic spherical approximation of 1/r kernel
......@@ -61,28 +63,22 @@
//!
//
void usage() {
std::cout << "Driver for HArmonic Spherical + Rotation -- kernel (1/r kernel)" << std::endl;
std::cout << "Options "<< std::endl
<< " -help to see the parameters " << std::endl
<< " -depth the depth of the octree "<< std::endl
<< " -subdepth specifies the size of the sub octree " << std::endl
<< " -f name name specifies the name of the particle distribution. If extension is . bfma th file is -in binary mode" << std::endl
<< " -t n specifies the number of threads used in the computations" << std::endl;
}
// Simply create particles and try the kernels
int main(int argc, char* argv[])
{
FHelpDescribeAndExit(argc, argv,
"Driver for HArmonic Spherical + Rotation -- kernel (1/r kernel).",
FParameterDefinitions::InputFile, FParameterDefinitions::OctreeHeight,
FParameterDefinitions::OctreeSubHeight, FParameterDefinitions::InputFile,
FParameterDefinitions::NbThreads);
const std::string defaultFile(/*SCALFMMDataPath+*/"../Data/test20k.fma");
const std::string filename(FParameters::getStr(argc,argv,"-f", defaultFile.c_str()));
const unsigned int TreeHeight = FParameters::getValue(argc, argv, "-depth", 5);
const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, "-subdepth", 2);
const unsigned int NbThreads = FParameters::getValue(argc, argv, "-t", 1);
if(FParameters::existParameter(argc, argv, "-h")||FParameters::existParameter(argc, argv, "-help")){
usage() ;
exit(-1);
}
const std::string filename(FParameters::getStr(argc,argv,FParameterDefinitions::InputFile.options, defaultFile.c_str()));
const unsigned int TreeHeight = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 5);
const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeSubHeight.options, 2);
const unsigned int NbThreads = FParameters::getValue(argc, argv, FParameterDefinitions::NbThreads.options, 1);
#ifdef _OPENMP
omp_set_num_threads(NbThreads) ;
std::cout << "\n>> Using " << omp_get_max_threads() << " threads.\n" << std::endl;
......
......@@ -43,6 +43,7 @@
#include "../../Src/Utils/FParameters.hpp"
#include "../Src/Utils/FParameterNames.hpp"
/// \file RotationFMMProc.cpp
//!
......@@ -62,186 +63,182 @@
//!
//
void usage() {
std::cout << "Driver for Rotation Spherical kernel using MPI (1/r kernel)" << std::endl;
std::cout << "Options "<< std::endl
<< " -help to see the parameters " << std::endl
<< " -depth the depth of the octree "<< std::endl
<< " -subdepth specifies the size of the sub octree " << std::endl
<< " -f name name specifies the name of the particle distribution" << std::endl
<< " -t n specifies the number of threads used in the computations" << std::endl
<< " CMD >> mpirun -np nb_proc_needed ./RotationFMMProc ....." << std::endl;
}
// Simply create particles and try the kernels
int main(int argc, char* argv[])
{
const std::string defaultFile(/*SCALFMMDataPath+*/"../Data/test20k.fma");
const std::string filename = FParameters::getStr(argc,argv,"-f", defaultFile.c_str());
const unsigned int TreeHeight = FParameters::getValue(argc, argv, "-depth", 5);
const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, "-subdepth", 2);
const unsigned int NbThreads = FParameters::getValue(argc, argv, "-t", 1);
if(FParameters::existParameter(argc, argv, "-h")||FParameters::existParameter(argc, argv, "-help")){
usage() ;
exit(-1);
}
FHelpDescribeAndExit(argc, argv,
"Driver for Rotation Spherical kernel using MPI (1/r kernel).\n"
"CMD >> mpirun -np nb_proc_needed ./RotationFMMProc [params]",
FParameterDefinitions::InputFile, FParameterDefinitions::OctreeHeight,
FParameterDefinitions::OctreeSubHeight, FParameterDefinitions::InputFile,
FParameterDefinitions::NbThreads);
const std::string defaultFile(/*SCALFMMDataPath+*/"../Data/test20k.fma");
const std::string filename = FParameters::getStr(argc,argv,FParameterDefinitions::InputFile.options, defaultFile.c_str());
const unsigned int TreeHeight = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 5);
const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeSubHeight.options, 2);
const unsigned int NbThreads = FParameters::getValue(argc, argv, FParameterDefinitions::NbThreads.options, 1);
#ifdef _OPENMP
omp_set_num_threads(NbThreads);
std::cout << "\n>> Using " << omp_get_max_threads() << " threads.\n" << std::endl;
omp_set_num_threads(NbThreads);
std::cout << "\n>> Using " << omp_get_max_threads() << " threads.\n" << std::endl;
#else
std::cout << "\n>> Sequential version.\n" << std::endl;
std::cout << "\n>> Sequential version.\n" << std::endl;
#endif
//
std::cout << "Parameters "<< std::endl
<< " Octree Depth "<< TreeHeight <<std::endl
<< " SubOctree depth "<< SubTreeHeight <<std::endl
<< " Input file name: " <<filename <<std::endl
<< " Thread number: " << NbThreads <<std::endl
<<std::endl;
//init values for MPI
FMpi app(argc,argv);
//
// init timer
FTic time;
FMpiFmaGenericLoader* loader = new FMpiFmaGenericLoader(filename,app.global());
if(!loader->isOpen()) throw std::runtime_error("Particle file couldn't be opened!") ;
////////////////////////////////////////////////////////////////////
// begin spherical kernel
// accuracy
const unsigned int P = 22;
// typedefs
typedef FP2PParticleContainerIndexed<> ContainerClass;
typedef FSimpleLeaf< ContainerClass > LeafClass;
typedef FRotationCell<P> CellClass;
typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
//
typedef FRotationKernel< CellClass, ContainerClass , P> KernelClass;
//
typedef FFmmAlgorithmThreadProc<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClassProc;
// init oct-tree
OctreeClass tree(TreeHeight, SubTreeHeight, loader->getBoxWidth(), loader->getCenterOfBox());
{ // -----------------------------------------------------
if(app.global().processId() == 0){
std::cout << "Creating & Inserting " << loader->getNumberOfParticles()
<< " particles ..." << std::endl;
std::cout << "\tHeight : " << TreeHeight << " \t sub-height : " << SubTreeHeight << std::endl;
}
time.tic();
//
struct TestParticle{
int indexInFile;
FPoint position;
FReal physicalValue;
const FPoint& getPosition(){
return position;
}
};
TestParticle* particles = new TestParticle[loader->getMyNumberOfParticles()];
memset(particles, 0, (unsigned int) (sizeof(TestParticle) * loader->getMyNumberOfParticles()));
//idx (in file) of the first part that will be used by this proc.
int idxStart = loader->getStart();
for(int idxPart = 0 ; idxPart < loader->getMyNumberOfParticles() ; ++idxPart){
//Storage of the index (in the original file) of each part.
particles[idxPart].indexInFile = idxPart + idxStart;
// Read particles from file
loader->fillParticle(&particles[idxPart].position,&particles[idxPart].physicalValue);
}
FVector<TestParticle> finalParticles;
FLeafBalance balancer;
FMpiTreeBuilder< TestParticle >::DistributeArrayToContainer(app.global(), particles, loader->getMyNumberOfParticles(),
tree.getBoxCenter(),
tree.getBoxWidth(),
tree.getHeight(), &finalParticles,&balancer);
for(int idx = 0 ; idx < finalParticles.getSize(); ++idx){
tree.insert(finalParticles[idx].position,finalParticles[idx].indexInFile,finalParticles[idx].physicalValue);
}
delete[] particles;
time.tac();
std::cout << "Done " << "(@Creating and Inserting Particles = "
<< time.elapsed() << "s)." << std::endl;
} // -----------------------------------------------------
{ // -----------------------------------------------------
std::cout << "\nRotation harmonic Spherical FMM Proc (P="<< P << ") ... " << std::endl;
time.tic();
//
// Here we use a pointer due to the limited size of the stack
std::cout << "Parameters "<< std::endl
<< " Octree Depth "<< TreeHeight <<std::endl
<< " SubOctree depth "<< SubTreeHeight <<std::endl
<< " Input file name: " <<filename <<std::endl
<< " Thread number: " << NbThreads <<std::endl
<<std::endl;
//init values for MPI
FMpi app(argc,argv);
//
KernelClass *kernels = new KernelClass(TreeHeight, loader->getBoxWidth(), loader->getCenterOfBox());
// init timer
FTic time;
FMpiFmaGenericLoader* loader = new FMpiFmaGenericLoader(filename,app.global());
if(!loader->isOpen()) throw std::runtime_error("Particle file couldn't be opened!") ;
////////////////////////////////////////////////////////////////////
// begin spherical kernel
// accuracy
const unsigned int P = 22;
// typedefs
typedef FP2PParticleContainerIndexed<> ContainerClass;
typedef FSimpleLeaf< ContainerClass > LeafClass;
typedef FRotationCell<P> CellClass;
typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
//
FmmClassProc algorithm(app.global(),&tree, kernels);
typedef FRotationKernel< CellClass, ContainerClass , P> KernelClass;
//
algorithm.execute(); // Here the call of the FMM algorithm
typedef FFmmAlgorithmThreadProc<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClassProc;
// init oct-tree
OctreeClass tree(TreeHeight, SubTreeHeight, loader->getBoxWidth(), loader->getCenterOfBox());
{ // -----------------------------------------------------
if(app.global().processId() == 0){
std::cout << "Creating & Inserting " << loader->getNumberOfParticles()
<< " particles ..." << std::endl;
std::cout << "\tHeight : " << TreeHeight << " \t sub-height : " << SubTreeHeight << std::endl;
}
time.tic();
//
struct TestParticle{
int indexInFile;
FPoint position;
FReal physicalValue;
const FPoint& getPosition(){
return position;
}
};
TestParticle* particles = new TestParticle[loader->getMyNumberOfParticles()];
memset(particles, 0, (unsigned int) (sizeof(TestParticle) * loader->getMyNumberOfParticles()));
//idx (in file) of the first part that will be used by this proc.
int idxStart = loader->getStart();
for(int idxPart = 0 ; idxPart < loader->getMyNumberOfParticles() ; ++idxPart){
//Storage of the index (in the original file) of each part.
particles[idxPart].indexInFile = idxPart + idxStart;
// Read particles from file
loader->fillParticle(&particles[idxPart].position,&particles[idxPart].physicalValue);
}
FVector<TestParticle> finalParticles;
FLeafBalance balancer;
FMpiTreeBuilder< TestParticle >::DistributeArrayToContainer(app.global(), particles, loader->getMyNumberOfParticles(),
tree.getBoxCenter(),
tree.getBoxWidth(),
tree.getHeight(), &finalParticles,&balancer);
for(int idx = 0 ; idx < finalParticles.getSize(); ++idx){
tree.insert(finalParticles[idx].position,finalParticles[idx].indexInFile,finalParticles[idx].physicalValue);
}
delete[] particles;
time.tac();
std::cout << "Done " << "(@Creating and Inserting Particles = "
<< time.elapsed() << "s)." << std::endl;
} // -----------------------------------------------------
{ // -----------------------------------------------------
std::cout << "\nRotation harmonic Spherical FMM Proc (P="<< P << ") ... " << std::endl;
time.tic();
//
// Here we use a pointer due to the limited size of the stack
//
KernelClass *kernels = new KernelClass(TreeHeight, loader->getBoxWidth(), loader->getCenterOfBox());
//
FmmClassProc algorithm(app.global(),&tree, kernels);
//
algorithm.execute(); // Here the call of the FMM algorithm
//
time.tac();
std::cout << "Done " << "(@Algorithm = " << time.elapsed() << "s)." << std::endl;
}
// -----------------------------------------------------
//
time.tac();
std::cout << "Done " << "(@Algorithm = " << time.elapsed() << "s)." << std::endl;
}
// -----------------------------------------------------
//
// Some output
//
//
{ // -----------------------------------------------------
long int N1=0, N2= loader->getNumberOfParticles()/2, N3= (loader->getNumberOfParticles()-1); ;
FReal energy =0.0 ;
// Some output
//
// Loop over all leaves
//
std::cout <<std::endl<<" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& "<<std::endl;
std::cout << std::scientific;
std::cout.precision(10) ;
tree.forEachLeaf([&](LeafClass* leaf){
const FReal*const posX = leaf->getTargets()->getPositions()[0];
const FReal*const posY = leaf->getTargets()->getPositions()[1];
const FReal*const posZ = leaf->getTargets()->getPositions()[2];
const FReal*const potentials = leaf->getTargets()->getPotentials();
const FReal*const forcesX = leaf->getTargets()->getForcesX();
const FReal*const forcesY = leaf->getTargets()->getForcesY();
const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
const FReal*const physicalValues = leaf->getTargets()->getPhysicalValues();
const FVector<int>&