Commit 319afac6 authored by BRAMAS Berenger's avatar BRAMAS Berenger

update arrange and vector and movers

parent 35007f67
// ===================================================================================
// 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 FAbstractMover{
public:
virtual void getParticlePosition(ParticleClass* lf, const int idxPart, FPoint* particlePos) = 0;
virtual void removeFromLeafAndKeep(ParticleClass* lf, const FPoint& particlePos, const int idxPart) = 0;
virtual void insertAllParticles(OctreeClass* tree) = 0;
};
#endif //FABSTRACTLEAFINTERFACE_HPP
......@@ -23,18 +23,6 @@
template <class OctreeClass, class ContainerClass, class LeafInterface >
class FArrangerPeriodic : public FOctreeArranger<OctreeClass,ContainerClass,LeafInterface>{
public:
FArrangerPeriodic(OctreeClass * octree) : FOctreeArranger<OctreeClass,ContainerClass,LeafInterface>(octree){
}
// To put in inhereed class
void checkPosition(FPoint& particlePos) override {
particlePos.setX( getPeriodicPos( particlePos.getX(), DirMinusX, DirPlusX, (this->MaxBox).getX(),(this->MinBox).getX(),DirX));
particlePos.setY( getPeriodicPos( particlePos.getY(), DirMinusY, DirPlusY, (this->MaxBox).getY(),(this->MinBox).getY(),DirY));
particlePos.setZ( getPeriodicPos( particlePos.getZ(), DirMinusZ, DirPlusZ, (this->MaxBox).getZ(),(this->MinBox).getZ(),DirZ));
}
FReal getPeriodicPos(FReal pos, PeriodicCondition periodicPlus, PeriodicCondition periodicMinus,FReal maxDir,FReal minDir,const int dir){
FReal res = pos;
if( TestPeriodicCondition(dir, periodicPlus) ){
......@@ -50,6 +38,18 @@ public:
}
return res;
}
public:
FArrangerPeriodic(OctreeClass * octree) : FOctreeArranger<OctreeClass,ContainerClass,LeafInterface>(octree){
}
// To put in inhereed class
void checkPosition(FPoint& particlePos) override {
particlePos.setX( getPeriodicPos( particlePos.getX(), DirMinusX, DirPlusX, (this->MaxBox).getX(),(this->MinBox).getX(),DirX));
particlePos.setY( getPeriodicPos( particlePos.getY(), DirMinusY, DirPlusY, (this->MaxBox).getY(),(this->MinBox).getY(),DirY));
particlePos.setZ( getPeriodicPos( particlePos.getZ(), DirMinusZ, DirPlusZ, (this->MaxBox).getZ(),(this->MinBox).getZ(),DirZ));
}
};
......
......@@ -37,7 +37,7 @@
* to move the particles in the tree instead of building a new
* tree.
*/
template <class OctreeClass, class ContainerClass, class LeafInterface >
template <class OctreeClass, class ContainerClass, class MoverClass >
class FOctreeArranger {
OctreeClass* const tree; //< The tree to work on
......@@ -45,16 +45,16 @@ public:
FReal boxWidth;
FPoint MinBox;
FPoint MaxBox;
LeafInterface * interface;
MoverClass* interface;
public:
/** Basic constructor */
FOctreeArranger(OctreeClass* const inTree) : tree(inTree), boxWidth(tree->getBoxWidth()),
explicit FOctreeArranger(OctreeClass* const inTree) : tree(inTree), boxWidth(tree->getBoxWidth()),
MinBox(tree->getBoxCenter(),-tree->getBoxWidth()/2),
MaxBox(tree->getBoxCenter(),tree->getBoxWidth()/2),
interface(){
interface(nullptr){
FAssertLF(tree, "Tree cannot be null" );
interface = new LeafInterface();
interface = new MoverClass;
}
virtual ~FOctreeArranger(){
......@@ -77,7 +77,7 @@ public:
ContainerClass * particles = octreeIterator.getCurrentLeaf()->getSrc();
for(int idxPart = 0 ; idxPart < particles->getNbParticles(); /*++idxPart*/){
FPoint currentPart;
interface->getParticlePosition(particles,idxPart,currentPart);
interface->getParticlePosition(particles,idxPart,&currentPart);
checkPosition(currentPart);
const MortonIndex particuleIndex = tree->getMortonFromPosition(currentPart);
if(particuleIndex != currentMortonIndex){
......@@ -90,8 +90,10 @@ public:
}
}
}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);
......@@ -111,142 +113,6 @@ public:
} while( workOnNext );
}
}
/** 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
......@@ -134,7 +134,7 @@ public:
// Copy elements
ObjectType* const nextArray = reinterpret_cast< ObjectType* >( inCapacity ? new char[sizeof(ObjectType) * inCapacity] : nullptr);
for(int idx = 0 ; idx < index ; ++idx){
new((void*)&nextArray[idx]) ObjectType(array[idx]);
new((void*)&nextArray[idx]) ObjectType(std::move(array[idx]));
(&array[idx])->~ObjectType();
}
delete [] reinterpret_cast< char* >(array);
......@@ -144,6 +144,21 @@ public:
}
}
/** Resize the vector (and change the capacity if needed) */
void resize(const int newSize){
if(index < newSize){
if(capacity < newSize){
setCapacity(int(newSize*1.5));
}
while(index != newSize){
new((void*)&array[index]) ObjectType();
}
}
else{
index = newSize;
}
}
/**
* @return Last inserted object
......@@ -277,6 +292,14 @@ public:
index += inSize;
}
/** Remove a values by shifting all the next values */
void removeOne(const int idxToRemove){
for(int idxMove = idxToRemove + 1; idxMove < index ; ++idxMove){
array[idxMove - 1] = array[idxMove];
}
index -= 1;
}
/** This class is a basic iterator
* <code>
* typename FVector<int>::ConstBasicIterator iter(myVector);<br>
......
......@@ -23,6 +23,9 @@ class FP2PParticleContainer : public FBasicParticleContainer<NVALS*(NRHS+4*NLHS)
typedef FBasicParticleContainer<NVALS*(NRHS+4*NLHS)> Parent;
public:
static const int NbAttributes = NVALS*(NRHS+4*NLHS);
typedef FReal AttributesClass;
FReal* getPhysicalValues(const int idxVals = 0, const int idxRhs = 0){
return Parent::getAttribute((0+idxRhs)*NVALS+idxVals);
}
......
......@@ -43,6 +43,36 @@ public:
const FVector<int>& getIndexes() const{
return indexes;
}
void clear(){
indexes.clear();
Parent::clear();
}
void removeParticles(const int indexesToRemove[], const int nbParticlesToRemove){
if(nbParticlesToRemove == 0 || indexesToRemove == nullptr){
return;
}
int offset = 1;
int idxIndexes = 1;
int idxIns = indexesToRemove[0] + 1;
for( ; idxIns < indexes.getSize() && idxIndexes < nbParticlesToRemove ; ++idxIns){
if( idxIns == indexesToRemove[idxIndexes] ){
idxIndexes += 1;
offset += 1;
}
else{
indexes[idxIns-offset] = indexes[idxIns];
}
}
for( ; idxIns < indexes.getSize() ; ++idxIns){
indexes[idxIns-offset] = indexes[idxIns];
}
indexes.resize(indexes.getSize()-nbParticlesToRemove);
Parent::removeParticles(indexesToRemove, nbParticlesToRemove);
}
};
#endif // FP2PPARTICLECONTAINERINDEXED_HPP
......@@ -31,7 +31,7 @@
#include "../../Src/Components/FBasicParticleContainer.hpp"
#include "../../Src/Components/FBasicCell.hpp"
#include "../../Src/Kernels/P2P/FP2PLeafInterface.hpp"
#include "../../Src/Arranger/FBasicParticleContainerIndexedMover.hpp"
#include "../../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "../../Src/Arranger/FOctreeArranger.hpp"
......@@ -53,7 +53,8 @@ int main(int argc, char ** argv){
typedef FSimpleLeaf< ContainerClass > LeafClass;
typedef FOctree< CellClass, ContainerClass , LeafClass > OctreeClass;
typedef FOctreeArranger<OctreeClass,ContainerClass,FP2PLeafInterface<OctreeClass>> ArrangerClass;
typedef FBasicParticleContainerIndexedMover<OctreeClass, ContainerClass> MoverClass;
typedef FOctreeArranger<OctreeClass, ContainerClass, MoverClass> ArrangerClass;
///////////////////////What we do/////////////////////////////
std::cout << ">> This executable has to be used to test the FMM algorithm.\n";
......
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