From 799e9fc2289fda4701f751e0c2952a42a87c78b0 Mon Sep 17 00:00:00 2001 From: bramas <berenger.bramas@inria.fr> Date: Wed, 16 Oct 2013 17:44:13 +0200 Subject: [PATCH] update TSM model using enum to enable tsm and index, but should be update and the result are wrong --- Src/Components/FBasicParticleContainer.hpp | 3 +- Src/Components/FParticleType.hpp | 24 ++ Src/Components/FTypedLeaf.hpp | 9 +- Src/Files/FFmaTsmLoader.hpp | 6 +- Src/Files/FRandomLoader.hpp | 6 +- .../P2P/FP2PParticleContainerIndexed.hpp | 5 +- Tests/Kernels/testSphericalTsmAlgorithm.cpp | 6 +- Tests/Utils/testFmmAlgorithmTsm.cpp | 6 +- Tests/Utils/testLoaderFMATsm.cpp | 6 +- UTests/utestRotationDirectTsm.cpp | 240 ++++++++++++++++++ 10 files changed, 292 insertions(+), 19 deletions(-) create mode 100644 Src/Components/FParticleType.hpp create mode 100644 UTests/utestRotationDirectTsm.cpp diff --git a/Src/Components/FBasicParticleContainer.hpp b/Src/Components/FBasicParticleContainer.hpp index 5dc496fc4..1c09c2609 100755 --- a/Src/Components/FBasicParticleContainer.hpp +++ b/Src/Components/FBasicParticleContainer.hpp @@ -21,6 +21,7 @@ #include "../Utils/FAlignedMemory.hpp" #include "../Utils/FMath.hpp" #include "../Utils/FPoint.hpp" +#include "FParticleType.hpp" /** * @author Berenger Bramas (berenger.bramas@inria.fr) @@ -200,7 +201,7 @@ public: * Push called usually by FTypedLeaf with the isTarget flag in addition */ template<typename... Args> - void push(const FPoint& inParticlePosition, const bool /*isTarget*/, Args... args){ + void push(const FPoint& inParticlePosition, const FParticleType /*particleType*/, Args... args){ push(inParticlePosition, args...); } diff --git a/Src/Components/FParticleType.hpp b/Src/Components/FParticleType.hpp new file mode 100644 index 000000000..8edd0d892 --- /dev/null +++ b/Src/Components/FParticleType.hpp @@ -0,0 +1,24 @@ +// =================================================================================== +// 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". +// =================================================================================== +#ifndef FPARTICLETYPE_HPP +#define FPARTICLETYPE_HPP + +enum FParticleType { + FParticleTypeSource = 0, + FParticleTypeTarget = 1 +}; + +#endif // FPARTICLETYPE_HPP diff --git a/Src/Components/FTypedLeaf.hpp b/Src/Components/FTypedLeaf.hpp index 8f5906016..1fc1a65d1 100755 --- a/Src/Components/FTypedLeaf.hpp +++ b/Src/Components/FTypedLeaf.hpp @@ -19,6 +19,8 @@ #include "../Utils/FAssertable.hpp" #include "FAbstractLeaf.hpp" +#include "FParticleType.hpp" + /** * @author Berenger Bramas (berenger.bramas@inria.fr) @@ -36,6 +38,7 @@ class FTypedLeaf : public FAbstractLeaf<ContainerClass>, public FAssertable { ContainerClass targets; //< The targets containers public: + /** Default destructor */ virtual ~FTypedLeaf(){ } @@ -47,9 +50,9 @@ public: * followed by other param given by the user */ template<typename... Args> - void push(const FPoint& inParticlePosition, const bool isTarget, Args ... args){ - if(isTarget) targets.push(inParticlePosition, isTarget, args...); - else sources.push(inParticlePosition, isTarget, args...); + void push(const FPoint& inParticlePosition, const FParticleType type, Args ... args){ + if(type == FParticleTypeTarget) targets.push(inParticlePosition, FParticleTypeTarget, args...); + else sources.push(inParticlePosition, FParticleTypeSource, args...); } /** diff --git a/Src/Files/FFmaTsmLoader.hpp b/Src/Files/FFmaTsmLoader.hpp index e372cdcdc..4c5356ee0 100755 --- a/Src/Files/FFmaTsmLoader.hpp +++ b/Src/Files/FFmaTsmLoader.hpp @@ -23,6 +23,7 @@ #include "../Utils/FGlobal.hpp" #include "FAbstractLoader.hpp" #include "../Utils/FPoint.hpp" +#include "../Components/FParticleType.hpp" /** * @author Berenger Bramas (berenger.bramas@inria.fr) @@ -122,14 +123,15 @@ public: * @warning to work with the loader, particles has to expose a setPosition method * @param the particle to fill */ - void fillParticle(FPoint*const inParticlePositions, FReal*const inPhysicalValue, bool*const inIsTarget){ + void fillParticle(FPoint*const inParticlePositions, FReal*const inPhysicalValue, FParticleType*const particleType){ FReal x,y,z,data; int isTarget; this->file >> x >> y >> z >> data >> isTarget; inParticlePositions->setPosition(x,y,z); *inPhysicalValue = data; - *inIsTarget = isTarget; + if(isTarget) (*particleType) = FParticleTypeTarget; + else (*particleType) = FParticleTypeSource; } }; diff --git a/Src/Files/FRandomLoader.hpp b/Src/Files/FRandomLoader.hpp index 21fce59d6..7b59de0e5 100755 --- a/Src/Files/FRandomLoader.hpp +++ b/Src/Files/FRandomLoader.hpp @@ -25,6 +25,7 @@ #include "FAbstractLoader.hpp" #include "../Utils/FPoint.hpp" +#include "../Components/FParticleType.hpp" /** * @author Berenger Bramas (berenger.bramas@inria.fr) @@ -114,9 +115,10 @@ public: } - void fillParticle(FPoint*const inParticlePositions, bool*const isTarget){ + void fillParticle(FPoint*const inParticlePositions, FParticleType*const isTarget){ FRandomLoader::fillParticle(inParticlePositions); - (*isTarget) = (FRandomLoader::getRandom() > 0.5 ); + if(FRandomLoader::getRandom() > 0.5 ) (*isTarget) = FParticleTypeTarget; + else (*isTarget) = FParticleTypeSource; } }; diff --git a/Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp b/Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp index 6ec6097b9..a74440e46 100644 --- a/Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp +++ b/Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp @@ -4,6 +4,7 @@ #include "../../Containers/FVector.hpp" #include "FP2PParticleContainer.hpp" +#include "../../Components/FParticleType.hpp" class FP2PParticleContainerIndexed : public FP2PParticleContainer { typedef FP2PParticleContainer Parent; @@ -18,8 +19,8 @@ public: } template<typename... Args> - void push(const FPoint& inParticlePosition, const bool isTarget, const int index, Args... args){ - Parent::push(inParticlePosition, isTarget, args... ); + void push(const FPoint& inParticlePosition, const FParticleType particleType, const int index, Args... args){ + Parent::push(inParticlePosition, particleType, args... ); indexes.push(index); } diff --git a/Tests/Kernels/testSphericalTsmAlgorithm.cpp b/Tests/Kernels/testSphericalTsmAlgorithm.cpp index f953cb7dc..bda26e84d 100755 --- a/Tests/Kernels/testSphericalTsmAlgorithm.cpp +++ b/Tests/Kernels/testSphericalTsmAlgorithm.cpp @@ -83,9 +83,9 @@ int main(int argc, char ** argv){ for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){ FPoint particlePosition; FReal physicalValue = 0.0; - bool isTarget; - loader.fillParticle(&particlePosition,&physicalValue,&isTarget); - tree.insert(particlePosition, isTarget, physicalValue ); + FParticleType particleType; + loader.fillParticle(&particlePosition,&physicalValue,&particleType); + tree.insert(particlePosition, particleType, physicalValue ); } counter.tac(); diff --git a/Tests/Utils/testFmmAlgorithmTsm.cpp b/Tests/Utils/testFmmAlgorithmTsm.cpp index 1355b4f19..5dd9f0259 100755 --- a/Tests/Utils/testFmmAlgorithmTsm.cpp +++ b/Tests/Utils/testFmmAlgorithmTsm.cpp @@ -83,10 +83,10 @@ int main(int argc, char ** argv){ { FPoint particlePosition; - bool isTarget; + FParticleType particleType; for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){ - loader.fillParticle(&particlePosition, &isTarget); - tree.insert(particlePosition, isTarget); + loader.fillParticle(&particlePosition, &particleType); + tree.insert(particlePosition, particleType); } } diff --git a/Tests/Utils/testLoaderFMATsm.cpp b/Tests/Utils/testLoaderFMATsm.cpp index 747150d33..f1fcd19c9 100755 --- a/Tests/Utils/testLoaderFMATsm.cpp +++ b/Tests/Utils/testLoaderFMATsm.cpp @@ -72,10 +72,10 @@ int main(int argc, char ** argv ){ FPoint particlePosition; FReal physicalValue = 0.0; - bool isTarget; + FParticleType particleType; for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){ - loader.fillParticle(&particlePosition,&physicalValue, &isTarget); - tree.insert(particlePosition, isTarget, physicalValue); + loader.fillParticle(&particlePosition,&physicalValue, &particleType); + tree.insert(particlePosition, particleType, physicalValue); } counter.tac(); diff --git a/UTests/utestRotationDirectTsm.cpp b/UTests/utestRotationDirectTsm.cpp new file mode 100644 index 000000000..12152da32 --- /dev/null +++ b/UTests/utestRotationDirectTsm.cpp @@ -0,0 +1,240 @@ + +// =================================================================================== +// 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 "../Src/Utils/FGlobal.hpp" + +#include "../Src/Containers/FOctree.hpp" +#include "../Src/Containers/FVector.hpp" + +#include "../Src/Kernels/Rotation/FRotationCell.hpp" +#include "../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp" + +#include "../Src/Components/FTypedLeaf.hpp" +#include "../Src/Extensions/FExtendCellType.hpp" +#include "../Src/Kernels/Rotation/FRotationKernel.hpp" + +#include "../Src/Files/FRandomLoader.hpp" + +#include "../Src/Core/FFmmAlgorithmThreadTsm.hpp" +#include "../Src/Core/FFmmAlgorithmTsm.hpp" + +#include "FUTester.hpp" + + +/** the test class the rotation and target source model. + * + */ +class TestRotationDirectTsm : public FUTester<TestRotationDirectTsm> { + /** The test method to factorize all the test based on different kernels */ + template <class CellClass, class ContainerClass, class KernelClass, class LeafClass, + class OctreeClass, class FmmClass> + void RunTest(){ + // Warning in make test the exec dir it Build/UTests + // Load particles + const int nbSources = 5000; + const int nbTargets = 5000; + + FRandomLoader loader(nbSources + nbTargets); + + Print("Number of particles:"); + Print(loader.getNumberOfParticles()); + + const int NbLevels = 4; + const int SizeSubLevels = 2; + + + struct TestParticle{ + FPoint position; + FReal forces[3]; + FReal physicalValue; + FReal potential; + }; + + TestParticle* const particlesSources = new TestParticle[nbSources]; + TestParticle* const particlesTargets = new TestParticle[nbTargets]; + + // Create octree + OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox()); + + const FReal physicalValue = 0.10; + + for(int idxPart = 0 ; idxPart < nbTargets ; ++idxPart){ + FPoint position; + loader.fillParticle(&position); + // put in tree + tree.insert(position, FParticleTypeTarget, idxPart, physicalValue); + // get copy + particlesTargets[idxPart].position = position; + particlesTargets[idxPart].potential = 0.0; + particlesTargets[idxPart].physicalValue = physicalValue; + particlesTargets[idxPart].forces[0] = 0.0; + particlesTargets[idxPart].forces[1] = 0.0; + particlesTargets[idxPart].forces[2] = 0.0; + } + + for(int idxPart = 0 ; idxPart < nbSources ; ++idxPart){ + FPoint position; + loader.fillParticle(&position); + // put in tree + tree.insert(position, FParticleTypeSource, idxPart, physicalValue); + // get copy + particlesSources[idxPart].position = position; + particlesSources[idxPart].physicalValue = physicalValue; + } + + + // Run FMM + Print("Fmm..."); + //KernelClass kernels(NbLevels,loader.getBoxWidth()); + KernelClass kernels(NbLevels,loader.getBoxWidth(), loader.getCenterOfBox()); + FmmClass algo(&tree,&kernels); + algo.execute(); + + // Run direct computation + Print("Direct..."); + for(int idxTarget = 0 ; idxTarget < nbTargets ; ++idxTarget){ + for(int idxOther = 0 ; idxOther < nbSources ; ++idxOther){ + FP2P::NonMutualParticles( + particlesSources[idxOther].position.getX(), particlesSources[idxOther].position.getY(), + particlesSources[idxOther].position.getZ(),particlesSources[idxOther].physicalValue, + particlesTargets[idxTarget].position.getX(), particlesTargets[idxTarget].position.getY(), + particlesTargets[idxTarget].position.getZ(),particlesTargets[idxTarget].physicalValue, + &particlesTargets[idxTarget].forces[0],&particlesTargets[idxTarget].forces[1], + &particlesTargets[idxTarget].forces[2],&particlesTargets[idxTarget].potential); + } + } + + // Compare + Print("Compute Diff..."); + FMath::FAccurater potentialDiff; + FMath::FAccurater fx, fy, fz; + { // Check that each particle has been summed with all other + + tree.forEachLeaf([&](LeafClass* leaf){ + if( leaf->getTargets()->getNbParticles() ){ + 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 FVector<int>& indexes = leaf->getTargets()->getIndexes(); + + for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){ + const int indexPartOrig = indexes[idxPart]; + potentialDiff.add(particlesTargets[indexPartOrig].potential,potentials[idxPart]); + fx.add(particlesTargets[indexPartOrig].forces[0],forcesX[idxPart]); + fy.add(particlesTargets[indexPartOrig].forces[1],forcesY[idxPart]); + fz.add(particlesTargets[indexPartOrig].forces[2],forcesZ[idxPart]); + } + } + }); + } + + delete[] particlesTargets; + delete[] particlesSources; + + // Print for information + Print("Potential diff is = "); + Print(potentialDiff.getL2Norm()); + Print(potentialDiff.getInfNorm()); + Print("Fx diff is = "); + Print(fx.getL2Norm()); + Print(fx.getInfNorm()); + Print("Fy diff is = "); + Print(fy.getL2Norm()); + Print(fy.getInfNorm()); + Print("Fz diff is = "); + Print(fz.getL2Norm()); + Print(fz.getInfNorm()); + + // Assert + const FReal MaximumDiff = FReal(0.0001); + uassert(potentialDiff.getL2Norm() < MaximumDiff); + uassert(potentialDiff.getInfNorm() < MaximumDiff); + uassert(fx.getL2Norm() < MaximumDiff); + uassert(fx.getInfNorm() < MaximumDiff); + uassert(fy.getL2Norm() < MaximumDiff); + uassert(fy.getInfNorm() < MaximumDiff); + uassert(fz.getL2Norm() < MaximumDiff); + uassert(fz.getInfNorm() < MaximumDiff); + } + + /** If memstas is running print the memory used */ + void PostTest() { + if( FMemStats::controler.isUsed() ){ + std::cout << "Memory used at the end " << FMemStats::controler.getCurrentAllocated() << " Bytes (" << FMemStats::controler.getCurrentAllocatedMB() << "MB)\n"; + std::cout << "Max memory used " << FMemStats::controler.getMaxAllocated() << " Bytes (" << FMemStats::controler.getMaxAllocatedMB() << "MB)\n"; + std::cout << "Total memory used " << FMemStats::controler.getTotalAllocated() << " Bytes (" << FMemStats::controler.getTotalAllocatedMB() << "MB)\n"; + } + } + + /////////////////////////////////////////////////////////// + // The tests! + /////////////////////////////////////////////////////////// + + static const int P = 9; + + template <const int P> + class CustomTypedRotationCell : public FRotationCell<P>, public FExtendCellType{ + }; + + /** Rotation */ + void TestRotation(){ + typedef CustomTypedRotationCell<P> CellClass; + typedef FP2PParticleContainerIndexed ContainerClass; + + typedef FRotationKernel<CellClass, ContainerClass, P > KernelClass; + + typedef FTypedLeaf<ContainerClass > LeafClass; + typedef FOctree< CellClass, ContainerClass , LeafClass > OctreeClass; + + typedef FFmmAlgorithmTsm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass; + + RunTest<CellClass, ContainerClass, KernelClass, LeafClass, OctreeClass, FmmClass>(); + } + + void TestRotationThread(){ + typedef CustomTypedRotationCell<P> CellClass; + typedef FP2PParticleContainerIndexed ContainerClass; + + typedef FRotationKernel<CellClass, ContainerClass, P > KernelClass; + + typedef FTypedLeaf<ContainerClass > LeafClass; + typedef FOctree< CellClass, ContainerClass , LeafClass > OctreeClass; + + typedef FFmmAlgorithmThreadTsm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClass; + + RunTest<CellClass, ContainerClass, KernelClass, LeafClass, OctreeClass, FmmClass>(); + } + + /////////////////////////////////////////////////////////// + // Set the tests! + /////////////////////////////////////////////////////////// + + /** set test */ + void SetTests(){ + AddTest(&TestRotationDirectTsm::TestRotation,"Test Rotation Kernel TSM"); + AddTest(&TestRotationDirectTsm::TestRotation,"Test Rotation Kernel TSM thread"); + } +}; + + +// You must do this +TestClass(TestRotationDirectTsm) + + + -- GitLab