Commit c4324bf8 authored by PIACIBELLO Cyrille's avatar PIACIBELLO Cyrille

Changes in FOctree Arranger some classes and interfaces added : PROBLEM :...

Changes in FOctree Arranger some classes and interfaces added : PROBLEM : memory leak probably in removeleaf routine
parent 4e9ef4c8
// ===================================================================================
// 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 FABSTRACTLEAFINTERFACE_HPP
#define FABSTRACTLEAFINTERFACE_HPP
template<class OctreeClass,class ParticleClass>
class FAbstractLeafInterface{
public:
// virtual FPoint getParticlePosition(ParticleClass* lf, const int idxPart) = 0;
virtual void getParticlePosition(ParticleClass* lf, const int idxPart, FPoint& newPos) = 0;
virtual void removeFromLeafAndKeep(ParticleClass* lf, const int idxPart) = 0;
virtual void insertAllParticles(OctreeClass* tree) = 0;
};
#endif //FABSTRACTLEAFINTERFACE_HPP
......@@ -22,12 +22,13 @@
#include "../Utils/FAssert.hpp"
#include "../Utils/FGlobalPeriodic.hpp"
#include "../Utils/FAssert.hpp"
/**
* This example show how to use the FOctreeArranger.
* @example testOctreeRearrange.cpp
*/
/**
* @brief This class is an arranger, it moves the particles that need to be hosted in a different leaf.
*
......@@ -36,118 +37,61 @@
* to move the particles in the tree instead of building a new
* tree.
*/
template <class OctreeClass, class ContainerClass, class ParticleClass, class ConverterClass >
template <class OctreeClass, class ContainerClass, class LeafInterface >
class FOctreeArranger {
OctreeClass* const tree; //< The tree to work on
FReal boxWidth;
FPoint min;
FPoint max;
LeafInterface * interface;
public:
/** Basic constructor */
FOctreeArranger(OctreeClass* const inTree) : tree(inTree) {
FOctreeArranger(OctreeClass* const inTree) : tree(inTree), boxWidth(tree->getBoxWidth()),
min(tree->getBoxCenter(),-tree->getBoxWidth()/2),
max(tree->getBoxCenter(),tree->getBoxWidth()/2),
interface(){
FAssertLF(tree, "Tree cannot be null" );
}
interface = new LeafInterface();
}
/** Arrange */
void rearrange(const int isPeriodic = DirNone){
// This vector is to keep the moving particles
FVector<ParticleClass> tomove;
virtual ~FOctreeArranger(){
delete interface;
}
// For periodic
const FReal boxWidth = tree->getBoxWidth();
const FPoint min(tree->getBoxCenter(),-boxWidth/2);
const FPoint max(tree->getBoxCenter(),boxWidth/2);
virtual void checkPosition(const FPoint& particlePos){
// Assert
FAssertLF( min.getX() < particlePos.getX() && max.getX() > particlePos.getX()
&& min.getY() < particlePos.getY() && max.getY() > particlePos.getY()
&& min.getZ() < particlePos.getZ() && max.getZ() > particlePos.getZ());
}
{ // iterate on the leafs and found particle to remove
FVector<int> indexesToExtract;
typename OctreeClass::Iterator octreeIterator(tree);
octreeIterator.gotoBottomLeft();
do{
const MortonIndex currentIndex = octreeIterator.getCurrentGlobalIndex();
ContainerClass* particles = octreeIterator.getCurrentLeaf()->getSrc();
//IdxPart is incremented at the end of the loop
for(int idxPart = 0 ; idxPart < particles->getNbParticles(); /*++idxPart*/){
FPoint partPos( particles->getPositions()[0][idxPart],
particles->getPositions()[1][idxPart],
particles->getPositions()[2][idxPart] );
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
if( TestPeriodicCondition(isPeriodic, DirPlusX) ){
while(partPos.getX() >= max.getX()){
partPos.incX(-boxWidth);
}
}
else if(partPos.getX() >= max.getX()){
printf("Error, particle out of Box in +X, index %lld\n", currentIndex);
printf("Application is exiting...\n");
}
if( TestPeriodicCondition(isPeriodic, DirMinusX) ){
while(partPos.getX() < min.getX()){
partPos.incX(boxWidth);
}
}
else if(partPos.getX() < min.getX()){
printf("Error, particle out of Box in -X, index %lld\n", currentIndex);
printf("Application is exiting...\n");
}
// YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
if( TestPeriodicCondition(isPeriodic, DirPlusY) ){
while(partPos.getY() >= max.getY()){
partPos.incY(-boxWidth);
}
}
else if(partPos.getY() >= max.getY()){
printf("Error, particle out of Box in +Y, index %lld\n", currentIndex);
printf("Application is exiting...\n");
}
if( TestPeriodicCondition(isPeriodic, DirMinusY) ){
while(partPos.getY() < min.getY()){
partPos.incY(boxWidth);
}
}
else if(partPos.getY() < min.getY()){
printf("Error, particle out of Box in -Y, index %lld\n", currentIndex);
printf("Application is exiting...\n");
}
// ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
if( TestPeriodicCondition(isPeriodic, DirPlusX) ){
while(partPos.getZ() >= max.getZ()){
partPos.incZ(-boxWidth);
}
}
else if(partPos.getZ() >= max.getZ()){
printf("Error, particle out of Box in +Z, index %lld\n", currentIndex);
printf("Application is exiting...\n");
}
if( TestPeriodicCondition(isPeriodic, DirMinusX) ){
while(partPos.getZ() < min.getZ()){
partPos.incZ(boxWidth);
}
}
else if(partPos.getZ() < min.getZ()){
printf("Error, particle out of Box in -Z, index %lld\n", currentIndex);
printf("Application is exiting...\n");
}
// set pos
particles->getWPositions()[0][idxPart] = partPos.getX();
particles->getWPositions()[1][idxPart] = partPos.getY();
particles->getWPositions()[2][idxPart] = partPos.getZ();
const MortonIndex particuleIndex = tree->getMortonFromPosition(partPos);
if(particuleIndex != currentIndex){
tomove.push(ConverterClass::GetParticleAndRemove(particles,idxPart));
//No need to increment idxPart, since the array has been staggered
}
else{
idxPart++;
}
void rearrange(){
typename OctreeClass::Iterator octreeIterator(tree);
octreeIterator.gotoBottomLeft();
do{
const MortonIndex currentMortonIndex = octreeIterator.getCurrentGlobalIndex();
ContainerClass * particles = octreeIterator.getCurrentLeaf()->getSrc();
for(int idxPart = 0 ; idxPart < particles->getNbParticles(); /*++idxPart*/){
FPoint currentPart;
interface->getParticlePosition(particles,idxPart,currentPart);
checkPosition(currentPart);
const MortonIndex particuleIndex = tree->getMortonFromPosition(currentPart);
if(particuleIndex != currentMortonIndex){
//Need to move this one
interface->removeFromLeafAndKeep(particles,idxPart);
}
else{
//Need to increment idx;
++idxPart;
}
} while(octreeIterator.moveRight());
}
{ // insert particles that moved
for(int idxPart = 0 ; idxPart < tomove.getSize() ; ++idxPart){
ConverterClass::Insert( tree , tomove[idxPart]);
}
}
}while(octreeIterator.moveRight());
//Insert back the parts that have been removed
interface->insertAllParticles(tree);
//Then, remove the empty leaves
{ // Remove empty leaves
typename OctreeClass::Iterator octreeIterator(tree);
......@@ -168,6 +112,141 @@ public:
}
}
/** Arrange */
// void rearrange_old(const int isPeriodic = DirNone){
// // This vector is to keep the moving particles
// FVector<ConverterClass::ParticleClass> tomove;
// // For periodic
// const FReal boxWidth = tree->getBoxWidth();
// const FPoint min(tree->getBoxCenter(),-boxWidth/2);
// const FPoint max(tree->getBoxCenter(),boxWidth/2);
// { // iterate on the leafs and found particle to remove
// FVector<int> indexesToExtract;
// typename OctreeClass::Iterator octreeIterator(tree);
// octreeIterator.gotoBottomLeft();
// do{
// const MortonIndex currentIndex = octreeIterator.getCurrentGlobalIndex();
// ContainerClass* particles = octreeIterator.getCurrentLeaf()->getSrc();
// //IdxPart is incremented at the end of the loop
// for(int idxPart = 0 ; idxPart < particles->getNbParticles(); /*++idxPart*/){
// FPoint partPos( particles->getPositions()[0][idxPart],
// particles->getPositions()[1][idxPart],
// particles->getPositions()[2][idxPart] );
// // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// bool isOut = false;
// if( TestPeriodicCondition(isPeriodic, DirPlusX) ){
// while(partPos.getX() >= max.getX()){
// partPos.incX(-boxWidth);
// }
// }
// else if(partPos.getX() >= max.getX()){
// printf("Error, particle out of Box in +X, index %lld\n", currentIndex);
// printf("Application is exiting...\n");
// isOut = true;
// }
// if( TestPeriodicCondition(isPeriodic, DirMinusX) ){
// while(partPos.getX() < min.getX()){
// partPos.incX(boxWidth);
// }
// }
// else if(partPos.getX() < min.getX()){
// printf("Error, particle out of Box in -X, index %lld\n", currentIndex);
// printf("Application is exiting...\n");
// isOut = true;
// }
// // YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
// if( TestPeriodicCondition(isPeriodic, DirPlusY) ){
// while(partPos.getY() >= max.getY()){
// partPos.incY(-boxWidth);
// }
// }
// else if(partPos.getY() >= max.getY()){
// printf("Error, particle out of Box in +Y, index %lld\n", currentIndex);
// printf("Application is exiting...\n");
// isOut = true;
// }
// if( TestPeriodicCondition(isPeriodic, DirMinusY) ){
// while(partPos.getY() < min.getY()){
// partPos.incY(boxWidth);
// }
// }
// else if(partPos.getY() < min.getY()){
// printf("Error, particle out of Box in -Y, index %lld\n", currentIndex);
// printf("Application is exiting...\n");
// isOut = true;
// }
// // ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
// if( TestPeriodicCondition(isPeriodic, DirPlusX) ){
// while(partPos.getZ() >= max.getZ()){
// partPos.incZ(-boxWidth);
// }
// }
// else if(partPos.getZ() >= max.getZ()){
// printf("Error, particle out of Box in +Z, index %lld\n", currentIndex);
// printf("Application is exiting...\n");
// isOut = true;
// }
// if( TestPeriodicCondition(isPeriodic, DirMinusX) ){
// while(partPos.getZ() < min.getZ()){
// partPos.incZ(boxWidth);
// }
// }
// else if(partPos.getZ() < min.getZ()){
// printf("Error, particle out of Box in -Z, index %lld\n", currentIndex);
// printf("Application is exiting...\n");
// isOut = true;
// }
// // set pos
// particles->getWPositions()[0][idxPart] = partPos.getX();
// particles->getWPositions()[1][idxPart] = partPos.getY();
// particles->getWPositions()[2][idxPart] = partPos.getZ();
// if(!isOut){
// const MortonIndex particuleIndex = tree->getMortonFromPosition(partPos);
// if(particuleIndex != currentIndex){
// tomove.push(ConverterClass::GetParticleAndRemove(particles,idxPart));
// //No need to increment idxPart, since the array has been staggered
// }
// else{
// idxPart++;
// }
// }
// else{//Particle is out of box, will be handle by Insert.
// tomove.push(ConverterClass::GetParticleAndRemove(particles,idxPart));
// }
// }
// } while(octreeIterator.moveRight());
// }
// { // insert particles that moved
// for(int idxPart = 0 ; idxPart < tomove.getSize() ; ++idxPart){
// ConverterClass::Insert( tree , tomove[idxPart]);
// }
// }
// { // Remove empty leaves
// typename OctreeClass::Iterator octreeIterator(tree);
// octreeIterator.gotoBottomLeft();
// bool workOnNext = true;
// do{
// // Empty leaf
// if( octreeIterator.getCurrentListTargets()->getNbParticles() == 0 ){
// const MortonIndex currentIndex = octreeIterator.getCurrentGlobalIndex();
// workOnNext = octreeIterator.moveRight();
// tree->removeLeaf( currentIndex );
// }
// // Not empty, just continue
// else {
// workOnNext = octreeIterator.moveRight();
// }
// } while( workOnNext );
// }
// }
};
#endif // FOCTREEARRANGER_HPP
// ===================================================================================
// 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 FP2PLEAFINTERFACE_HPP
#define FP2PLEAFINTERFACE_HPP
#include "Arranger/FAbstractLeafInterface.hpp"
#include "Components/FBasicParticleContainer.hpp"
#include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"
template<class OctreeClass>
class FP2PLeafInterface : public FAbstractLeafInterface<OctreeClass,FP2PParticleContainerIndexed<> >{
private:
typedef FP2PParticleContainerIndexed<> ContainerClass;
ContainerClass * toStoreRemovedParts;
FVector<int> indexes;
public:
FP2PLeafInterface() : toStoreRemovedParts(),indexes(0){
toStoreRemovedParts = new ContainerClass();
}
virtual ~FP2PLeafInterface(){
indexes.clear();
delete toStoreRemovedParts;
}
void getParticlePosition(ContainerClass* lf,const int idxPart, FPoint& newPos){
newPos = FPoint(lf->getPositions()[0][idxPart],lf->getPositions()[1][idxPart],lf->getPositions()[2][idxPart]);
}
void removeFromLeafAndKeep(ContainerClass* lf, const int idxPart){
//Store index
indexes.push(lf->getIndexes()[idxPart]);
//Store particles attributes
toStoreRemovedParts->push(FPoint(lf->getPositions()[0][idxPart],lf->getPositions()[1][idxPart],lf->getPositions()[2][idxPart]),
idxPart,
lf->getPhysicalValues()[idxPart],
lf->getForcesX()[idxPart],lf->getForcesY()[idxPart],lf->getForcesZ()[idxPart]);
lf->removeParticles(&idxPart,1);
}
//Easy one use insert(std::array)
void insertAllParticles(OctreeClass* tree){
for(int idxToInsert = 0; idxToInsert<toStoreRemovedParts->getNbParticles() ; ++idxToInsert){
tree->insert(FPoint(toStoreRemovedParts->getPositions()[0][idxToInsert],
toStoreRemovedParts->getPositions()[1][idxToInsert],
toStoreRemovedParts->getPositions()[2][idxToInsert]),
indexes[idxToInsert],
toStoreRemovedParts->getPhysicalValues()[idxToInsert],
toStoreRemovedParts->getForcesX()[idxToInsert],
toStoreRemovedParts->getForcesY()[idxToInsert],
toStoreRemovedParts->getForcesZ()[idxToInsert]);
}
toStoreRemovedParts->clear();
}
};
#endif //FP2PLEAFINTERFACE_HPP
......@@ -4,13 +4,13 @@
// 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.
//
// 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.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
......@@ -31,37 +31,13 @@
#include "../../Src/Components/FBasicParticleContainer.hpp"
#include "../../Src/Components/FBasicCell.hpp"
#include "../../Src/Kernels/P2P/FP2PLeafInterface.hpp"
#include "../../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "../../Src/Arranger/FOctreeArranger.hpp"
#include "../../Src/Utils/FParameterNames.hpp"
struct TestParticle{
FPoint position;
const FPoint& getPosition(){
return position;
}
};
template <class ParticleClass>
class Converter {
public:
template <class ContainerClass>
static ParticleClass GetParticleAndRemove(ContainerClass* container, const int idxExtract){
TestParticle part;
part.position.setPosition(
container->getPositions()[0][idxExtract],
container->getPositions()[1][idxExtract],
container->getPositions()[2][idxExtract]);
container->removeParticles(&idxExtract, 1);
return part;
}
template <class OctreeClass>
static void Insert(OctreeClass* tree, const ParticleClass& part){
tree->insert(part.position);
}
};
// Simply create particles and try the kernels
int main(int argc, char ** argv){
......@@ -72,11 +48,13 @@ int main(int argc, char ** argv){
FParameterDefinitions::OctreeSubHeight);
typedef FBasicCell CellClass;
typedef FBasicParticleContainer<0> ContainerClass;
typedef FP2PParticleContainerIndexed<> ContainerClass;
typedef FSimpleLeaf< ContainerClass > LeafClass;
typedef FOctree< CellClass, ContainerClass , LeafClass > OctreeClass;
typedef FOctreeArranger<OctreeClass,ContainerClass,FP2PLeafInterface<OctreeClass>> ArrangerClass;
///////////////////////What we do/////////////////////////////
std::cout << ">> This executable has to be used to test the FMM algorithm.\n";
//////////////////////////////////////////////////////////////
......@@ -113,7 +91,7 @@ int main(int argc, char ** argv){
(BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2)),
(BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2)),
(BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2)));
tree.insert(particleToFill);
tree.insert(particleToFill,idxPart);
}
}
......@@ -122,42 +100,46 @@ int main(int argc, char ** argv){
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
ArrangerClass arrange(&tree);
std::cout << "Working on particles ..." << std::endl;
counter.tic();
// In order to test multiple displacement of particles
// for(int ite=0 ; ite<10 ; ++ite){
std::cout << "Working on particles ..." << std::endl;
counter.tic();
{ // Create new position for each particles
OctreeClass::Iterator octreeIterator(&tree);
octreeIterator.gotoBottomLeft();
do{
ContainerClass* particles = octreeIterator.getCurrentListTargets();
for(int idxPart = 0; idxPart < particles->getNbParticles() ; ++idxPart){
particles->getWPositions()[0][idxPart] = (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2));
particles->getWPositions()[1][idxPart] = (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2));
particles->getWPositions()[2][idxPart] = (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2));
}
} while(octreeIterator.moveRight());
}
{ // Create new position for each particles
OctreeClass::Iterator octreeIterator(&tree);
octreeIterator.gotoBottomLeft();
do{
ContainerClass* particles = octreeIterator.getCurrentListTargets();
for(int idxPart = 0; idxPart < particles->getNbParticles() ; ++idxPart){
particles->getWPositions()[0][idxPart] = (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2));
particles->getWPositions()[1][idxPart] = (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2));
particles->getWPositions()[2][idxPart] = (BoxWidth*FReal(drand48())) + (BoxCenter-(BoxWidth/2));
}
} while(octreeIterator.moveRight());
}
counter.tac();
std::cout << "Done " << "(@Moving = " << counter.elapsed() << "s)." << std::endl;
counter.tac();
std::cout << "Done " << "(@Moving = " << counter.elapsed() << "s)." << std::endl;
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
std::cout << "Arrange ..." << std::endl;
counter.tic();
std::cout << "Arrange ..." << std::endl;
counter.tic();
FOctreeArranger<OctreeClass, ContainerClass, TestParticle, Converter<TestParticle> > arrange(&tree);
arrange.rearrange();
//FOctreeArranger<OctreeClass, ContainerClass, TestParticle, Converter<TestParticle> > arrange(&tree);
arrange.rearrange();
counter.tac();
std::cout << "Done " << "(@Arrange = " << counter.elapsed() << "s)." << std::endl;
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
counter.tac();
std::cout << "Done " << "(@Arrange = " << counter.elapsed() << "s)." << std::endl;
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
// }
std::cout << "Test ..." << std::endl;
counter.tic();
......@@ -228,6 +210,3 @@ int main(int argc, char ** argv){
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment