// =================================================================================== // Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger 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". // =================================================================================== // ==== CMAKE ===== // @FUSE_BLAS // @FUSE_FFT // ================ #include #include #include "Utils/FParameters.hpp" #include "Utils/FTic.hpp" #include "Containers/FOctree.hpp" //#include "Containers/FVector.hpp" //#include "Components/FSimpleLeaf.hpp" #include "Utils/FPoint.hpp" #include "Files/FFmaGenericLoader.hpp" #include "Files/FRandomLoader.hpp" #include "Components/FBasicKernels.hpp" #include "Components/FSimpleIndexedLeaf.hpp" #include "Kernels/P2P/FP2PParticleContainerIndexed.hpp" #include "Adaptative/FAdaptiveCell.hpp" #include "Adaptative/FAdaptiveKernelWrapper.hpp" #include "Adaptative/FAbstractAdaptiveKernel.hpp" // #include "Kernels/Interpolation/FInterpMatrixKernel.hpp" #include "Kernels/Uniform/FUnifCell.hpp" #include "AdaptiveTree/FAdaptUnifKernel.hpp" #include "AdaptiveTree/FAdaptTools.hpp" // // #include "Core/FFmmAlgorithm.hpp" //#include "Core/FFmmAlgorithmThread.hpp" //#include "Core/FFmmAlgorithmTask.hpp" /** This program show an example of use of the fmm basic algo * it also check that each particles is impacted each other particles */ void usage() { std::cout << "Driver to obtain statistics on the octree" << 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 << " -fin name specifies the name of the particle distribution" << std::endl << " -sM s_min^M threshold for Multipole (l+1)^2 for Spherical harmonics"< KernelClass; typedef FUnifCell

CellClass; typedef FP2PParticleContainerIndexed<> ContainerClass; typedef FSimpleIndexedLeaf LeafClass; typedef FInterpMatrixKernelR MatrixKernelClass; // typedef FAdaptiveUnifKernel KernelClass; // // typedef FAdaptiveCell< CellClass, ContainerClass > CellWrapperClass; typedef FAdaptiveKernelWrapper< KernelClass, CellClass, ContainerClass > KernelWrapperClass; typedef FOctree< CellWrapperClass, ContainerClass , LeafClass > OctreeClass; // FFmmAlgorithmTask FFmmAlgorithmThread typedef FFmmAlgorithm FmmClass; ///////////////////////What we do///////////////////////////// std::cout << ">> This executable has to be used to test the FMM algorithm.\n"; ////////////////////////////////////////////////////////////// // const int NbLevels = FParameters::getValue(argc,argv,"-depth", 3); const int SizeSubLevels = FParameters::getValue(argc,argv,"-subdepth", 2); const int sminM = FParameters::getValue(argc,argv,"-sM", P*P*P); const int sminL = FParameters::getValue(argc,argv,"-sL", P*P*P); // FTic counter; ////////////////////////////////////////////////////////////////////////////////// // Not Random Loader ////////////////////////////////////////////////////////////////////////////////// const std::string fileName(FParameters::getStr(argc,argv,"-fin", "../Data/prolate50.out.fma")); FFmaGenericLoader loader(fileName); const long int NbPart = loader.getNumberOfParticles() ; // Random Loader //const int NbPart = FParameters::getValue(argc,argv,"-nb", 2000000); // FRandomLoader loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1); ////////////////////////////////////////////////////////////////////////////////// OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox()); ////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// std::cout << "Creating & Inserting " << NbPart << " particles ..." << std::endl; std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl; std::cout << " criteria SM: "<< sminM <* const particles = new FmaRWParticle<8,8>[NbPart]; FPoint minPos(L,L,L), maxPos(-L,-L,-L); // loader.fillParticle(particles,NbPart); for(int idxPart = 0 ; idxPart < NbPart; ++idxPart){ const FPoint PP(particles[idxPart].getPosition() ) ; // minPos.setX(FMath::Min(minPos.getX(),PP.getX())) ; minPos.setY(FMath::Min(minPos.getY(),PP.getY())) ; minPos.setZ(FMath::Min(minPos.getZ(),PP.getZ())) ; maxPos.setX(FMath::Max(maxPos.getX(),PP.getX())) ; maxPos.setY(FMath::Max(maxPos.getY(),PP.getY())) ; maxPos.setZ(FMath::Max(maxPos.getZ(),PP.getZ())) ; // tree.insert(PP, idxPart, particles[idxPart].getPhysicalValue()); counter.tac(); std::cout << "Data are inside the box delimited by "<getTargets()->getPotentials(); const FReal*const physicalValues = leaf->getTargets()->getPhysicalValues(); 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 FVector& indexes = leaf->getTargets()->getIndexes(); for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){ const int indexPartOrig = indexes[idxPart]; potentialDiff.add(particles[indexPartOrig].getPotential(),potentials[idxPart]); fx.add(particles[indexPartOrig].getForces()[0],forcesX[idxPart]); fy.add(particles[indexPartOrig].getForces()[1],forcesY[idxPart]); fz.add(particles[indexPartOrig].getForces()[2],forcesZ[idxPart]); energy += potentials[idxPart]*physicalValues[idxPart]; // std::cout << indexPartOrig // << " " << particles[indexPartOrig].getPotential() << " " << particles[indexPartOrig].getForces()[0] // << " " << potentials[idxPart] << " " << forcesX[idxPart] // << std::endl; } }); } delete[] particles; // Print for information std::cout << "Potential " << potentialDiff << std::endl; std::cout << "Fx " << fx << std::endl; std::cout << "Fy " << fy << std::endl; std::cout << "Fz " << fz << std::endl; OctreeClass::Iterator octreeIterator(&tree); std::ofstream file("aa.tree", std::ofstream::out ); // //////////////////////////////////////////////////////////////////// // Export adaptive tree in our format //////////////////////////////////////////////////////////////////// // // ----------------------------------------------------- // // // Set Global id // long int idCell = setGlobalID(tree); ////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// tree.forEachCellLeaf([&](CellWrapperClass* cell, LeafClass* leaf){ file << "Cell Id " << cell->getGlobalId( ) << " Nb particles "<< leaf->getSrc()->getNbParticles()<hasDevelopment()){ file <<"Cell id "<< octreeIterator.getCurrentCell()->getGlobalId( ) << " "<<*(octreeIterator.getCurrentCell())<< std::endl ; } } while(octreeIterator.moveRight()); octreeIterator.moveDown() ; octreeIterator.gotoLeft(); } std::cout << " END " << std::endl; // Check octreeIterator.gotoBottomLeft(); do { std::cout << " Level " <