Commit 6dbb127e authored by berenger-bramas's avatar berenger-bramas
Browse files

Clean comments

Refactoring (especially the Core/FTest...)
Remove the bug of forces computation (comparing to FMB)

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@21 2616d619-271b-44dc-8df4-d4a8f33a7222
parent bc3ed3b2
......@@ -10,7 +10,7 @@
* This class is a linked list container.
* It is a very basic list to enable strong performance.
*
* Please refere to unit test flistUTest.cpp
* Please refere to unit test flistUTest.cpp to know more.
*/
template< class Object >
class FList {
......@@ -87,6 +87,7 @@ public:
/**
* Push an element in the front of the list
* @param inObject the object to insert
*/
void pushFront(Object& inObject){
Node* newNode = new Node;
......@@ -100,6 +101,7 @@ public:
/**
* Push an element in the front of the list
* used when type is pointer and like [TYPE* const] object
* @param inObject the object to insert
*/
void pushFront(Object const inObject){
Node* newNode = new Node;
......@@ -113,6 +115,7 @@ public:
/**
* To get front value (last pushed value)
* if size == 0 then defaultValue is returned
* the list is unchanged after this function
* @param defaultValue as the returned value in case size == 0, equal Object() if no param as passed
* @return first value if exists or defaultValue otherwise
*/
......@@ -124,6 +127,7 @@ public:
/**
* To get front value as const
* if size == 0 then defaultValue is return
* the list is unchanged after this function
* @param defaultValue as the returned value in case size == 0, equal Object() if no param as passed
* @return first value if exists or defaultValue otherwise
*/
......@@ -182,7 +186,7 @@ public:
BasicIterator(FList& list) : iter(list.root){
}
/** to progress on the list */
/** To progress on the list */
void progress(){
if(this->iter) this->iter = this->iter->next;
}
......@@ -213,6 +217,20 @@ public:
};
/**
* This iterator allow accessing list's elements
* If you change the target list pointed by an iterator
* you cannot used the iterator any more.
* <code>
* FList<int> values; <br>
* // inserting ... <br>
* FList<int>::ConstBasicIterator iter(values); <br>
* while( iter.isValide() ){ <br>
* iter.value() += 1; <br>
* iter.progress(); <br>
* } <br>
* </code>
*/
class ConstBasicIterator {
private:
const Node* iter; //< current node on the list
......
......@@ -4,6 +4,7 @@
#include "FSubOctree.hpp"
#include "../Utils/FGlobal.hpp"
#include "../Utils/F3DPosition.hpp"
#include "../Utils/FMath.hpp"
#include "FTreeCoordinate.hpp"
......@@ -24,21 +25,21 @@
* </code>
*
* Particules and cells has to respect the Abstract class definition.
* Particule can extend {FExtendPosition}
* Cell can extend {FExtendPosition,FExtendMortonIndex}
* Particule must extend {FExtendPosition}
* Cell must extend extend {FExtendPosition,FExtendMortonIndex}
*/
template< class ParticuleClass, class CellClass, int OctreeHeight, int SubtreeHeight = 3>
class FOctree {
const int height; //< tree height
const int leafIndex; //< index of leaf int array
const double boxWidth; //< the space system width
const FReal boxWidth; //< the space system width
const F3DPosition boxCenter; //< the space system center
const F3DPosition boxCorner; //< the space system corner (used to compute morton index)
double boxWidthAtLevel[OctreeHeight]; //< to store the width of each boxs at all levels
FReal boxWidthAtLevel[OctreeHeight]; //< to store the width of each boxs at all levels
FSubOctree< ParticuleClass, CellClass > root;//< root suboctree
FSubOctree< ParticuleClass, CellClass > root; //< root suboctree
/** Forbiden copy operator */
FOctree& operator=(const FOctree&) {
......@@ -70,9 +71,9 @@ class FOctree {
* @param inRelativePosition a position from the corner of the box
* @return the box num at the leaf level that contains inRelativePosition
*/
long getTreeCoordinate(const double inRelativePosition) const {
const double indexDouble = inRelativePosition / this->boxWidthAtLevel[this->leafIndex];
const long index = FMath::dfloor(indexDouble);
long getTreeCoordinate(const FReal inRelativePosition) const {
const FReal indexFReal = inRelativePosition / this->boxWidthAtLevel[this->leafIndex];
const long index = FMath::dfloor(indexFReal);
if( index && FMath::LookEqual(inRelativePosition, this->boxWidthAtLevel[this->leafIndex] * index ) ){
return index - 1;
}
......@@ -85,17 +86,16 @@ public:
* @param inBoxWidth box width for this simulation
* @param inBoxCenter box center for this simulation
*/
FOctree(const double inBoxWidth, const F3DPosition& inBoxCenter)
FOctree(const FReal inBoxWidth, const F3DPosition& inBoxCenter)
: boxWidth(inBoxWidth) , boxCenter(inBoxCenter), boxCorner(inBoxCenter - (inBoxWidth/2)),
height(OctreeHeight) , leafIndex(OctreeHeight-1),
root(0, 0, SubtreeHeight, 1){
double tempWidth = this->boxWidth;
FReal tempWidth = this->boxWidth;
// pre compute box width for each level
for(int indexLevel = 0; indexLevel < this->height; ++indexLevel ){
this->boxWidthAtLevel[indexLevel] = tempWidth;
tempWidth /= 2.0;
}
}
/** Desctructor */
......@@ -114,7 +114,6 @@ public:
root.insert( particuleIndex, inParticule, this->height, this->boxWidthAtLevel);
}
/**
* The class works on suboctree. Most of the resources needed
* are avaiblable by using FAbstractSubOctree. But when accessing
......@@ -128,10 +127,7 @@ public:
};
/**
* The class works on suboctree. Most of the resources needed
* are avaiblable by using FAbstractSubOctree. But when accessing
* to the leaf we have to use FSubOctree or FSubOctreeWithLeafs
* depending if we are working on the bottom of the tree.
* This class is a const SubOctreeTypes
*/
union SubOctreeTypesConst {
const FAbstractSubOctree<ParticuleClass,CellClass>* tree; //< Usual pointer to work
......@@ -217,8 +213,11 @@ public:
}
/**
* Move iterator to the top! (level 0 of root, level 1 of octree)
* index = left limit at root level
* Move iterator to the top! (level 0 of root suboctree, level 1 of octree)
* after this function : index = left limit at root level
* the Algorithm is :
* going to root suboctree
* going to the first level and most left node
*/
void gotoTop(){
while(this->current.tree->hasParent()){
......@@ -230,7 +229,10 @@ public:
/**
* Move iterator to the bottom left place
* We are on a leaf
* We are on a leaf a the most left node
* the Algorithm is :
* first go to top
* then stay on the left and go downward
*/
void gotoBottomLeft(){
gotoTop();
......@@ -246,6 +248,10 @@ public:
/**
* Move iterator to the left place at the same level
* if needed we go on another suboctree but we stay on at the same level
* the Algorithm is :
* go to top
* go downard until we are a the same level
*/
void gotoLeft(){
// Function variables
......@@ -267,7 +273,11 @@ public:
}
/**
* Move iterator to the left place at the same level
* Move iterator to the right place at the same level
* if needed we go on another suboctree but we stay on at the same level
* the Algorithm is :
* go to top
* go downard until we are a the same level
*/
void gotoRight(){
// Function variables
......@@ -307,6 +317,8 @@ public:
*
* In the second case, it meanse we need to change octree downward
* but it is easy because we can use the left limit!
*
* @return true if we succeed to go to the right, else false
*/
bool moveRight(){
// Function variables
......@@ -386,9 +398,12 @@ public:
}
return false;
}
/**
* Move to the upper level
* It may cause to change the suboctree we are working on
* but we are using the same morton index >> 3
* @return true if succeed
*/
bool moveUp() {
// It is on the top level?
......@@ -408,11 +423,13 @@ public:
}
return true;
}
/**
* Move down
* It may cause to change the suboctree we are working on
* We point on the first child found from left to right in the above
* level
* @return true if succeed
*/
bool moveDown(){
if( !isAtLeafLevel() ){
......@@ -437,7 +454,6 @@ public:
return false;
}
/**
* To know if we are not on the root level
* @return true if we can move up
......@@ -514,7 +530,7 @@ public:
};
// To be able to access octree root
// To be able to access octree root & data
friend class Iterator;
///////////////////////////////////////////////////////////////////////////
......
......@@ -2,6 +2,7 @@
#define FSUBOCTREE_HPP
// /!\ Please, you must read the license at the bottom of this page
#include "../Utils/FGlobal.hpp"
#include "../Utils/F3DPosition.hpp"
#include "../Utils/FAssertable.hpp"
#include "../Utils/FMath.hpp"
......@@ -51,9 +52,9 @@ protected:
/**
* This function compute the morton index for the last level of this suboctree.
* suppose we have an index like : 000.010.111.001.101.110
* and now considere that suboctree height is 2, the morton index have to be cut as :
* and now considere that suboctree's height is 2, the morton index have to be cut as :
* [000.010].[111.001].[101.110] each part correspond to a morton index a leaf level for the
* different suboctree.
* different suboctrees.
* This is why depending on the level of the octree we need to remove extra part on the left and
* on the right.
*/
......@@ -72,7 +73,7 @@ protected:
* when computing
* @param arrayIndex the index at the leaf index of the new element
*/
void createPreviousCells(MortonIndex arrayIndex, MortonIndex inLeafCellIndex, const double* const inBoxWidthAtLevel){
void createPreviousCells(MortonIndex arrayIndex, MortonIndex inLeafCellIndex, const FReal* const inBoxWidthAtLevel){
int indexLevel = this->subOctreeHeight - 1;
while(indexLevel >= 0 && !this->cells[indexLevel][arrayIndex]){
this->cells[indexLevel][arrayIndex] = new CellClass();
......@@ -93,7 +94,7 @@ 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 double* const inBoxWidthAtLevel){
void newLeafInserted(const long arrayIndex, const MortonIndex inLeafCellIndex, const FReal* const inBoxWidthAtLevel){
createPreviousCells(arrayIndex,inLeafCellIndex, inBoxWidthAtLevel);
// Update if this is the bottom left
if(arrayIndex < this->leftLeafIndex) this->leftLeafIndex = arrayIndex;
......@@ -157,7 +158,7 @@ public:
* @param inParticule the particule to insert (must inherite from FAbstractParticule)
* @param inParticule the inTreeHeight the height of the tree
*/
virtual void insert(const MortonIndex index, ParticuleClass* const inParticule, const int inTreeHeight, const double* const inBoxWidthAtLevel) = 0;
virtual void insert(const MortonIndex index, ParticuleClass* const inParticule, const int inTreeHeight, const FReal* const inBoxWidthAtLevel) = 0;
///////////////////////////////////////
// This is the FOctree::Iterator Part
......@@ -209,6 +210,12 @@ public:
return parent;
}
/** To get access to the parent suboctree (const version)
* @return parent */
const FAbstractSubOctree* getParent() const{
return parent;
}
/** To get the index of the current suboctree in the parent leafs array
* This index can is part of the morton index of the cells contains
* in this suboctree
......@@ -279,7 +286,7 @@ public:
/**
* Refer to FAbstractSubOctree::insert
*/
void insert(const MortonIndex index, ParticuleClass* const inParticule, const int inTreeHeight, const double* const inBoxWidthAtLevel){
void insert(const MortonIndex index, ParticuleClass* const inParticule, const int inTreeHeight, const FReal* const inBoxWidthAtLevel){
// Get the morton index for the leaf level
const MortonIndex arrayIndex = FAbstractSubOctree<ParticuleClass,CellClass>::getLeafIndex(index,inTreeHeight);
// is there already a leaf?
......@@ -291,13 +298,20 @@ public:
this->leafs[arrayIndex]->pushFront(inParticule);
}
/** To get access leafs elements
/** To get access to leafs elements
* @param index the position of the leaf
* @return the list of particules at this index */
FList<ParticuleClass*>* getLeaf(const int index){
return this->leafs[index];
}
/** To get access to leafs elements
* @param index the position of the leaf
* @return the list of particules at this index */
const FList<ParticuleClass*>* getLeaf(const int index) const {
return this->leafs[index];
}
};
......@@ -359,7 +373,7 @@ public:
/**
* Refer to FAbstractSubOctree::insert
*/
void insert(const MortonIndex index, ParticuleClass* const inParticule, const int inTreeHeight, const double* const inBoxWidthAtLevel){
void insert(const MortonIndex index, ParticuleClass* const inParticule, 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<ParticuleClass,CellClass>::getLeafIndex(index,inTreeHeight);
......@@ -388,7 +402,14 @@ public:
/** To get access to leafs elements (child suboctree)
* @param index the position of the leaf/child suboctree
* @return child at this index */
FAbstractSubOctree<ParticuleClass,CellClass>* leafs(const int index) const {
FAbstractSubOctree<ParticuleClass,CellClass>* leafs(const int index) {
return this->subleafs[index];
}
/** To get access to leafs elements (child suboctree)
* @param index the position of the leaf/child suboctree
* @return child at this index */
const FAbstractSubOctree<ParticuleClass,CellClass>* leafs(const int index) const {
return this->subleafs[index];
}
};
......
......@@ -13,171 +13,172 @@ typedef long long MortonIndex;
*
* This class represents tree coordinate. It is used to save
* the position in "box unit" (not system/space unit!).
* It is directly related to morton index
*/
class FTreeCoordinate{
private:
long x; //< x box-th position
long y; //< y box-th position
long z; //< z box-th position
long x; //< x box-th position
long y; //< y box-th position
long z; //< z box-th position
public:
/** Default constructor */
FTreeCoordinate() : x(0), y(0), z(0){
}
/** Default constructor (position = {0,0,0})*/
FTreeCoordinate() : x(0), y(0), z(0){
}
/**
/**
* Default constructor
* @param inX the x
* @param inY the y
* @param inZ the z
*/
FTreeCoordinate(const long inX,const long inY,const long inZ)
: x(inX), y(inY), z(inZ){
}
FTreeCoordinate(const long inX,const long inY,const long inZ)
: x(inX), y(inY), z(inZ){
}
/** Default destructor */
virtual ~FTreeCoordinate(){
}
/** Default destructor */
virtual ~FTreeCoordinate(){
}
/**
/**
* Copy constructor
* @param other the source class to copy
*/
FTreeCoordinate(const FTreeCoordinate& other):x(other.x), y(other.y), z(other.z){
}
FTreeCoordinate(const FTreeCoordinate& other):x(other.x), y(other.y), z(other.z){
}
/**
/**
* Copy constructor
* @param other the source class to copy
* @return this a reference to the current object
*/
FTreeCoordinate& operator=(const FTreeCoordinate& other){
this->x = other.x;
this->y = other.y;
this->z = other.z;
return *this;
}
/**
FTreeCoordinate& operator=(const FTreeCoordinate& other){
this->x = other.x;
this->y = other.y;
this->z = other.z;
return *this;
}
/**
* Position setter
* @param inX the new x
* @param inY the new y
* @param inZ the new z
*/
void setPosition(const long inX,const long inY,const long inZ){
this->x = inX;
this->y = inY;
this->z = inZ;
}
void setPosition(const long inX,const long inY,const long inZ){
this->x = inX;
this->y = inY;
this->z = inZ;
}
/**
/**
* X Getter
* @return this->x
*/
long getX() const{
return this->x;
}
long getX() const{
return this->x;
}
/**
/**
* Y Getter
* @return this->y
*/
long getY() const{
return this->y;
}
long getY() const{
return this->y;
}
/**
/**
* Z Getter
* @return this->z
*/
long getZ() const{
return this->z;
}
long getZ() const{
return this->z;
}
/**
/**
* X Setter, simply change x position
* @param the new x
*/
void setX(const long inX){
this->x = inX;
}
void setX(const long inX){
this->x = inX;
}
/**
/**
* Y Setter, simply change y position
* @param the new y
*/
void setY(const long inY){
this->y = inY;
}
void setY(const long inY){
this->y = inY;
}
/**
/**
* Z Setter, simply change z position
* @param the new z
*/
void setZ(const long inZ){
this->z = inZ;
}
void setZ(const long inZ){
this->z = inZ;
}
/**
/**
* To get the morton index of the current position
* @complexity inLevel
* @param inLevel the level of the component
* @return morton index
*/
MortonIndex getMortonIndex(const int inLevel) const{
MortonIndex index = 0x0LL;
MortonIndex mask = 0x1LL;
MortonIndex mx = this->x << 2;
MortonIndex my = this->y << 1;
MortonIndex mz = this->z;
for(int indexLevel = 0; indexLevel < inLevel ; ++indexLevel){
index |= (mz & mask);
mask <<= 1;
index |= (my & mask);
mask <<= 1;
index |= (mx & mask);
mask <<= 1;
mz <<= 2;
my <<= 2;
mx <<= 2;
}
return index;
}
/** This function set the position of the current object using a morton index
MortonIndex getMortonIndex(const int inLevel) const{
MortonIndex index = 0x0LL;
MortonIndex mask = 0x1LL;
// the ordre is xyz.xyz...
MortonIndex mx = this->x << 2;
MortonIndex my = this->y << 1;
MortonIndex mz = this->z;
for(int indexLevel = 0; indexLevel < inLevel ; ++indexLevel){
index |= (mz & mask);
mask <<= 1;
index |= (my & mask);
mask <<= 1;
index |= (mx & mask);
mask <<= 1;
mz <<= 2;
my <<= 2;
mx <<= 2;
}
return index;
}
/** This function set the position of the current object using a morton index
* @param inIndex the morton index to compute position
* @param the level of the morton index
*/
void setPositionFromMorton(MortonIndex inIndex, const int inLevel){
MortonIndex mask = 0x1LL;
void setPositionFromMorton(MortonIndex inIndex, const int inLevel){
MortonIndex mask = 0x1LL;
this->x = 0;
this->y = 0;
this->z = 0;
this->x = 0;
this->y = 0;
this->z = 0;
for(int indexLevel = 0; indexLevel < inLevel ; ++indexLevel){
z |= (inIndex & mask);
inIndex >>= 1;
y |= (inIndex & mask);
inIndex >>= 1;
x |= (inIndex & mask);
mask <<= 1;
}
for(int indexLevel = 0; indexLevel < inLevel ; ++indexLevel){
z |= (inIndex & mask);
inIndex >>= 1;
y |= (inIndex & mask);
inIndex >>= 1;
x |= (inIndex & mask);
mask <<= 1;
}