Commit 095e8b6f authored by berenger-bramas's avatar berenger-bramas

Sorry forgot to add the Src dir!

Here it the new src dir with some minor changes in CMake files.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@61 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 00fcfecf
......@@ -34,6 +34,7 @@ endif()
# Compile option
ADD_DEFINITIONS(-O2 -Wall -Wshadow -Wpointer-arith -Wcast-qual)
CONFIGURE_FILE( ${CMAKE_SOURCE_DIR}/Src/ScalFmmConfig.h.cmake
${CMAKE_BINARY_DIR}/Src/ScalFmmConfig.h )
......
cmake_minimum_required(VERSION 2.6)
# Configuration du projet
project(Lib_scalfmm)
set(LIBRARY_OUTPUT_PATH ../lib/${CMAKE_BUILD_TYPE})
# Searching all cpp file
file(
GLOB_RECURSE
source_lib_files
./*.cpp
)
# Adding cpp files to project
add_library(
scalfmm
STATIC
${source_lib_files}
)
# Adding the entire project dir as an include dir
INCLUDE_DIRECTORIES(
${CMAKE_BINARY_DIR}/Sources
)
#ifndef FABSTRACTCELL_HPP
#define FABSTRACTCELL_HPP
// /!\ Please, you must read the license at the bottom of this page
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAbstractCell
* @brief
* Please read the license
*
* This class define the method that every cell class
* has to implement.
*
* In fact FOctree & FFmmAlgorithm need this function to be implemented.
* But you cannot use this interface with the extension (as an example :
* because the compiler will faill to know if getMortonIndex is coming
* from this interface or from the extension)
*
* @warning Inherite from this class when implement a specific cell type
*/
class FAbstractCell{
public:
/** Default destructor */
virtual ~FAbstractCell(){
}
/**
* Must be implemented by each user Cell class
* @return the position of the current cell
*/
virtual MortonIndex getMortonIndex() const = 0;
/**
* Must be implemented by each user Cell class
* @param inIndex the position of the current cell
*/
virtual void setMortonIndex(const MortonIndex inIndex) = 0;
/**
* Must be implemented by each user Cell class
* @param inPosition the position of the current cell
*/
virtual void setPosition(const F3DPosition& inPosition) = 0;
/** Because the system can run in Tsm mode
* a cell has to express if it has sources
* @return true if there are sources particles inside
*/
virtual bool hasSrcChild() const = 0;
/** Because the system can run in Tsm mode
* a cell has to express if it has targets
* @return true if there are targets particles inside
*/
virtual bool hasTargetsChild() const = 0;
/**
* This function make the cell containing sources
*/
virtual void setSrcChildTrue() = 0;
/**
* This function make the cell containing targets
*/
virtual void setTargetsChildTrue() = 0;
};
#endif //FABSTRACTCELL_HPP
// [--LICENSE--]
#ifndef FABSTRACTKERNELS_HPP
#define FABSTRACTKERNELS_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "../Utils/FGlobal.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAbstractKernels
* @brief
* Please read the license
*
* If you want to create you own kernels you have to inherit from this class.
*/
template< class ParticleClass, class CellClass, int TreeHeight>
class FAbstractKernels{
public:
/** Default destructor */
virtual ~FAbstractKernels(){
}
/**
* Init the Kernels
* This function is called just before to start the computation
*/
virtual void init(){}
/**
* P2M
* particles to multipole
* @param pole the multipole to fill using the particles
* @param particles the particles from the same spacial boxe
*/
virtual void P2M(CellClass* const pole, const FList<ParticleClass*>* const particles) = 0;
/**
* M2M
* Multipole to multipole
* @param pole the father (the boxe that contains other ones)
* @param child the boxe to take values from
* @param the current computation level
* the child array has a size of 8 elements (address if exists or 0 otherwise).
* You must test if a pointer is 0 to know if an element exists inside this array
*/
virtual void M2M(CellClass* const FRestrict pole, const CellClass*const FRestrict *const FRestrict child, const int inLevel) = 0;
/**
* M2L
* Multipole to local
* @param local the element to fill using distant neighbors
* @param distantNeighbors is an array containing fathers's direct neighbors's child - direct neigbors
* @param size the number of neighbors
* @param inLevel the current level of the computation
*/
virtual void M2L(CellClass* const FRestrict local, const CellClass*const FRestrict *const FRestrict distantNeighbors, const int size, const int inLevel) = 0;
/**
* L2L
* Local to local
* @param the father to take value from
* @param the child to downward values (child may have already been impacted by M2L)
* @param level the current level of computation
* the child array has a size of 8 elements (address if exists or 0 otherwise).
* You must test if a pointer is 0 to know if an element exists inside this array
*/
virtual void L2L(const CellClass* const FRestrict local, CellClass* FRestrict * const FRestrict child, const int inLevel) = 0;
/**
* L2P
* Local to particles
* @param local the leaf element (smaller boxe local element)
* @param particles the list of particles inside this boxe
*/
virtual void L2P(const CellClass* const local, FList<ParticleClass*>* const particles) = 0;
/**
* P2P
* Particles to particles
* @param targets current boxe targets particles
* @param sources current boxe sources particles
* @param directNeighborsParticles the particles from direct neighbors (this is an array of list)
* @param size the number of direct neighbors (the size of the array directNeighborsParticles)
*/
virtual void P2P(FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>*const FRestrict *const FRestrict directNeighborsParticles, const int size) = 0;
};
#endif //FABSTRACTKERNELS_HPP
// [--LICENSE--]
#ifndef FABSTRACTLEAF_HPP
#define FABSTRACTLEAF_HPP
// /!\ Please, you must read the license at the bottom of this page
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAbstractLeaf
* @brief
* Please read the license
* This class is used to enable the use of typed particles
* (source XOR target) or simple system (source AND target)
*/
template< class ParticleClass >
class FAbstractLeaf {
public:
/** Default destructor */
virtual ~FAbstractLeaf(){
}
/**
* To add a new particle in the leaf
* @param particle the new particle
* Depending on the system to use the class that inherit
* this interface can sort the particle as they like.
*/
virtual void push(ParticleClass* const particle) = 0;
/**
* To get all the sources in a leaf
* @return a pointer to the list of particles that are sources
* Depending on the system to use the class that inherit
* this interface can sort the particle as they like.
*/
virtual FList<ParticleClass*>* getSrc() = 0;
/**
* To get all the target in a leaf
* @return a pointer to the list of particles that are targets
* Depending on the system to use the class that inherit
* this interface can sort the particle as they like.
*/
virtual FList<ParticleClass*>* getTargets() = 0;
};
#endif //FABSTRACTLEAF_HPP
// [--LICENSE--]
#ifndef FABSTRACTPARTICLE_HPP
#define FABSTRACTPARTICLE_HPP
// /!\ Please, you must read the license at the bottom of this page
/* forward declaration to avoid include */
class F3DPosition;
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FAbstractBody
* @brief
* Please read the license
*
* This class define the method that every particle class
* has to implement.
*
* In fact FOctree & FFmmAlgorithm need this function to be implemented.
* But you cannot use this interface with the extension (as an example :
* because the compiler will faill to know if getPosition is coming
* from this interface or from the extension)
*
*
* @warning Inherite from this class when implement a specific particle type
*/
class FAbstractParticle{
public:
/** Default destructor */
virtual ~FAbstractParticle(){
}
/**
* Must be implemented by each user Particle class
* @return the position of the current cell
*/
virtual F3DPosition getPosition() const = 0;
};
#endif //FABSTRACTPARTICLE_HPP
// [--LICENSE--]
#ifndef FBASICCELL_HPP
#define FBASICCELL_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "../Extenssions/FExtendPosition.hpp"
#include "../Extenssions/FExtendMortonIndex.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FBasicCell
* Please read the license
*
* This class defines a basic cell used for examples. It extends
* the mininum, only what is needed by FOctree and FFmmAlgorithm
* to make the things working.
* By using this extension it will implement the FAbstractCell without
* inheriting from it.
*/
class FBasicCell : public FExtendPosition, public FExtendMortonIndex {
public:
/** Default destructor */
virtual ~FBasicCell(){
}
};
#endif //FBASICCELL_HPP
// [--LICENSE--]
#ifndef FBASICKERNELS_HPP
#define FBASICKERNELS_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "FAbstractKernels.hpp"
#include "../Utils/FTrace.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class AbstractKernels
* @brief
* Please read the license
*
* This kernels simply shows the details of the information
* it receives (in debug)
*/
template< class ParticleClass, class CellClass, int TreeHeight>
class FBasicKernels : public FAbstractKernels<ParticleClass,CellClass,TreeHeight> {
public:
/** Default destructor */
virtual ~FBasicKernels(){
}
/** When init the kernel */
virtual void init(){}
/** Print the number of particles */
virtual void P2M(CellClass* const , const FList<ParticleClass*>* const ) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
/** Print the morton index */
virtual void M2M(CellClass* const FRestrict , const CellClass*const FRestrict *const FRestrict , const int ) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
/** Print the morton index */
virtual void M2L(CellClass* const FRestrict , const CellClass*const FRestrict *const FRestrict , const int , const int ) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
/** Print the morton index */
virtual void L2L(const CellClass* const FRestrict , CellClass* FRestrict *const FRestrict , const int ) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
/** Print the number of particles */
virtual void L2P(const CellClass* const , FList<ParticleClass*>* const ){
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
/** Print the number of particles */
virtual void P2P(FList<ParticleClass*>* const FRestrict , const FList<ParticleClass*>* const FRestrict ,
FList<ParticleClass*>* FRestrict const* FRestrict , const int ) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
};
#endif //FBASICKERNELS_HPP
// [--LICENSE--]
#ifndef FBASICPARTICLE_HPP
#define FBASICPARTICLE_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "../Extenssions/FExtendPosition.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FBasicParticle
* Please read the license
*
* This class defines a basic particle used for examples. It extends
* the mininum, only what is needed by FOctree and FFmmAlgorithm
* to make the things working.
* By using this extension it will implement the FAbstractParticle without
* inheriting from it.
*/
class FBasicParticle : public FExtendPosition{
public:
/** Default destructor */
virtual ~FBasicParticle(){
}
};
#endif //FBASICPARTICLE_HPP
// [--LICENSE--]
#ifndef FFmaPARTICLE_HPP
#define FFmaPARTICLE_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "FBasicParticle.hpp"
#include "../Extenssions/FExtendPhysicalValue.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FFmaParticle
* Please read the license
*
* This class defines a particle for FMA loader.
* As defined in FFmaLoader it needs {FBasicParticle,FExtendPhysicalValue}
*/
class FFmaParticle : public FBasicParticle, public FExtendPhysicalValue {
public:
/** Default destructor */
virtual ~FFmaParticle(){
}
};
#endif //FFmaPARTICLE_HPP
// [--LICENSE--]
#ifndef FSIMPLELEAF_HPP
#define FSIMPLELEAF_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "../Containers/FList.hpp"
#include "FAbstractLeaf.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FSimpleLeaf
* @brief
* Please read the license
* This class is used as a leaf in simple system (source AND target)
* here there is only one list that store all particles.
*/
template< class ParticleClass >
class FSimpleLeaf : public FAbstractLeaf<ParticleClass> {
FList<ParticleClass*> particles;
public:
/** Default destructor */
virtual ~FSimpleLeaf(){
}
/**
* To add a new particle in the leaf
* @param particle the new particle
*/
void push(ParticleClass* const particle){
this->particles.pushFront(particle);
}
/**
* To get all the sources in a leaf
* @return a pointer to the list of particles that are sources
*/
FList<ParticleClass*>* getSrc() {
return &this->particles;
}
/**
* To get all the target in a leaf
* @return a pointer to the list of particles that are targets
*/
FList<ParticleClass*>* getTargets() {
return &this->particles;
}
};
#endif //FSIMPLELEAF_HPP
// [--LICENSE--]
#ifndef FTESTCELL_HPP
#define FTESTCELL_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "FBasicCell.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FBasicCell
* Please read the license
*
* This class is used in the FTestKernels, please
* look at this class to know whit it is.
*/
class FTestCell : public FBasicCell {
// To store data during upward and downward pass
long dataUp, dataDown;
public:
FTestCell(): dataUp(0) , dataDown(0){
}
/** Default destructor */
virtual ~FTestCell(){
}
long getDataUp() const {
return this->dataUp;
}
void setDataUp(const long inData){
this->dataUp = inData;
}
long getDataDown() const {
return this->dataDown;
}
void setDataDown(const long inData){
this->dataDown = inData;
}
};
#endif //FTESTCELL_HPP
// [--LICENSE--]
#ifndef FTESTKERNELS_HPP
#define FTESTKERNELS_HPP
// /!\ Please, you must read the license at the bottom of this page
#include <iostream>
#include "FAbstractKernels.hpp"
#include "../Containers/FList.hpp"
#include "../Containers/FOctree.hpp"
#include "../Utils/FTrace.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class AbstractKernels
* @brief
* Please read the license
*
* This kernels is a virtual kernels to validate that the fmm algorithm is
* correctly done on particles.
* It used FTestCell and FTestParticle
*/
template< class ParticleClass, class CellClass, int TreeHeight>
class FTestKernels : public FAbstractKernels<ParticleClass,CellClass,TreeHeight> {
public:
/** Default destructor */
virtual ~FTestKernels(){
}
// Before upward
void P2M(CellClass* const pole, const FList<ParticleClass*>* const particles) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
// the pole represents all particles under
pole->setDataUp(particles->getSize());
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// During upward
void M2M(CellClass* const FRestrict pole, const CellClass *const FRestrict *const FRestrict child, const int ) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
// A parent represents the sum of the child
for(int idx = 0 ; idx < 8 ; ++idx){
if(child[idx]){
pole->setDataUp(pole->getDataUp() + child[idx]->getDataUp());
}
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// Before Downward
void M2L(CellClass* const FRestrict pole, const CellClass*const FRestrict *const distantNeighbors, const int size, const int ) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
// The pole is impacted by what represent other poles
for(int idx = 0 ; idx < size ; ++idx){
pole->setDataDown(pole->getDataDown() + distantNeighbors[idx]->getDataUp());
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// During Downward
void L2L(const CellClass*const FRestrict local, CellClass* FRestrict *const FRestrict child, const int) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
// Each child is impacted by the father
for(int idx = 0 ; idx < 8 ; ++idx){
if(child[idx]){
child[idx]->setDataDown(local->getDataDown() + child[idx]->getDataDown());
}
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// After Downward
void L2P(const CellClass* const local, FList<ParticleClass*>*const particles){
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
// The particles is impacted by the parent cell
typename FList<ParticleClass*>::BasicIterator iter(*particles);
while( iter.isValide() ){
iter.value()->setDataDown(iter.value()->getDataDown() + local->getDataDown());
iter.progress();
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
// After Downward
void P2P(FList<ParticleClass*>* const FRestrict targets, const FList<ParticleClass*>* const FRestrict sources,
FList<ParticleClass*>* FRestrict const* FRestrict directNeighbors, const int size) {
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
// Each particles targeted is impacted by the particles sources
long inc = sources->getSize();
if(targets == sources){
inc -= 1;
}
for(int idx = 0 ; idx < size ; ++idx){
inc += directNeighbors[idx]->getSize();
}
typename FList<ParticleClass*>::BasicIterator iter(*targets);
while( iter.isValide() ){
iter.value()->setDataDown(iter.value()->getDataDown() + inc);
iter.progress();
}
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
}
};
/** This function test the octree to be sure that the fmm algorithm
* has worked completly.
*/
template< class ParticleClass, class CellClass, template<class ParticleClass> class LeafClass, int TreeHeight, int SizeSubLevels>
void ValidateFMMAlgo(FOctree<ParticleClass, CellClass, LeafClass, TreeHeight , SizeSubLevels>* const tree){
std::cout << "Check Result\n";
int NbPart = 0;
{ // Check that each particle has been summed with all other
typename FOctree<ParticleClass, CellClass, LeafClass, TreeHeight, SizeSubLevels>::Iterator octreeIterator(tree);
octreeIterator.gotoBottomLeft();
do{
if(octreeIterator.getCurrentCell()->getDataUp() != octreeIterator.getCurrentListSrc()->getSize() ){
std::cout << "Problem P2M : " << (octreeIterator.getCurrentCell()->getDataUp() - octreeIterator.getCurrentListSrc()->getSize()) << "\n";
}
NbPart += octreeIterator.getCurrentListSrc()->getSize();
} while(octreeIterator.moveRight());
}
{ // Ceck if there is number of NbPart summed at level 1
typename FOctree<ParticleClass, CellClass, LeafClass, TreeHeight, SizeSubLevels>::Iterator octreeIterator(tree);
octreeIterator.moveDown();
long res = 0;
do{
res += octreeIterator.getCurrentCell()->getDataUp();
} while(octreeIterator.moveRight());
if(res != NbPart){
std::cout << "Problem M2M at level 1 : " << res << "\n";
}
}
{ // Ceck if there is number of NbPart summed at level 1
typename FOctree<ParticleClass, CellClass, LeafClass, TreeHeight, SizeSubLevels>::Iterator octreeIterator(tree);
octreeIterator.gotoBottomLeft();
for(int idxLevel = TreeHeight - 1 ; idxLevel > 1 ; --idxLevel ){
long res = 0;
do{
res += octreeIterator.getCurrentCell()->getDataUp();
} while(octreeIterator.moveRight());
if(res != NbPart){
std::cout << "Problem M2M at level " << idxLevel << " : " << res << "\n";
}
octreeIterator.moveUp();
octreeIterator.gotoLeft();
}
}
{ // Check that each particle has been summed with all other
typename FOctree<ParticleClass, CellClass, LeafClass, TreeHeight, SizeSubLevels>::Iterator octreeIterator(tree);
octreeIterator.gotoBottomLeft();
do{
typename FList<ParticleClass*>::BasicIterator iter(*octreeIterator.getCurrentListTargets());
const bool isUsingTsm = (octreeIterator.getCurrentListTargets() != octreeIterator.getCurrentListSrc());
while( iter.isValide() ){
// If a particles has been impacted by less than NbPart - 1 (the current particle)
// there is a problem
if( (!isUsingTsm && iter.value()->getDataDown() != NbPart - 1) ||
(isUsingTsm && iter.value()->getDataDown() != NbPart) ){
std::cout << "Problem L2P + P2P : " << iter.value()->getDataDown() << "\n";
}
iter.progress();
}
} while(octreeIterator.moveRight());