Commit b2b63e05 authored by Quentin Khan's avatar Quentin Khan
parents c5d7579b f0b9809d
......@@ -200,6 +200,10 @@ public:
void * getUserKernelDatas(){
return userData;
}
//Getter
Scalfmm_Kernel_Descriptor getKernelFct() const {
return kernel;
}
void M2L_Extended(CellClass * src, CellClass * tgt, const FTreeCoordinate transfer, const int level){
if(kernel.m2l_ext){
......@@ -456,74 +460,77 @@ public:
*
*/
void internal_M2L(){
if(upperLimit > 1){ // if upperLimit == 1, then, M2L has been
// done at level 2, and hence all the far
// field has been calculated.
//Starting at the lower level where the M2L has not been done.
typename OctreeClass::Iterator octreeIterator(octree); //lvl : 1
while(octreeIterator.level() != upperLimit){
octreeIterator.moveDown();
}
if(this->kernel->getKernelFct().m2l_ext){
if(upperLimit > 1){ // if upperLimit == 1, then, M2L has been
// done at level 2, and hence all the far
// field has been calculated.
//Starting at the lower level where the M2L has not been done.
typename OctreeClass::Iterator octreeIterator(octree); //lvl : 1
while(octreeIterator.level() != upperLimit){
octreeIterator.moveDown();
}
//I'm at the upperLimit, so the lowest level where M2L has been done.
do{
CoreCell * currentTgt = octreeIterator.getCurrentCell(); // This one is targeted
//Then, we get the interaction list at this lvl. This will provide us with lots of source cells.
const CoreCell * currentInteractionList[343];
//Get an iterator for the sources
typename OctreeClass::Iterator upAndDownIterator = octreeIterator;
{//This is supposed to be done for multiple level. You
//need to go up until level 2. And then, to go down
//until level upperLimit. I think it's possible ...
while(upAndDownIterator.level() >= 2){
upAndDownIterator.moveUp();
//There, we get the interaction list of all parents of tgt cell
const int nbInteract = octree->getInteractionNeighbors(currentInteractionList,
upAndDownIterator.getCurrentGlobalCoordinate(),
upAndDownIterator.level());
int currentLevel = upAndDownIterator.level();
if(nbInteract){
//Then, we do M2L for each child at level upperLimit of each 343 Interaction cells.
for(int idxSrc = 0; idxSrc < 343 ; ++idxSrc){
if(currentInteractionList[idxSrc]){//Check if it exist
const CoreCell * currentSource = currentInteractionList[idxSrc]; //For clarity, will be otpimised out, anyway
MortonIndex idx = currentSource->getMortonIndex();
//At this point, we instanciate
//the number of child needed.
//This only depends on diffenrence
//between current level and
//upperLimit level
int totalNumberOfChild = FMath::pow(8,upperLimit-currentLevel);
for(int idxChildSrc = 0; idxChildSrc < totalNumberOfChild ; ++idxChildSrc){//For all 8^{number of levels to down} children
MortonIndex indexOfChild = ((idx << 3*(upperLimit-currentLevel))+idxChildSrc);
CoreCell * src = octree->getCell(indexOfChild,upperLimit); //Get the cell
if(src){//check if it exists
FTreeCoordinate srcCoord = src->getCoordinate();
FTreeCoordinate tgtCoord = currentTgt->getCoordinate();
//Build tree coord translation vector
FTreeCoordinate transfer;
transfer.setPosition(tgtCoord.getX()-srcCoord.getX(),
tgtCoord.getY()-srcCoord.getY(),
tgtCoord.getZ()-srcCoord.getZ());
kernel->M2L_Extended(src,currentTgt,transfer,octreeIterator.level());
//I'm at the upperLimit, so the lowest level where M2L has been done.
do{
CoreCell * currentTgt = octreeIterator.getCurrentCell(); // This one is targeted
//Then, we get the interaction list at this lvl. This will provide us with lots of source cells.
const CoreCell * currentInteractionList[343];
//Get an iterator for the sources
typename OctreeClass::Iterator upAndDownIterator = octreeIterator;
{//This is supposed to be done for multiple level. You
//need to go up until level 2. And then, to go down
//until level upperLimit. I think it's possible ...
while(upAndDownIterator.level() >= 2){
upAndDownIterator.moveUp();
//There, we get the interaction list of all parents of tgt cell
const int nbInteract = octree->getInteractionNeighbors(currentInteractionList,
upAndDownIterator.getCurrentGlobalCoordinate(),
upAndDownIterator.level());
int currentLevel = upAndDownIterator.level();
if(nbInteract){
//Then, we do M2L for each child at level upperLimit of each 343 Interaction cells.
for(int idxSrc = 0; idxSrc < 343 ; ++idxSrc){
if(currentInteractionList[idxSrc]){//Check if it exist
const CoreCell * currentSource = currentInteractionList[idxSrc]; //For clarity, will be otpimised out, anyway
MortonIndex idx = currentSource->getMortonIndex();
//At this point, we instanciate
//the number of child needed.
//This only depends on diffenrence
//between current level and
//upperLimit level
int totalNumberOfChild = FMath::pow(8,upperLimit-currentLevel);
for(int idxChildSrc = 0; idxChildSrc < totalNumberOfChild ; ++idxChildSrc){//For all 8^{number of levels to down} children
MortonIndex indexOfChild = ((idx << 3*(upperLimit-currentLevel))+idxChildSrc);
CoreCell * src = octree->getCell(indexOfChild,upperLimit); //Get the cell
if(src){//check if it exists
FTreeCoordinate srcCoord = src->getCoordinate();
FTreeCoordinate tgtCoord = currentTgt->getCoordinate();
//Build tree coord translation vector
FTreeCoordinate transfer;
transfer.setPosition(tgtCoord.getX()-srcCoord.getX(),
tgtCoord.getY()-srcCoord.getY(),
tgtCoord.getZ()-srcCoord.getZ());
kernel->M2L_Extended(src,currentTgt,transfer,octreeIterator.level());
}
}
}
}
}
}
}
}
}while(octreeIterator.moveRight());
}
else{
FAssertLF("No reasons to be there, seriously ...\nExiting anyway...");
}while(octreeIterator.moveRight());
}
else{
FAssertLF("No reasons to be there, seriously ...\nExiting anyway...");
}
}
}
void execute_fmm(){
......@@ -570,7 +577,6 @@ public:
}
if (FScalFMMEngine<FReal>::Algorithm != 2){
if(upperLimit != 2){
printf("At least I'm here\n");
abstrct->execute(FFmmP2M | FFmmM2M | FFmmM2L, upperLimit, treeHeight);
printf("\tUpPass finished\n");
internal_M2L();
......
......@@ -297,7 +297,7 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_SOURCE_DIR}/CMakeModules/morse/")
else()
message(WARNING "BLAS has not been found, SCALFMM will continue to compile but some applications will be disabled.")
message(WARNING "If you have BLAS set BLAS_LIBDIR, BLAS_INCDIR or BLAS_DIR (CMake variables using -D or environment variables).")
set(SCALFMM_USE_FFT OFF)
set(SCALFMM_USE_BLAS OFF)
endif()
endif(SCALFMM_USE_BLAS)
......
......@@ -32,7 +32,7 @@ PROJECT_NAME = ScalFmm
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = @ScalFMM_MAJOR_VERSION@.@ScalFMM_MINOR_VERSION@
PROJECT_NUMBER = @SCALFMM_MAJOR_VERSION@.@SCALFMM_MINOR_VERSION@
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
......
......@@ -73,7 +73,7 @@ int main(int argc, char* argv[])
FParameterDefinitions::NbThreads);
const std::string defaultFile(/*SCALFMMDataPath+*/"Data/unitCubeXYZQ100.bfma" );
const std::string defaultFile(SCALFMMDataPath+"unitCubeXYZQ100.bfma" );
const std::string filename = FParameters::getStr(argc,argv,FParameterDefinitions::InputFile.options, defaultFile.c_str());
const unsigned int TreeHeight = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeHeight.options, 5);
const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, FParameterDefinitions::OctreeSubHeight.options, 2);
......@@ -258,7 +258,14 @@ int main(int argc, char* argv[])
writer.writeArrayOfReal(particles, 8 , NbPoints);
delete[] particles;
//
std::string name1( "output.fma");
//
FFmaGenericWriter<FReal> writer1(name1) ;
writer1.writeDistributionOfParticlesFromOctree(&tree,NbPoints) ;
}
return 0;
}
......@@ -233,7 +233,7 @@ protected:
* \brief Main costzone algorithm.
*
* Moves through the tree in-order and assigns each cell to a zone. When a
* zone's cumulative cost is too high, the new cells are insterted in the
* zone's cumulative cost is too high, the new cells are inserted in the
* next one.
*/
void costzones() {
......@@ -374,7 +374,7 @@ protected:
/**
* \brief Computes and stores the leaves' total cost.
*
* The tree itertor (#_it) is moved to the bottom level of the
* The tree iterator (#_it) is moved to the bottom level of the
* tree by this method. After the method returns, the iterator is left at
* the rightmost leaf.
*/
......@@ -397,7 +397,7 @@ protected:
* \brief Computes and stores the internal cells' total cost.
* \warning This method makes use of
*
* The tree itertor (#_it) is moved to the bottom level of the
* The tree iterator (#_it) is moved to the bottom level of the
* tree by this method. After the method returns, the iterator is left at
* the rightmost leaf.
*/
......
......@@ -91,6 +91,7 @@ class FFmmAlgorithmThreadBalanced : public FAbstractAlgorithm, public FAlgorithm
/// The vector containing the internal costzones
const std::vector<std::vector<ZoneBoundClass>>& costzones;
/// The vector containing the leaf level costzones
const std::vector<std::vector<ZoneBoundClass>>& leafcostzones;
......@@ -160,7 +161,7 @@ protected:
/**
* \brief Runs the complete algorithm.
*
* \param operationsToProceed A flag combinaison to specifiy the operators
* \param operationsToProceed A flag combinaison to specify the operators
* to use. See FFmmOperations in FCoreCommon.hpp.
*/
void executeCore(const unsigned operationsToProceed) override {
......@@ -216,7 +217,7 @@ protected:
The zones are calculated sequentially, we use the same iterator and
save it's position when we change zone.
*/
for( std::vector<ZoneBoundClass> zone : leafcostzones ) {
for( std::vector<ZoneBoundClass> zone : costzones ) {
int nbCells = 0;
for( ZoneBoundClass bounds : zone ) {
nbCells += bounds.second;
......@@ -225,8 +226,8 @@ protected:
iterVector.push_back(
std::pair<TreeIterator,int>(
octreeIterator, // Iterator to the current cell
nbCells)); // Cell count in zone
nbCells) // Cell count in zone
);
// Move iterator to end of zone (which is the first of the next zone)
for( int idx = 0; idx < nbCells; idx++) {
octreeIterator.moveRight();
......@@ -240,15 +241,15 @@ protected:
const int threadIdx = omp_get_thread_num();
KernelClass * const myThreadkernels = kernels[threadIdx];
TreeIterator zoneIterator = iterVector.at(threadIdx).first;
int zoneCellCount = iterVector[threadIdx].second;
int zoneCellCount = iterVector[threadIdx].second;
// Call P2M on cells
while ( zoneCellCount-- > 0 ) {
myThreadkernels->P2M(zoneIterator.getCurrentCell(), // Cell
zoneIterator.getCurrentListSrc()); // Particles
zoneIterator.getCurrentListSrc()); // Particles
zoneIterator.moveRight();
}
}
} // barrier
FLOG( computationCounter.tac() );
......
......@@ -22,7 +22,7 @@
#include "FTreeCoordinate.hpp"
#include "FBlockAllocator.hpp"
#include "../Utils/FLog.hpp"
#include "Utils/FLog.hpp"
#include "../Utils/FGlobal.hpp"
#include "../Utils/FGlobalPeriodic.hpp"
#include "../Utils/FPoint.hpp"
......@@ -54,6 +54,13 @@
*/
template<class FReal, class CellClass, class ContainerClass, class LeafClass, class CellAllocatorClass = FBasicBlockAllocator<CellClass> /*FListBlockAllocator<CellClass, 15>*/ >
class FOctree : public FNoCopyable {
public:
using FRealType = FReal;
using CellClassType = CellClass;
using ContainerClassType = ContainerClass;
using LeafClassType = LeafClass; //< The type of the Leaf used in the Octree
protected:
typedef FOctree<FReal, CellClass , ContainerClass, LeafClass, CellAllocatorClass> OctreeType;
typedef FSubOctreeWithLeafs<FReal, CellClass , ContainerClass, LeafClass, CellAllocatorClass> SubOctreeWithLeaves;
typedef FSubOctree<FReal, CellClass , ContainerClass, LeafClass, CellAllocatorClass> SubOctree;
......@@ -73,7 +80,7 @@ class FOctree : public FNoCopyable {
/**
* Get morton index from a position for the leaf leavel
* Get morton index from a position for the leaf level
* @param inPosition position to compute
* @return the morton index
*/
......@@ -175,7 +182,7 @@ public:
* algorithm is :
* Compute morton index for the particle
* ask node to insert this particle
* @param inParticle the particle to insert (must inherite from FAbstractParticle)
* @param inParticle the particle to insert (must inherit from FAbstractParticle)
*/
template<typename... Args>
void insert(const FPoint<FReal>& inParticlePosition, Args... args){
......@@ -249,7 +256,7 @@ public:
/**
* This has to be used to iterate on an octree
* It simply stores an pointer on a suboctree and moves to right/left/up/down.
* Please refere to testOctreeIter file to see how it works.
* Please refer to testOctreeIter file to see how it works.
*
* @code
* FOctree<TestParticle, TestCell, NbLevels, NbSubLevels>::Iterator octreeIterator(&tree); <br>
......@@ -362,7 +369,7 @@ public:
* 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
* go downward until we are a the same level
*/
void gotoLeft(){
// Function variables
......@@ -388,7 +395,7 @@ public:
* 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
* go downward until we are a the same level
*/
void gotoRight(){
// Function variables
......@@ -426,7 +433,7 @@ public:
* until : the current level if we did not have change the current suboctree
* or : the leaf level
*
* In the second case, it meanse we need to change octree downward
* In the second case, it means 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
......@@ -629,7 +636,7 @@ public:
/** Gets the children of the current cell.
*
* This function return an array of 8 CellClass. To konw whether
* This function return an array of 8 CellClass. To know whether
* a child cell exists or not, the pointer must be checked.
*
* @return the 8-child array.
......@@ -647,7 +654,7 @@ public:
/** Gets the children of the current cell.
*
* This function return an array of 8 CellClass. To konw whether
* This function return an array of 8 CellClass. To know whether
* a child cell exists or not, the pointer must be checked.
*
* @return the 8-child array.
......@@ -691,7 +698,7 @@ public:
/** This function return a cell (if it exists) from a morton index and a level
* @param inIndex the index of the desired cell
* @param inLevel the level of the desired cell (cannot be infered from the index)
* @param inLevel the level of the desired cell (cannot be inferred from the index)
* @return the cell if it exist or null (0)
* This function starts from the root until it find a missing cell or the right cell
*/
......@@ -766,10 +773,10 @@ public:
}
/** This function return an adresse of cell array from a morton index and a level
/** This function return an address of cell array from a morton index and a level
*
* @param inIndex the index of the desired cell array has to contains
* @param inLevel the level of the desired cell (cannot be infered from the index)
* @param inLevel the level of the desired cell (cannot be inferred from the index)
* @return the cell if it exist or null (0)
*
*/
......@@ -865,7 +872,7 @@ public:
}
/** This function fills an array with all the neighbors of a cell,
* i.e. childs of parent's neighbors, direct neighbors and cell itself.
* i.e. Child of parent's neighbors, direct neighbors and cell itself.
* This is called for instance when the nearfield also needs to be approximated
* in that cas we only call this function at the leaf level.
* @param inNeighbors the array to store the elements
......@@ -1033,7 +1040,7 @@ public:
/** This function return a cell (if it exists) from a morton index and a level
* @param inIndex the index of the desired cell
* @param inLevel the level of the desired cell (cannot be infered from the index)
* @param inLevel the level of the desired cell (cannot be inferred from the index)
* @return the cell if it exist or null (0)
*
*/
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the FMM.
//
......@@ -323,6 +323,7 @@ protected:
octreeIterator.gotoBottomLeft();
// for each leafs
// Coloring all the cells
do{
const FTreeCoordinate& coord = octreeIterator.getCurrentGlobalCoordinate();
const int shapePosition = (coord.getX()%3)*9 + (coord.getY()%3)*3 + (coord.getZ()%3);
......@@ -337,7 +338,8 @@ protected:
const FSize nbLeaf = shapes[idxShape].getSize();
for(int iterLeaf = 0 ; iterLeaf < nbLeaf ; ++iterLeaf ){
typename OctreeClass::Iterator toWork = shapes[idxShape][iterLeaf];
#pragma omp task firstprivate(neighbors, toWork)
// ToDO increase the granularity of the task
#pragma omp task firstprivate(neighbors,toWork)
{
const int counter = tree->getLeafsNeighbors(neighbors, toWork.getCurrentGlobalCoordinate(),heightMinusOne);
kernels[omp_get_thread_num()]->P2P(toWork.getCurrentGlobalCoordinate(), toWork.getCurrentListTargets(),
......
......@@ -30,6 +30,7 @@
#include "FAbstractLoader.hpp"
#include "Utils/FPoint.hpp"
#include "Containers/FOctree.hpp"
/** \brief Particle class used in FMA loader and writer.
......@@ -775,6 +776,55 @@ public:
}
}
/**
* Write all particles inside the octree
*
* @param tree Octree that contains the particles in the leaves
* @param N number of particles
*
* example
* \code
* OctreeClass tree(TreeHeight, SubTreeHeight, BoxWidth, CenterOfBox);
* ...
* FFmaGenericWriter<FReal> writer(filenameOut) ;
* Fwriter.writeHeader(Centre,BoxWith, nbParticles,*particles) ;
* Fwriter.writeDistributionOfParticlesFromOctree(&tree, nbParticles);
* \endcode
*/
template <class Toctree>
void writeDistributionOfParticlesFromOctree( Toctree *tree, const FSize N){
//
this->writeHeader(tree->getBoxCenter(),tree->getBoxWidth(), N, sizeof(FReal), 4 );
FReal * particles ;
FSize nbMaxParticlesInLeaf = 0 ;
tree->forEachLeaf([&]( typename Toctree::LeafClassType* leaf){
//
// Input
const FReal*const posX = leaf->getTargets()->getPositions()[0];
const FReal*const posY = leaf->getTargets()->getPositions()[1];
const FReal*const posZ = leaf->getTargets()->getPositions()[2];
const FReal*const physicalValues = leaf->getTargets()->getPhysicalValues();
//
const FSize nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
if (nbParticlesInLeaf > nbMaxParticlesInLeaf ) {
nbMaxParticlesInLeaf = nbParticlesInLeaf ;
particles = new FReal[4*nbMaxParticlesInLeaf] ;
}
//
for(FSize idxPart = 0 , j = 0; idxPart < nbParticlesInLeaf ; ++idxPart, j+=4){
particles[j] = posX[idxPart] ;
particles[j+1] = posY[idxPart] ;
particles[j+2] = posZ[idxPart] ;
particles[j+3] = physicalValues[idxPart] ;
}
this-> writeArrayOfReal(particles, 4, nbParticlesInLeaf) ;
});
delete [] particles ;
}
private:
void writerAscciHeader( const FPoint<FReal> &centerOfBox,const FReal &boxWidth,
const FSize &nbParticles, const unsigned int *typeFReal) {
......@@ -803,107 +853,6 @@ private:
//$ \class FmaR4W4Particle
//$
//$ \brief Basic Particle class used in FMA loader and writer
//$
//$ Here we consider only the position and the physical value in the structure
//$ We read (R4) and write (W4) the four values: the position, the physical value.
//$ This class is used in the generateDistributions example.
//$
// class FmaR4W4Particle {
// public:
// FPoint<FReal> position; ///< position of the particle
// FReal physicalValue; ///< its physical value
// /**
// * return a pointer on the first value of the structure
// */
// FReal * getPtrFirstData()
// {return position.getDataValue() ;}
// const FReal * getPtrFirstData() const
// {return position.getDataValue() ;}
// /**
// * return The number of data to read. it is used in FMAGenericLoader (here 4)
// */
// FSize getReadDataNumber()
// { return 4;}
// /**
// * return The number of data to write. it is used in FMAGenericWriter (here 4)
// */
// FSize getWriteDataNumber() const
// { return 4;}
// /**
// * return size in byte of the structure. it is used in FMAGenericWriter
// */
// FSize getWriteDataSize() const
// { return sizeof(FmaR4W4Particle);}
// };
//$ \class FmaR4W8Particle
//$
//$ \brief The Particle class used in FMA loader and writer
//$
//$ In this class we consider the position, the physical value, the potential and the force in the structure
//$ but we read (R4) only the four first values: the position and the physical value and we write (W8) all the data (8 values) in a file.
//$ This class can be used if you read a file generated by generateDistributions and you want to store the result of a direct computations or a FFM one..
//$
// class FmaR4W8Particle {
// public:
// FPoint<FReal> position; ///< position of the particle
// FReal physicalValue; ///< its physical value (mass or charge
// FReal potential; ///< the potential
// FReal forces[3]; ///<the force
// /**
// * return a pointer on the first value of the structure
// */
// FReal * getPtrFirstData()
// {return position.getDataValue() ;}
// const FReal * getPtrFirstData() const
// {return position.getDataValue() ;}
// /**
// * return The number of data to read. it is used in FMAGenericLoader (here 4)
// */
// FSize getReadDataNumber()
// { return 4;}
// /**
// * return The number of data to write. it is used in FMAGenericWriter (here 8)
// */
// FSize getWriteDataNumber() const
// { return 8;}
// /**
// * return size in byte of the structure. it is used in FMAGenericWriter
// */
// FSize getWriteDataSize() const
// { return sizeof(FmaR4W8Particle);}
// };
//
//$ \class FmaR8W8Particle
//$
//$ \brief The Particle class used in FMA loader and writer
//$
//$ Same as FmaR4W8Particle class but here we want to read (R8) all the data (8 values) and want to store also all the data.
//$ This class is used if you create an array of particles from a file generate by a previous computation (directComputation or a FMM computation)
//$ and you want to compare your result with the read values .
// class FmaR8W8Particle : public FmaR4W8Particle {
// public:
// /**
// * return The number of data to read. it is used in FMAGenericLoader (here 8)
// * Useful to read the result of the output of DirectComputation and to compare the potential and the force
// * with the FMM computation
// */
// FSize getReadDataNumber()
// { return 8;}
// };
//\typedef FmaBasicParticle an alias of FmaR4W4Particle
// Particle contains 4 values of type FReal and we read and write the four values
//
#endif //FFmaGenericLoader_HPP
This diff is collapsed.
This diff is collapsed.
......@@ -25,7 +25,6 @@ class FGroupOfParticles {
MortonIndex startingIndex;
MortonIndex endingIndex;
int numberOfLeavesInBlock;
int blockIndexesTableSize;
//< The real number of particles allocated
FSize nbParticlesAllocatedInGroup;
......@@ -41,6 +40,7 @@ class FGroupOfParticles {
/** Information about a leaf */
struct alignas(FStarPUDefaultAlign::StructAlign) LeafHeader {
MortonIndex mindex;
FSize nbParticles;
size_t offSet;
};
......@@ -60,9 +60,6 @@ protected:
return nbParticles + (MemoryAlignementParticles - (nbParticles%MemoryAlignementParticles));
}
//< This value is for not used leaves
static const int LeafIsEmptyFlag = -1;
//< The size of memoryBuffer in byte
size_t allocatedMemoryInByte;
//< Pointer to a block memory
......@@ -70,8 +67,6 @@ protected:
//< Pointer to the header inside the block memory
BlockHeader* blockHeader;
//< Pointer to the indexes table inside the block memory
int* blockIndexesTable;
//< Pointer to leaves information
LeafHeader* leafHeader;
//< The total number of particles in the group
......@@ -96,13 +91,11 @@ public:
FGroupOfParticles(unsigned char* inBuffer, const size_t inAllocatedMemoryInByte,
unsigned char* inAttributes)
: allocatedMemoryInByte(inAllocatedMemoryInByte), memoryBuffer(inBuffer),
blockHeader(nullptr), blockIndexesTable(nullptr), leafHeader(nullptr), nbParticlesInGroup(0),
blockHeader(nullptr), leafHeader(nullptr), nbParticlesInGroup(0),
attributesBuffer(nullptr), deleteBuffer(false){
// Move the pointers to the correct position
blockHeader = reinterpret_cast<BlockHeader*>(inBuffer);
inBuffer += sizeof(BlockHeader);
blockIndexesTable = reinterpret_cast<int*>(inBuffer);
inBuffer += (blockHeader->blockIndexesTableSize*sizeof(int));
leafHeader = reinterpret_cast<LeafHeader*>(inBuffer);
// Init particle pointers
......@@ -133,7 +126,7 @@ public:
* @param inNumberOfLeaves total number of leaves in the interval (should be <= inEndingIndex-inEndingIndex)
*/
FGroupOfParticles(const MortonIndex inStartingIndex, const MortonIndex inEndingIndex, const int inNumberOfLeaves, const FSize inNbParticles)
: allocatedMemoryInByte(0), memoryBuffer(nullptr), blockHeader(nullptr), blockIndexesTable(nullptr), leafHeader(nullptr), nbParticlesInGroup(inNbParticles),
: allocatedMemoryInByte(0), memoryBuffer(nullptr), blockHeader(nullptr), leafHeader(nullptr), nbParticlesInGroup(inNbParticles),
deleteBuffer(true){
memset(particlePosition, 0, sizeof(particlePosition));
memset(particleAttributes, 0, sizeof(particleAttributes));
......@@ -141,12 +134,11 @@ public:
const FSize nbParticlesAllocatedInGroup = RoundToUpperParticles(nbParticlesInGroup+(MemoryAlignementParticles-1)*inNumberOfLeaves);
// Find the number of leaf to allocate in the blocks
const int blockIndexesTableSize = int(inEndingIndex-inStartingIndex);
FAssertLF(inNumberOfLeaves <= blockIndexesTableSize);
FAssertLF(int(inEndingIndex-inStartingIndex) >= inNumberOfLeaves);
// Total number of bytes in the block
const size_t sizeOfOneParticle = (3*sizeof(FReal) + NbSymbAttributes*sizeof(AttributeClass));