Attention une mise à jour du serveur va être effectuée le vendredi 16 avril entre 12h et 12h30. Cette mise à jour va générer une interruption du service de quelques minutes.

Commit 2e5564a4 authored by berenger-bramas's avatar berenger-bramas

Now store the Tree Coordinate on the cells

and avoid computation when needed (especially for the M2L)

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@109 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 70f110b2
......@@ -21,50 +21,62 @@
*/
class FAbstractCell{
public:
/** Default destructor */
virtual ~FAbstractCell(){
}
/** Default destructor */
virtual ~FAbstractCell(){
}
/**
/**
* Must be implemented by each user Cell class
* @return the position of the current cell
*/
virtual MortonIndex getMortonIndex() const = 0;
* @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;
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;
virtual void setPosition(const F3DPosition& inPosition) = 0;
/** Because the system can run in Tsm mode
/**
* Must be implemented by each user Cell class
* @return the position in the tree coordinate
*/
virtual const F3DPosition& getCoordinate() const = 0;
/**
* Must be implemented by each user Cell class
* @param the position in the tree coordinate
*/
virtual void setCoordinate(const long inX, const long inY, const long inZ) = 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;
virtual bool hasSrcChild() const = 0;
/** Because the system can run in Tsm mode
/** 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;
virtual bool hasTargetsChild() const = 0;
/**
/**
* This function make the cell containing sources
*/
virtual void setSrcChildTrue() = 0;
virtual void setSrcChildTrue() = 0;
/**
/**
* This function make the cell containing targets
*/
virtual void setTargetsChildTrue() = 0;
virtual void setTargetsChildTrue() = 0;
};
......
......@@ -4,6 +4,7 @@
#include "../Extensions/FExtendPosition.hpp"
#include "../Extensions/FExtendMortonIndex.hpp"
#include "../Extensions/FExtendCoordinate.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
......@@ -16,7 +17,7 @@
* By using this extension it will implement the FAbstractCell without
* inheriting from it.
*/
class FBasicCell : public FExtendPosition, public FExtendMortonIndex {
class FBasicCell : public FExtendPosition, public FExtendMortonIndex, public FExtendCoordinate {
public:
/** Default destructor */
virtual ~FBasicCell(){
......
......@@ -58,14 +58,14 @@ class FOctree {
* @param inPosition position to compute
* @return the morton index
*/
MortonIndex getLeafMortonFromPosition(const F3DPosition& inPosition) const {
FTreeCoordinate getCoordinateFromPosition(const F3DPosition& inPosition) const {
// box coordinate to host the particle
FTreeCoordinate host;
// position has to be relative to corner not center
host.setX( getTreeCoordinate( inPosition.getX() - this->boxCorner.getX() ));
host.setY( getTreeCoordinate( inPosition.getY() - this->boxCorner.getY() ));
host.setZ( getTreeCoordinate( inPosition.getZ() - this->boxCorner.getZ() ));
return host.getMortonIndex(leafIndex);
return host;
}
/**
......@@ -121,8 +121,9 @@ public:
* @param inParticle the particle to insert (must inherite from FAbstractParticle)
*/
void insert(const ParticleClass& inParticle){
const MortonIndex particleIndex = getLeafMortonFromPosition( inParticle.getPosition() );
root.insert( particleIndex, inParticle, this->height, this->boxWidthAtLevel);
const FTreeCoordinate host = getCoordinateFromPosition( inParticle.getPosition() );
const MortonIndex particleIndex = host.getMortonIndex(leafIndex);
root.insert( particleIndex, host, inParticle, this->height, this->boxWidthAtLevel);
}
/**
......@@ -666,19 +667,6 @@ public:
return &workingTree.tree->cellsAt(levelInTree)[treeLeafMask & inIndex];
}
/** This function fill an array with the distant neighbors of a cell
* @param inNeighbors the array to store the elements
* @param inIndex the index of the element we want the neighbors
* @param inLevel the level of the element
* @return the number of neighbors
*/
int getDistantNeighbors(const CellClass* inNeighbors[208],
FTreeCoordinate& inCurrentPosition, FTreeCoordinate inNeighborsPosition[208],
const MortonIndex inIndex, const int inLevel) const{
MortonIndex inNeighborsIndex[208];
return getDistantNeighborsWithIndex(inNeighbors, inNeighborsIndex, inCurrentPosition, inNeighborsPosition, inIndex, inLevel);
}
/** This function fill an array with the distant neighbors of a cell
* @param inNeighbors the array to store the elements
......@@ -687,7 +675,7 @@ public:
* @param inLevel the level of the element
* @return the number of neighbors
*/
int getDistantNeighborsWithIndex(const CellClass* inNeighbors[208], MortonIndex inNeighborsIndex[208],
int getDistantNeighbors(const CellClass* inNeighbors[208],
FTreeCoordinate& inCurrentPosition, FTreeCoordinate inNeighborsPosition[208],
const MortonIndex inIndex, const int inLevel) const{
......@@ -733,7 +721,6 @@ public:
FMath::Abs(workingCell.getY() - potentialNeighbor.getY()) > 1 ||
FMath::Abs(workingCell.getZ() - potentialNeighbor.getZ()) > 1){
// add to neighbors
inNeighborsIndex[idxNeighbors] = mortonOther | idxCousin;
inNeighbors[idxNeighbors] = cells[idxCousin];
inNeighborsPosition[idxNeighbors] = FTreeCoordinate((other.getX()<<1) | (idxCousin>>2 & 1),
(other.getY()<<1) | (idxCousin>>1 & 1),
......
......@@ -76,16 +76,26 @@ protected:
* when computing
* @param arrayIndex the index at the leaf index of the new element
*/
void createPreviousCells(MortonIndex arrayIndex, MortonIndex inLeafCellIndex, const FReal* const inBoxWidthAtLevel){
void createPreviousCells(MortonIndex arrayIndex, MortonIndex inLeafCellIndex, const FTreeCoordinate& treePosition, const FReal* const inBoxWidthAtLevel){
int indexLevel = this->subOctreeHeight - 1;
int bottomToTop = 0;
while(indexLevel >= 0 && !this->cells[indexLevel][arrayIndex]){
this->cells[indexLevel][arrayIndex] = new CellClass();
this->cells[indexLevel][arrayIndex]->setMortonIndex(inLeafCellIndex);
this->cells[indexLevel][arrayIndex]->setCoordinate(treePosition.getX() >> bottomToTop,
treePosition.getY() >> bottomToTop,
treePosition.getZ() >> bottomToTop);
const int realLevel = indexLevel + this->getSubOctreePosition();
this->cells[indexLevel][arrayIndex]->setPosition(FConvert::MortonToPosition(inLeafCellIndex,realLevel,inBoxWidthAtLevel[realLevel]));
const FReal widthAtLevel = inBoxWidthAtLevel[realLevel];
this->cells[indexLevel][arrayIndex]->setPosition(F3DPosition(
treePosition.getX() * widthAtLevel + widthAtLevel/2.0,
treePosition.getY() * widthAtLevel + widthAtLevel/2.0,
treePosition.getZ() * widthAtLevel + widthAtLevel/2.0));
--indexLevel;
++bottomToTop;
arrayIndex >>= 3;
inLeafCellIndex >>= 3;
......@@ -97,8 +107,8 @@ protected:
* for example it updates the leaf array marges and calls createPreviousCells()
* @param arrayIndex the position of the new leaf in the leafs array
*/
void newLeafInserted(const long arrayIndex, const MortonIndex inLeafCellIndex, const FReal* const inBoxWidthAtLevel){
createPreviousCells(arrayIndex,inLeafCellIndex, inBoxWidthAtLevel);
void newLeafInserted(const long arrayIndex, const MortonIndex inLeafCellIndex, const FTreeCoordinate& host, const FReal* const inBoxWidthAtLevel){
createPreviousCells(arrayIndex,inLeafCellIndex, host, inBoxWidthAtLevel);
// Update if this is the bottom left
if(arrayIndex < this->leftLeafIndex) this->leftLeafIndex = arrayIndex;
if(arrayIndex > this->rightLeafIndex) this->rightLeafIndex = arrayIndex;
......@@ -166,7 +176,7 @@ public:
* @param inParticle the particle to insert (must inherite from FAbstractParticle)
* @param inParticle the inTreeHeight the height of the tree
*/
virtual void insert(const MortonIndex index, const ParticleClass& inParticle, const int inTreeHeight, const FReal* const inBoxWidthAtLevel) = 0;
virtual void insert(const MortonIndex index, const FTreeCoordinate& host, const ParticleClass& inParticle, const int inTreeHeight, const FReal* const inBoxWidthAtLevel) = 0;
///////////////////////////////////////
// This is the FOctree::Iterator Part
......@@ -307,13 +317,19 @@ public:
/**
* Refer to FAbstractSubOctree::insert
*/
void insert(const MortonIndex index, const ParticleClass& inParticle, const int inTreeHeight, const FReal* const inBoxWidthAtLevel){
void insert(const MortonIndex index, const FTreeCoordinate& host, const ParticleClass& inParticle, const int inTreeHeight, const FReal* const inBoxWidthAtLevel){
// Get the morton index for the leaf level
const MortonIndex arrayIndex = FAbstractSubOctree<ParticleClass,CellClass,LeafClass>::getLeafIndex(index,inTreeHeight);
// is there already a leaf?
if( !this->leafs[arrayIndex] ){
this->leafs[arrayIndex] = new LeafClass<ParticleClass>();
FAbstractSubOctree<ParticleClass,CellClass,LeafClass>::newLeafInserted( arrayIndex , index, inBoxWidthAtLevel);
const FTreeCoordinate hostAtLevel(
host.getX() >> (inTreeHeight - (this->subOctreeHeight + this->subOctreePosition) ),
host.getY() >> (inTreeHeight - (this->subOctreeHeight + this->subOctreePosition) ),
host.getZ() >> (inTreeHeight - (this->subOctreeHeight + this->subOctreePosition) ));
FAbstractSubOctree<ParticleClass,CellClass,LeafClass>::newLeafInserted( arrayIndex , index, hostAtLevel, inBoxWidthAtLevel);
}
// add particle to leaf list
this->leafs[arrayIndex]->push(inParticle);
......@@ -416,7 +432,7 @@ public:
/**
* Refer to FAbstractSubOctree::insert
*/
void insert(const MortonIndex index, const ParticleClass& inParticle, const int inTreeHeight, const FReal* const inBoxWidthAtLevel){
void insert(const MortonIndex index, const FTreeCoordinate& host, const ParticleClass& inParticle, const int inTreeHeight, const FReal* const inBoxWidthAtLevel){
// We need the morton index at the bottom level of this sub octree
// so we remove the right side
const MortonIndex arrayIndex = FAbstractSubOctree<ParticleClass,CellClass,LeafClass>::getLeafIndex(index,inTreeHeight);
......@@ -436,10 +452,10 @@ public:
}
// We need to inform parent class
FAbstractSubOctree<ParticleClass,CellClass,LeafClass>::newLeafInserted( arrayIndex, index >> (3 * (inTreeHeight-nextSubOctreePosition) ), inBoxWidthAtLevel);
FAbstractSubOctree<ParticleClass,CellClass,LeafClass>::newLeafInserted( arrayIndex, index >> (3 * (inTreeHeight-nextSubOctreePosition) ), host, inBoxWidthAtLevel);
}
// Ask next suboctree to insert the particle
this->subleafs[arrayIndex]->insert( index, inParticle, inTreeHeight, inBoxWidthAtLevel);
this->subleafs[arrayIndex]->insert( index, host, inParticle, inTreeHeight, inBoxWidthAtLevel);
}
/** To get access to leafs elements (child suboctree)
......
......@@ -232,9 +232,9 @@ public:
kernels->L2P(octreeIterator.getCurrentCell(), octreeIterator.getCurrentListTargets());
FDEBUG(computationCounterL2P.tac());
// need the current particles and neighbors particles
const int counter = tree->getLeafsNeighborsWithIndex(neighbors,neighborsIndex, octreeIterator.getCurrentGlobalIndex(),heightMinusOne);
const int counter = tree->getLeafsNeighborsWithIndex(neighbors, neighborsIndex, octreeIterator.getCurrentGlobalIndex(),heightMinusOne);
FDEBUG(computationCounterP2P.tic());
kernels->P2P(octreeIterator.getCurrentGlobalIndex(),octreeIterator.getCurrentListTargets(), octreeIterator.getCurrentListSrc() , neighbors, neighborsIndex,counter);
kernels->P2P(octreeIterator.getCurrentGlobalIndex(),octreeIterator.getCurrentListTargets(), octreeIterator.getCurrentListSrc() , neighbors, neighborsIndex, counter);
FDEBUG(computationCounterP2P.tac());
} while(octreeIterator.moveRight());
......
......@@ -88,7 +88,7 @@ public:
for(int idxShape = 0 ; idxShape < SizeShape ; ++idxShape){
this->shapeLeaf[idxShape] = 0;
}
const int LeafIndex = OctreeHeight - 1;
//const int LeafIndex = OctreeHeight - 1;
// Count leaf
leafsNumber = 0;
......@@ -96,9 +96,9 @@ public:
octreeIterator.gotoBottomLeft();
do{
++leafsNumber;
const MortonIndex index = octreeIterator.getCurrentGlobalIndex();
FTreeCoordinate coord;
coord.setPositionFromMorton(index, LeafIndex);
const FTreeCoordinate& coord = octreeIterator.getCurrentCell()->getCoordinate();
//const MortonIndex index = octreeIterator.getCurrentGlobalIndex();
//coord.setPositionFromMorton(index, LeafIndex);
++this->shapeLeaf[(coord.getX()%3)*9 + (coord.getY()%3)*3 + (coord.getZ()%3)];
} while(octreeIterator.moveRight());
......
......@@ -516,7 +516,6 @@ public:
#pragma omp parallel
{
const CellClass* neighbors[208];
MortonIndex neighborsIndexes[208];
FTreeCoordinate currentPosition;
FTreeCoordinate neighborsPosition[208];
......@@ -530,13 +529,13 @@ public:
#pragma omp for //schedule(dynamic)
for(int idxCell = startIdx ; idxCell < endIdx ; ++idxCell){
const int neighborsCounter = tree->getDistantNeighborsWithIndex(neighbors, neighborsIndexes, currentPosition, neighborsPosition,iterArray[idxCell].getCurrentGlobalIndex(),idxLevel);
const int neighborsCounter = tree->getDistantNeighbors(neighbors, currentPosition, neighborsPosition, iterArray[idxCell].getCurrentGlobalIndex(),idxLevel);
bool needData = false;
for(int idxNeighbor = 0 ; idxNeighbor < neighborsCounter ; ++idxNeighbor){
// Get Morton index from this neigbor cell
const MortonIndex indexCell = neighborsIndexes[idxNeighbor];
const MortonIndex indexCell = neighbors[idxNeighbor]->getMortonIndex();
// Is this cell out of our interval?
if(indexCell < startIdxIndex || endIdxIndex < indexCell){
FDEBUG(findCounter.tic());
......@@ -845,9 +844,10 @@ public:
for(int idxLeaf = this->leafLeft ; idxLeaf <= this->leafRight ; ++idxLeaf){
iterArray[idxLeaf] = octreeIterator;
const MortonIndex index = octreeIterator.getCurrentGlobalIndex();
FTreeCoordinate coord;
coord.setPositionFromMorton(index, LeafIndex);
//const MortonIndex index = octreeIterator.getCurrentGlobalIndex();
//FTreeCoordinate coord;
//coord.setPositionFromMorton(index, LeafIndex);
const FTreeCoordinate& coord = octreeIterator.getCurrentCell()->getCoordinate();
const int shape = (coord.getX()%3)*9 + (coord.getY()%3)*3 + (coord.getZ()%3);
shapeType[idxLeaf-this->leafLeft] = shape;
++shapeLeaf[shape];
......
#ifndef FEXTENDCOORDINATE_HPP
#define FEXTENDCOORDINATE_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "../Utils/FGlobal.hpp"
#include "../Containers/FTreeCoordinate.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
* @class FExtendCoordinate
* Please read the license
* This class is an extenssion.
* It proposes a mortonIndex.
*/
class FExtendCoordinate {
protected:
FTreeCoordinate coordinate; //< The position
public:
/** Default constructor */
FExtendCoordinate() {
}
/** Copy constructor */
FExtendCoordinate(const FExtendCoordinate& other) : coordinate(other.coordinate) {
}
/** Destructor */
virtual ~FExtendCoordinate(){
}
/** Copy operator */
FExtendCoordinate& operator=(const FExtendCoordinate& other) {
this->coordinate = other.coordinate;
return *this;
}
/** To get the position */
const FTreeCoordinate& getCoordinate() const {
return this->coordinate;
}
/** To set the position */
void setCoordinate(const FTreeCoordinate& inCoordinate) {
this->coordinate = inCoordinate;
}
/** To set the position from 3 FReals */
void setCoordinate(const long inX, const long inY, const long inZ) {
this->coordinate.setX(inX);
this->coordinate.setY(inY);
this->coordinate.setZ(inZ);
}
};
#endif //FEXTENDCOORDINATE_HPP
// [--LICENSE--]
......@@ -1271,9 +1271,7 @@ public:
iterTarget.data().setForces( iterTarget.data().getForces() + force_vector_tmp );
FReal potential;
expansion_Evaluate_local_with_Y_already_computed(local->getLocal(),&potential);
iterTarget.data().setPotential(potential);
iterTarget.data().setPotential(expansion_Evaluate_local_with_Y_already_computed(local->getLocal()));
/*printf("[END] fx = %e \t fy = %e \t fz = %e \n\n",
iterTarget.data()->getForces().getX(),iterTarget.data()->getForces().getY(),iterTarget.data()->getForces().getZ());*/
......@@ -1285,8 +1283,7 @@ public:
}
void expansion_Evaluate_local_with_Y_already_computed(const FComplexe* local_exp,
FReal* const p_result){
FReal expansion_Evaluate_local_with_Y_already_computed(const FComplexe* local_exp){
FTRACE( FTrace::Controller.enterFunction(FTrace::KERNELS, __FUNCTION__ , __FILE__ , __LINE__) );
FReal result = 0.0;
......@@ -1310,9 +1307,8 @@ public:
}
}
*p_result = result;
FTRACE( FTrace::Controller.leaveFunction(FTrace::KERNELS) );
return result;
}
///////////////////////////////////////////////////////////////////////////////
......
......@@ -14,24 +14,7 @@
*/
class FConvert {
public :
/** To get spatial position (F3DPosition) from morton data
* @param inIndex the morton index of the object
* @param inLevel the level of the current object
* @param inWidthAtLevel the width of the box at this level
* return outPosition the result
*/
static F3DPosition MortonToPosition(const MortonIndex inIndex, const int inLevel, const FReal inWidthAtLevel){
FTreeCoordinate treePosition;
treePosition.setPositionFromMorton(inIndex, inLevel);
F3DPosition outPosition(
treePosition.getX() * inWidthAtLevel + inWidthAtLevel/2,
treePosition.getY() * inWidthAtLevel + inWidthAtLevel/2,
treePosition.getZ() * inWidthAtLevel + inWidthAtLevel/2
);
return outPosition;
}
};
......
......@@ -205,11 +205,10 @@ int main(int argc, char ** argv){
}
const FBasicCell* neighbors[208];
MortonIndex neighborsIndexes[208];
FTreeCoordinate currentPosition;
FTreeCoordinate neighborsPosition[208];
M2LCalculusAtLevel[idxArray] += tree.getDistantNeighborsWithIndex(neighbors, neighborsIndexes, currentPosition, neighborsPosition, octreeIterator.getCurrentGlobalIndex(),idxLevel);
M2LCalculusAtLevel[idxArray] += tree.getDistantNeighbors(neighbors, currentPosition, neighborsPosition, octreeIterator.getCurrentGlobalIndex(),idxLevel);
} while(octreeIterator.moveRight());
......
......@@ -24,7 +24,7 @@ class TestConvert : public FUTester<TestConvert> {
void ConvertMorton(){
{
const FTreeCoordinate pos(0,1,10);
const F3DPosition posReal = FConvert::MortonToPosition(pos.getMortonIndex(5),5,10.0);
const F3DPosition posReal;// = FConvert::MortonToPosition(pos.getMortonIndex(5),5,10.0);
assert( FMath::LookEqual(posReal.getX(),FReal(5.0)) );
assert( FMath::LookEqual(posReal.getY(),FReal(15.0)) );
assert( FMath::LookEqual(posReal.getZ(),FReal(105.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