Commit 707a196a authored by COULAUD Olivier's avatar COULAUD Olivier

Improvements

parent 550b03cd
8 4
20000
0.5 0.5 0.5 0.5
0.840188 0.394383 0.783099 0.01
......@@ -19999,4 +20000,4 @@
0.231414 0.84072 0.612182 0.01
0.779025 0.297831 0.261955 0.01
0.800173 0.19078 0.63721 0.01
0.0661965 0.492443 0.801716 0.01
\ No newline at end of file
0.0661965 0.492443 0.801716 0.01
......@@ -37,7 +37,7 @@
\endcode
* \subsection concrete A Concrete example : SH FMM
* \subsection concrete A Concrete example : Spherical Harmonics FMM
* In this part we will run a simulation with Spherical Harmonics and rotation optimization:
* ./Examples/Release/RotationFMM .
......@@ -47,32 +47,32 @@
In the test file we can read:
\code{.cpp}
* const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.fma");
* FFmaLoader<ParticleClass> loader(filename);
* std::string filename = FParameters::getStr(argc, argv,"-fin", "../Data/test20k.fma");
* FFmaGenericLoader loader(filename);
\endcode
* It means, that the test file is reading FMA file (with FFmaLoader)
* It means, that the test file is reading FMA file (see <a href="class_f_fma_generic_loader.html#details">FMA format</a>)
* which can be changed but here we still use this format. We can pass a
* file in parameter with the -f command. So let first create a 2.000.000
* particles file in the FMA test format:
* file in parameter with the -fin option. So let first create with <a href=generate_distributions_8cpp.html> generateDistributions</a> 2.000.000
* particles in a unit cube and store the particle in a file with the FMA format:
\code{.cpp}
* ./Tests/Release/testLoaderFMACreate -nb 2000000 -f my2kkpartfile.fma
* ./Exemple/Release/generateDistributions -N 2000000 -unitcube -filename my2kkpartfile.fma
\endcode
Which create a file called my2kkpartfile.fma.
* \subsubsection running Running the Simulation
* With the SH kernel we can choose the P=4 accuracy parameter for this
* kernel.
* With the Spherical harmonic expansion kernel we can choose the P=4 accuracy parameter for this
* kernel. RotationFMM
\code{.cpp}
* ./Examples/Release/RotationFMM -f my2kkpartfile.fma -depth 5 -subdepth 3
\endcode
* \section driver Driver
* \section driver Drivers
* <a href="../html/files.html"> Here</a> some drivers.
*
html/files.html
......@@ -86,7 +86,6 @@ html/files.html
<li> testBlas.cpp : this file tests the blas, it simply validate that the link was OK </li>
<li> testLoaderFMABinCreate.cpp : this file creates a particles file in binary in the FMA format. </li>
<li> testChebBinaryM2L.cpp : </li>
<li> testLoaderFMABinCreateSphere.cpp : this file creates particles file in binary and FMA format with a spherical distribution. </li>
<li> testChebBinarySymM2L.cpp </li>
<li> testLoaderFMA.cpp : this file illustrates how to load particles from a FMA file. </li>
<li> testChebInterpolator.cpp : </li>
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas
// 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".
// ===================================================================================
// ==== CMAKE =====
// @FUSE_BLAS
// ================
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include "ScalFmmConfig.h"
#include "Files/FFmaGenericLoader.hpp"
#include "Kernels/Chebyshev/FChebCell.hpp"
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "Kernels/Chebyshev/FChebSymKernel.hpp"
#include "Components/FSimpleLeaf.hpp"
#include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "Utils/FParameters.hpp"
#include "Containers/FOctree.hpp"
#ifdef _OPENMP
#include "Core/FFmmAlgorithmThread.hpp"
#else
#include "Core/FFmmAlgorithmThread.hpp"
#endif
/**
* This program runs the FMM Algorithm with the Chebyshev kernel and compares the results with a direct computation.
*/
/// \file ChebyshevInterpolationFMM.cpp
//!
//! \brief This program runs the FMM Algorithm with the interpolation kernel based on Chebyshev interpolation (1/r kernel)
//! \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. The file have to be in our FMA format
//! \param -bin if the file is in binary mode
//!
//
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
<< " -bin if the 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[])
{
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);
}
#ifdef _OPENMP
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;
#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 timer
FTic time;
// open particle file
////////////////////////////////////////////////////////////////////
//
FFmaGenericLoader loader(filename);
//
////////////////////////////////////////////////////////////////////
// begin Chebyshev kernel
// accuracy
const unsigned int ORDER = 7;
// typedefs
typedef FP2PParticleContainerIndexed<> ContainerClass;
typedef FSimpleLeaf< ContainerClass > LeafClass;
typedef FChebCell<ORDER> CellClass;
typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
//
typedef FInterpMatrixKernelR MatrixKernelClass;
typedef FChebSymKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
//
#ifdef _OPENMP
typedef FFmmAlgorithmThread<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
#else
typedef FFmmAlgorithm<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
#endif
// init oct-tree
OctreeClass tree(TreeHeight, SubTreeHeight, loader.getBoxWidth(), loader.getCenterOfBox());
{ // -----------------------------------------------------
std::cout << "Creating & Inserting " << loader.getNumberOfParticles()
<< " particles ..." << std::endl;
std::cout << "\tHeight : " << TreeHeight << " \t sub-height : " << SubTreeHeight << std::endl;
time.tic();
//
FPoint position;
FReal physicalValue = 0.0;
//
for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
//
// Read particle per particle from file
loader.fillParticle(&position,&physicalValue);
//
// put particle in octree
tree.insert(position, idxPart, physicalValue);
}
time.tac();
std::cout << "Done " << "(@Creating and Inserting Particles = "
<< time.elapsed() << " s) ." << std::endl;
} // -----------------------------------------------------
{ // -----------------------------------------------------
std::cout << "\nChebyshev FMM (ORDER="<< ORDER << ") ... " << std::endl;
time.tic();
//
KernelClass kernels(TreeHeight, loader.getBoxWidth(), loader.getCenterOfBox());
//
FmmClass algorithm(&tree, &kernels);
//
algorithm.execute(); // Here the call of the FMM algorithm
//
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 ;
//
// 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>& indexes = leaf->getTargets()->getIndexes();
for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
const int indexPartOrig = indexes[idxPart];
if ((indexPartOrig == N1) || (indexPartOrig == N2) || (indexPartOrig == N3) ) {
std::cout << "Index "<< indexPartOrig <<" potential " << potentials[idxPart]
<< " Pos "<<posX[idxPart]<<" "<<posY[idxPart]<<" "<<posZ[idxPart]
<< " Forces: " << forcesX[idxPart] << " " << forcesY[idxPart] << " "<< forcesZ[idxPart] <<std::endl;
}
energy += potentials[idxPart]*physicalValues[idxPart] ;
}
});
std::cout <<std::endl<<"Energy: "<< energy<<std::endl;
std::cout <<std::endl<<" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& "<<std::endl<<std::endl;
}
// -----------------------------------------------------
return 0;
}
This diff is collapsed.
......@@ -25,16 +25,26 @@
#include "ScalFmmConfig.h"
#include "Utils/FTic.hpp"
//#include "Utils/FMath.hpp"
#include "Utils/FParameters.hpp"
//#include "Utils/FIOVtk.hpp"
//#include "Containers/FVector.hpp"
#include "Files/FFmaGenericLoader.hpp"
#include "Kernels/P2P/FP2P.hpp"
//
/// \file DirectComputation.cpp
//!
//! \brief DirectComputation: Driver to compute direct interaction between N particles for 1/r kernel.
//!
//! DirectComputation: Driver to compute direct interaction between N particles for 1/r kernel.
//! the particles are read from file given by -fin argument and potential, forces are stored in FMA format.
//! <b> General arguments:</b>
//! \param -help (-h) to see the parameters available in this driver
//! \param -fin name: file name to convert (with extension .fma (ascii) or bfma (binary).
//! Only our FMA (.bma, .bfma) is allowed "
//! \param -fout filenameOUT output file with extension (default output.bfma)
//! \param -verbose : print index x y z Q V fx fy fz
//!
// Simply create particles and try the kernels
int main(int argc, char ** argv){
......@@ -55,7 +65,8 @@ int main(int argc, char ** argv){
//////////////////////////////////////////////////////////////
const std::string filenameIn(FParameters::getStr(argc,argv,"-fin", "../Data/unitCubeXYZQ20k.fma"));
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"));
//
FTic counter;
......
......@@ -21,8 +21,10 @@
#include <iostream>
#include <stdexcept>
#include <cstdio>
#include <string>
#include <cstdlib>
#include "ScalFmmConfig.h"
#include "Utils/FParameters.hpp"
#include "Files/FFmaGenericLoader.hpp"
......@@ -35,8 +37,11 @@
#include "Containers/FOctree.hpp"
#ifdef _OPENMP
#include "Core/FFmmAlgorithmThread.hpp"
#else
#include "Core/FFmmAlgorithm.hpp"
#endif
/// \file RotationFMM.cpp
//!
......@@ -71,7 +76,8 @@ void usage() {
// Simply create particles and try the kernels
int main(int argc, char* argv[])
{
const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.fma");
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);
......@@ -97,17 +103,12 @@ int main(int argc, char* argv[])
FTic time;
// open particle file
bool binaryMode = false;
if(FParameters::existParameter(argc, argv, "-bin")){
binaryMode = true;
}
FFmaGenericLoader loader(filename,binaryMode);
if(!loader.isOpen()) throw std::runtime_error("Particle file couldn't be opened!") ;
////////////////////////////////////////////////////////////////////
//
FFmaGenericLoader loader(filename);
//
////////////////////////////////////////////////////////////////////
//
// begin spherical kernel
// accuracy
......@@ -120,15 +121,18 @@ int main(int argc, char* argv[])
//
typedef FRotationKernel< CellClass, ContainerClass , P> KernelClass;
//
#ifdef _OPENMP
typedef FFmmAlgorithmThread<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
#else
typedef FFmmAlgorithm<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
#endif
// init oct-tree
OctreeClass tree(TreeHeight, SubTreeHeight, loader.getBoxWidth(), loader.getCenterOfBox());
{ // -----------------------------------------------------
std::cout << "Creating & Inserting " << loader.getNumberOfParticles()
<< " particles ..." << std::endl;
<< " particles ..." << std::endl;
std::cout << "\tHeight : " << TreeHeight << " \t sub-height : " << SubTreeHeight << std::endl;
time.tic();
//
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas
// 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".
// ===================================================================================
// ==== CMAKE =====
// @FUSE_MPI
// ================
#include <iostream>
#include <stdexcept>
#include <cstdio>
#include <cstdlib>
#include "ScalFmmConfig.h"
#include "../../Src/Containers/FOctree.hpp"
#include "../../Src/Utils/FMpi.hpp"
#include "../../Src/Core/FFmmAlgorithmThreadProc.hpp"
#include "../../Src/Files/FFmaGenericLoader.hpp"
#include "../../Src/Files/FMpiFmaLoader.hpp"
#include "../../Src/Files/FMpiTreeBuilder.hpp"
#include "../../Src/BalanceTree/FLeafBalance.hpp"
#include "../../Src/Kernels/Rotation/FRotationKernel.hpp"
#include "../../Src/Kernels/Rotation/FRotationCell.hpp"
#include "../../Src/Components/FSimpleLeaf.hpp"
#include "../../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "../../Src/Utils/FParameters.hpp"
/// \file RotationFMMProc.cpp
//!
//! \brief This program runs the MPI FMM with harmonic spherical approximation of 1/r kernel
//! \authors B. Bramas, O. Coulaud
//!
//! This code is a short example to use the rotation harmonic spherical approximation 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. The file have to be in our FMA format
//! \param -bin if the file is in binary mode
//!
//
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);
}
#ifdef _OPENMP
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;
#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;
FMpiFmaLoader loader(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());
{ // -----------------------------------------------------
std::cout << "Creating & Inserting " << loader.getNumberOfParticles()
<< " particles ..." << std::endl;
std::cout << "\tHeight : " << TreeHeight << " \t sub-height : " << SubTreeHeight << std::endl;
time.tic();
//
struct TestParticle{
FPoint position;
FReal physicalValue;
const FPoint& getPosition(){
return position;
}
};
TestParticle* particles = new TestParticle[loader.getNumberOfParticles()];
memset(particles, 0, (unsigned int) (sizeof(TestParticle) * loader.getNumberOfParticles()));
for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
// Read particles from file
loader.fillParticle(&particles[idxPart].position,&particles[idxPart].physicalValue);
}
FVector<TestParticle> finalParticles;
FLeafBalance balancer;
FMpiTreeBuilder< TestParticle >::ArrayToTree(app.global(), particles, loader.getNumberOfParticles(),
tree.getBoxCenter(),
tree.getBoxWidth(),
tree.getHeight(), &finalParticles,&balancer);
for(int idx = 0 ; idx < finalParticles.getSize(); ++idx){
tree.insert(finalParticles[idx].position,idx,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;
}
// -----------------------------------------------------
//
// Some output
//
//
{ // -----------------------------------------------------
long int N1=0, N2= loader.getNumberOfParticles()/4, N3= (loader.getNumberOfParticles() -1)/2; ;
FReal energy =0.0 ;
//
// 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 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>& indexes = leaf->getTargets()->getIndexes();
for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
const int indexPartOrig = indexes[idxPart];
if ((indexPartOrig == N1) || (indexPartOrig == N2) || (indexPartOrig == N3) ) {
std::cout << "Proc "<< app.global().processId() << " Index "<< indexPartOrig <<" potential " << potentials[idxPart]
<< " Forces: " << forcesX[idxPart] << " " << forcesY[idxPart] << " "<< forcesZ[idxPart] <<std::endl;
}
energy += potentials[idxPart]*physicalValues[idxPart] ;
}
});
std::cout <<std::endl<<"Energy: "<< energy<<std::endl;
std::cout <<std::endl<<" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& "<<std::endl<<std::endl;
}
// -----------------------------------------------------
return 0;
}
......@@ -8,8 +8,9 @@
#include <iostream>
#include <fstream>
//#include <sstream>
#include <string>
#include <cstdlib>
//
#include "Utils/FGlobal.hpp"
#include "Utils/FPoint.hpp"
#include "Files/FFmaGenericLoader.hpp"
......@@ -17,11 +18,12 @@
#include "Utils/FGenerateDistribution.hpp"
//
/// \file changeFormat.cpp
/// \file changeFmaFormat.cpp
//!
//! \brief changeFormat: Driver to transform a FMA format and to build a visualization file
//!
//!
//! Driver to transform a FMA format and/or to build a visualization file<br>
//! For a description of the FMA format see FFmaGenericLoader<br>
//! <b> General arguments:</b>
//! \param -help (-h) to see the parameters available in this driver
//! \param -fin name: file name to convert (with extension .fma (ascii) or bfma (binary)
......@@ -66,47 +68,48 @@ int main(int argc, char ** argv){
//
// Allocation
//
long int NbPoints = loader.getNumberOfParticles();
FSize NbPoints = loader.getNumberOfParticles();
const unsigned int nbData = loader.getNbRecordPerline() ;
const unsigned int arraySize =nbData*NbPoints;
FReal * particles ;
FReal * particles ;
particles = new FReal[arraySize] ;
memset(particles,0,arraySize*sizeof(FReal));
std::memset(particles,0,arraySize*sizeof(FReal));
//
// Read Data
int j = 0, k=0 ;
for(int idxPart = 0 ; idxPart < NbPoints ;++idxPart, j+=nbData){
// //
// //
loader.fillParticle(&particles[j],nbData);
// std::cout << "idxPart "<< idxPart << " ";
// for (int jj= 0 ; jj<nbData ; ++jj, ++k){
// std::cout << particles[k] << " ";
// }
// std::cout << std::endl;
// std::cout << "idxPart "<< idxPart << " ";
// for (int jj= 0 ; jj<nbData ; ++jj, ++k){
// std::cout << particles[k] << " ";
// }
// std::cout << std::endl;
}
//
/////////////////////////////////////////////////////////////////////////
// Save data
/////////////////////////////////////////////////////////////////////////
//
// Generate file for ScalFMM Loader
// Generate file for ScalFMM FMAGenericLoader
//
bool binaryMode = false;
std::string outfilename(FParameters::getStr(argc,argv,"-fout", "output"));
if( FParameters::existParameter(argc, argv, "-bin")){
binaryMode = true;
outfilename += ".bfma";
}
else {
outfilename += ".fma";
if(FParameters::existParameter(argc, argv, "-fout")){
std::string name(FParameters::getStr(argc,argv,"-fout", "output"));
if( FParameters::existParameter(argc, argv, "-bin")){
name += ".bfma";
}
else {
name += ".fma";
}
FFmaGenericWriter writer(name) ;
writer.writeHeader( loader.getCenterOfBox(), loader.getBoxWidth() , NbPoints, sizeof(FReal), nbData) ;
writer.writeArrayOfReal(particles, nbData, NbPoints);
}
FFmaGenericWriter writer(outfilename,binaryMode) ;
writer.writeHeader( loader.getCenterOfBox(), loader.getBoxWidth() , NbPoints, sizeof(FReal), nbData) ;
writer.writeArrayOfReal(particles, nbData, NbPoints);