MAJ terminée. Nous sommes passés en version 14.6.2 . Pour consulter les "releases notes" associées c'est ici :

https://about.gitlab.com/releases/2022/01/11/security-release-gitlab-14-6-2-released/
https://about.gitlab.com/releases/2022/01/04/gitlab-14-6-1-released/

Commit e6421c6c authored by COULAUD Olivier's avatar COULAUD Olivier
Browse files
parents cfbd9c17 f484a848
......@@ -314,6 +314,9 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_SOURCE_DIR}/CMakeModules/morse/")
unset(FFT_LIBRARIES CACHE)
message(STATUS " SCALFMM USE MKL already defined")
set(FFT_INCLUDES "$ENV{MKLROOT}/include/fftw" CACHE STRING "Set your MKL flags")
if (BLAS_FOUND)
set(FFTW_FOUND ON)
endif()
else(SCALFMM_USE_MKL_AS_BLAS)
......@@ -350,7 +353,7 @@ if (MORSE_DISTRIB_DIR OR EXISTS "${CMAKE_SOURCE_DIR}/CMakeModules/morse/")
if (FFT_INCLUDES)
set(SCALFMM_INCLUDES "${SCALFMM_INCLUDES}; ${FFT_INCLUDES}")
endif()
if(FFTW_FOUND)
message(STATUS " SCALFMM_LIBRARIES = ${SCALFMM_LIBRARIES}")
message(STATUS " SCALFMM_INCLUDES = ${SCALFMM_INCLUDES}")
......
......@@ -28,25 +28,25 @@
###
# Set some colors
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColourReset "${Esc}[m")
set(ColourBold "${Esc}[1m")
set(Red "${Esc}[31m")
set(Green "${Esc}[32m")
set(Yellow "${Esc}[33m")
set(Blue "${Esc}[34m")
set(Magenta "${Esc}[35m")
set(Cyan "${Esc}[36m")
set(White "${Esc}[37m")
set(BoldRed "${Esc}[1;31m")
set(BoldGreen "${Esc}[1;32m")
set(BoldYellow "${Esc}[1;33m")
set(BoldBlue "${Esc}[1;34m")
set(BoldMagenta "${Esc}[1;35m")
set(BoldCyan "${Esc}[1;36m")
set(BoldWhite "${Esc}[1;37m")
endif()
#if(NOT WIN32)
# string(ASCII 27 Esc)
# set(ColourReset "${Esc}[m")
# set(ColourBold "${Esc}[1m")
# set(Red "${Esc}[31m")
# set(Green "${Esc}[32m")
# set(Yellow "${Esc}[33m")
# set(Blue "${Esc}[34m")
# set(Magenta "${Esc}[35m")
# set(Cyan "${Esc}[36m")
# set(White "${Esc}[37m")
# set(BoldRed "${Esc}[1;31m")
# set(BoldGreen "${Esc}[1;32m")
# set(BoldYellow "${Esc}[1;33m")
# set(BoldBlue "${Esc}[1;34m")
# set(BoldMagenta "${Esc}[1;35m")
# set(BoldCyan "${Esc}[1;36m")
# set(BoldWhite "${Esc}[1;37m")
#endif()
# Colorize cmake messages during configure
function(message)
......
......@@ -36,25 +36,25 @@
# Set some colors
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColourReset "${Esc}[m")
set(ColourBold "${Esc}[1m")
set(Red "${Esc}[31m")
set(Green "${Esc}[32m")
set(Yellow "${Esc}[33m")
set(Blue "${Esc}[34m")
set(Magenta "${Esc}[35m")
set(Cyan "${Esc}[36m")
set(White "${Esc}[37m")
set(BoldRed "${Esc}[1;31m")
set(BoldGreen "${Esc}[1;32m")
set(BoldYellow "${Esc}[1;33m")
set(BoldBlue "${Esc}[1;34m")
set(BoldMagenta "${Esc}[1;35m")
set(BoldCyan "${Esc}[1;36m")
set(BoldWhite "${Esc}[1;37m")
endif()
#if(NOT WIN32)
# string(ASCII 27 Esc)
# set(ColourReset "${Esc}[m")
# set(ColourBold "${Esc}[1m")
# set(Red "${Esc}[31m")
# set(Green "${Esc}[32m")
# set(Yellow "${Esc}[33m")
# set(Blue "${Esc}[34m")
# set(Magenta "${Esc}[35m")
# set(Cyan "${Esc}[36m")
# set(White "${Esc}[37m")
# set(BoldRed "${Esc}[1;31m")
# set(BoldGreen "${Esc}[1;32m")
# set(BoldYellow "${Esc}[1;33m")
# set(BoldBlue "${Esc}[1;34m")
# set(BoldMagenta "${Esc}[1;35m")
# set(BoldCyan "${Esc}[1;36m")
# set(BoldWhite "${Esc}[1;37m")
#endif()
# This macro informs why the _header_to_find file has not been found
......
......@@ -63,25 +63,25 @@
# Set some colors
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColourReset "${Esc}[m")
set(ColourBold "${Esc}[1m")
set(Red "${Esc}[31m")
set(Green "${Esc}[32m")
set(Yellow "${Esc}[33m")
set(Blue "${Esc}[34m")
set(Magenta "${Esc}[35m")
set(Cyan "${Esc}[36m")
set(White "${Esc}[37m")
set(BoldRed "${Esc}[1;31m")
set(BoldGreen "${Esc}[1;32m")
set(BoldYellow "${Esc}[1;33m")
set(BoldBlue "${Esc}[1;34m")
set(BoldMagenta "${Esc}[1;35m")
set(BoldCyan "${Esc}[1;36m")
set(BoldWhite "${Esc}[1;37m")
endif()
#if(NOT WIN32)
# string(ASCII 27 Esc)
# set(ColourReset "${Esc}[m")
# set(ColourBold "${Esc}[1m")
# set(Red "${Esc}[31m")
# set(Green "${Esc}[32m")
# set(Yellow "${Esc}[33m")
# set(Blue "${Esc}[34m")
# set(Magenta "${Esc}[35m")
# set(Cyan "${Esc}[36m")
# set(White "${Esc}[37m")
# set(BoldRed "${Esc}[1;31m")
# set(BoldGreen "${Esc}[1;32m")
# set(BoldYellow "${Esc}[1;33m")
# set(BoldBlue "${Esc}[1;34m")
# set(BoldMagenta "${Esc}[1;35m")
# set(BoldCyan "${Esc}[1;36m")
# set(BoldWhite "${Esc}[1;37m")
#endif()
## Some macros to print status when search for headers and libs
# This macro informs why the _lib_to_find file has not been found
......
......@@ -58,25 +58,25 @@
# Set some colors
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColourReset "${Esc}[m")
set(ColourBold "${Esc}[1m")
set(Red "${Esc}[31m")
set(Green "${Esc}[32m")
set(Yellow "${Esc}[33m")
set(Blue "${Esc}[34m")
set(Magenta "${Esc}[35m")
set(Cyan "${Esc}[36m")
set(White "${Esc}[37m")
set(BoldRed "${Esc}[1;31m")
set(BoldGreen "${Esc}[1;32m")
set(BoldYellow "${Esc}[1;33m")
set(BoldBlue "${Esc}[1;34m")
set(BoldMagenta "${Esc}[1;35m")
set(BoldCyan "${Esc}[1;36m")
set(BoldWhite "${Esc}[1;37m")
endif()
#if(NOT WIN32)
# string(ASCII 27 Esc)
# set(ColourReset "${Esc}[m")
# set(ColourBold "${Esc}[1m")
# set(Red "${Esc}[31m")
# set(Green "${Esc}[32m")
# set(Yellow "${Esc}[33m")
# set(Blue "${Esc}[34m")
# set(Magenta "${Esc}[35m")
# set(Cyan "${Esc}[36m")
# set(White "${Esc}[37m")
# set(BoldRed "${Esc}[1;31m")
# set(BoldGreen "${Esc}[1;32m")
# set(BoldYellow "${Esc}[1;33m")
# set(BoldBlue "${Esc}[1;34m")
# set(BoldMagenta "${Esc}[1;35m")
# set(BoldCyan "${Esc}[1;36m")
# set(BoldWhite "${Esc}[1;37m")
#endif()
## Some macros to print status when search for headers and libs
# This macro informs why the _lib_to_find file has not been found
......
......@@ -53,25 +53,25 @@
# Set some colors
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColourReset "${Esc}[m")
set(ColourBold "${Esc}[1m")
set(Red "${Esc}[31m")
set(Green "${Esc}[32m")
set(Yellow "${Esc}[33m")
set(Blue "${Esc}[34m")
set(Magenta "${Esc}[35m")
set(Cyan "${Esc}[36m")
set(White "${Esc}[37m")
set(BoldRed "${Esc}[1;31m")
set(BoldGreen "${Esc}[1;32m")
set(BoldYellow "${Esc}[1;33m")
set(BoldBlue "${Esc}[1;34m")
set(BoldMagenta "${Esc}[1;35m")
set(BoldCyan "${Esc}[1;36m")
set(BoldWhite "${Esc}[1;37m")
endif()
#if(NOT WIN32)
# string(ASCII 27 Esc)
# set(ColourReset "${Esc}[m")
# set(ColourBold "${Esc}[1m")
# set(Red "${Esc}[31m")
# set(Green "${Esc}[32m")
# set(Yellow "${Esc}[33m")
# set(Blue "${Esc}[34m")
# set(Magenta "${Esc}[35m")
# set(Cyan "${Esc}[36m")
# set(White "${Esc}[37m")
# set(BoldRed "${Esc}[1;31m")
# set(BoldGreen "${Esc}[1;32m")
# set(BoldYellow "${Esc}[1;33m")
# set(BoldBlue "${Esc}[1;34m")
# set(BoldMagenta "${Esc}[1;35m")
# set(BoldCyan "${Esc}[1;36m")
# set(BoldWhite "${Esc}[1;37m")
#endif()
## Some macros to print status when search for headers and libs
# This macro informs why the _lib_to_find file has not been found
......
......@@ -169,17 +169,18 @@ public:
}
}
/**
* This constructor create a group tree from a particle container index.
* The morton index are computed and the particles are sorted in a first stage.
* Then the leaf level is done.
* Finally the other leve are proceed one after the other.
* It should be easy to make it parallel using for and tasks.
* If no limite give inLeftLimite = -1
*/
template<class ParticleContainer>
FGroupTree(const int inTreeHeight, const FReal inBoxWidth, const FPoint<FReal>& inBoxCenter,
const int inNbElementsPerBlock, ParticleContainer* inParticlesContainer, const bool particlesAreSorted = false):
const int inNbElementsPerBlock, ParticleContainer* inParticlesContainer,
const bool particlesAreSorted = false, MortonIndex inLeftLimite = -1):
treeHeight(inTreeHeight),nbElementsPerBlock(inNbElementsPerBlock),cellBlocksPerLevel(nullptr),
boxCenter(inBoxCenter), boxCorner(inBoxCenter,-(inBoxWidth/2)), boxWidth(inBoxWidth),
boxWidthAtLeafLevel(inBoxWidth/FReal(1<<(inTreeHeight-1))){
......@@ -204,8 +205,8 @@ public:
for(int idxPart = 0 ; idxPart < nbParticles ; ++idxPart){
const FTreeCoordinate host = FCoordinateComputer::GetCoordinateFromPositionAndCorner<FReal>(this->boxCorner, this->boxWidth,
treeHeight,
FPoint<FReal>(xpos[idxPart], ypos[idxPart], zpos[idxPart]) );
treeHeight,
FPoint<FReal>(xpos[idxPart], ypos[idxPart], zpos[idxPart]) );
const MortonIndex particleIndex = host.getMortonIndex(treeHeight-1);
particlesToSort[idxPart].mindex = particleIndex;
particlesToSort[idxPart].originalIndex = idxPart;
......@@ -219,6 +220,8 @@ public:
});
}
FAssertLF(nbParticles == 0 || inLeftLimite < particlesToSort[0].mindex);
// Convert to block
const int idxLevel = (treeHeight - 1);
int* nbParticlesPerLeaf = new int[nbElementsPerBlock];
......@@ -287,12 +290,26 @@ public:
delete[] particlesToSort;
}
// For each level from heigth - 2 to 1
for(int idxLevel = treeHeight-2; idxLevel > 0 ; --idxLevel){
inLeftLimite = (inLeftLimite == -1 ? inLeftLimite : (inLeftLimite>>3));
CellGroupConstIterator iterChildCells = cellBlocksPerLevel[idxLevel+1].begin();
const CellGroupConstIterator iterChildEndCells = cellBlocksPerLevel[idxLevel+1].end();
// Skip blocks that do not respect limit
while(iterChildCells != iterChildEndCells
&& ((*iterChildCells)->getEndingIndex()>>3) <= inLeftLimite){
++iterChildCells;
}
// If lower level is empty or all blocks skiped stop here
if(iterChildCells == iterChildEndCells){
break;
}
MortonIndex currentCellIndex = (*iterChildCells)->getStartingIndex();
if((currentCellIndex>>3) <= inLeftLimite) currentCellIndex = ((inLeftLimite+1)<<3);
int sizeOfBlock = 0;
// We need to proceed each group in sub level
......@@ -345,8 +362,6 @@ public:
delete[] currentBlockIndexes;
}
/**
* This constructor create a group tree from a particle container index.
* The morton index are computed and the particles are sorted in a first stage.
......@@ -354,11 +369,17 @@ public:
* Finally the other leve are proceed one after the other.
* It should be easy to make it parallel using for and tasks.
* If no limite give inLeftLimite = -1
* The cover ration is the minimum pourcentage of cell that should
* exist in a group (0 means no limite, 1 means the block must be dense)
* oneParent should be turned on if it is better to have one block parent
* per sublock (in case of have the cost of FMM that increase with the level
* this could be an asset).
*/
template<class ParticleContainer>
FGroupTree(const int inTreeHeight, const FReal inBoxWidth, const FPoint<FReal>& inBoxCenter,
const int inNbElementsPerBlock, ParticleContainer* inParticlesContainer,
const bool particlesAreSorted, MortonIndex inLeftLimite):
const bool particlesAreSorted, const bool oneParent,
const FReal inCoverRatio = 0.0, MortonIndex inLeftLimite = -1):
treeHeight(inTreeHeight),nbElementsPerBlock(inNbElementsPerBlock),cellBlocksPerLevel(nullptr),
boxCenter(inBoxCenter), boxCorner(inBoxCenter,-(inBoxWidth/2)), boxWidth(inBoxWidth),
boxWidthAtLeafLevel(inBoxWidth/FReal(1<<(inTreeHeight-1))){
......@@ -382,7 +403,7 @@ public:
const FReal* zpos = inParticlesContainer->getPositions()[2];
for(int idxPart = 0 ; idxPart < nbParticles ; ++idxPart){
const FTreeCoordinate host = FCoordinateComputer::GetCoordinateFromPosition<FReal>(this->boxCorner, this->boxWidth,
const FTreeCoordinate host = FCoordinateComputer::GetCoordinateFromPositionAndCorner<FReal>(this->boxCorner, this->boxWidth,
treeHeight,
FPoint<FReal>(xpos[idxPart], ypos[idxPart], zpos[idxPart]) );
const MortonIndex particleIndex = host.getMortonIndex(treeHeight-1);
......@@ -490,56 +511,117 @@ public:
if((currentCellIndex>>3) <= inLeftLimite) currentCellIndex = ((inLeftLimite+1)<<3);
int sizeOfBlock = 0;
// We need to proceed each group in sub level
while(iterChildCells != iterChildEndCells){
// Count until end of sub group is reached or we have enough cells
while(sizeOfBlock < nbElementsPerBlock && iterChildCells != iterChildEndCells ){
if((sizeOfBlock == 0 || currentBlockIndexes[sizeOfBlock-1] != (currentCellIndex>>3))
&& (*iterChildCells)->exists(currentCellIndex)){
currentBlockIndexes[sizeOfBlock] = (currentCellIndex>>3);
sizeOfBlock += 1;
currentCellIndex = (((currentCellIndex>>3)+1)<<3);
}
else{
currentCellIndex += 1;
}
// If we are at the end of the sub group, move to next
while(iterChildCells != iterChildEndCells && (*iterChildCells)->getEndingIndex() <= currentCellIndex){
++iterChildCells;
// Update morton index
if(iterChildCells != iterChildEndCells && currentCellIndex < (*iterChildCells)->getStartingIndex()){
currentCellIndex = (*iterChildCells)->getStartingIndex();
if(oneParent == false){
// We need to proceed each group in sub level
while(iterChildCells != iterChildEndCells){
// Count until end of sub group is reached or we have enough cells
while(sizeOfBlock < nbElementsPerBlock && iterChildCells != iterChildEndCells ){
if((sizeOfBlock == 0 || currentBlockIndexes[sizeOfBlock-1] != (currentCellIndex>>3))
&& (*iterChildCells)->exists(currentCellIndex)){
currentBlockIndexes[sizeOfBlock] = (currentCellIndex>>3);
sizeOfBlock += 1;
currentCellIndex = (((currentCellIndex>>3)+1)<<3);
}
else{
currentCellIndex += 1;
}
// If we are at the end of the sub group, move to next
while(iterChildCells != iterChildEndCells && (*iterChildCells)->getEndingIndex() <= currentCellIndex){
++iterChildCells;
// Update morton index
if(iterChildCells != iterChildEndCells && currentCellIndex < (*iterChildCells)->getStartingIndex()){
currentCellIndex = (*iterChildCells)->getStartingIndex();
}
}
}
}
// If group is full
if(sizeOfBlock == nbElementsPerBlock || (sizeOfBlock && iterChildCells == iterChildEndCells)){
// Create a group
CellGroupClass*const newBlock = new CellGroupClass(currentBlockIndexes[0],
currentBlockIndexes[sizeOfBlock-1]+1,
sizeOfBlock);
// Init cells
for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){
newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock);
// If group is full
if(sizeOfBlock == nbElementsPerBlock || (sizeOfBlock && iterChildCells == iterChildEndCells)){
// Create a group
CellGroupClass*const newBlock = new CellGroupClass(currentBlockIndexes[0],
currentBlockIndexes[sizeOfBlock-1]+1,
sizeOfBlock);
// Init cells
for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){
newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock);
CompositeCellClass newNode = newBlock->getCompleteCell(currentBlockIndexes[cellIdInBlock]);
newNode.setMortonIndex(currentBlockIndexes[cellIdInBlock]);
FTreeCoordinate coord;
coord.setPositionFromMorton(currentBlockIndexes[cellIdInBlock], idxLevel);
newNode.setCoordinate(coord);
}
CompositeCellClass newNode = newBlock->getCompleteCell(currentBlockIndexes[cellIdInBlock]);
newNode.setMortonIndex(currentBlockIndexes[cellIdInBlock]);
FTreeCoordinate coord;
coord.setPositionFromMorton(currentBlockIndexes[cellIdInBlock], idxLevel);
newNode.setCoordinate(coord);
// Keep the block
cellBlocksPerLevel[idxLevel].push_back(newBlock);
sizeOfBlock = 0;
}
}
}
else{
// We need to proceed each group in sub level
while(iterChildCells != iterChildEndCells){
// We want one parent group per child group so we will stop the parent group
// when we arrive to the same parent as lastChildIndex (which is lastChildIndex>>3)
const MortonIndex lastChildIndex = ((*iterChildCells)->getEndingIndex()-1);
// Count until end of sub group is reached or we passe the requested parent
while( iterChildCells != iterChildEndCells
&& (currentCellIndex>>3) <= (lastChildIndex>>3) ){
// Proceed until the requested parent
while(currentCellIndex != (*iterChildCells)->getEndingIndex()
&& (currentCellIndex>>3) <= (lastChildIndex>>3) ){
if((*iterChildCells)->exists(currentCellIndex)){
currentBlockIndexes[sizeOfBlock] = (currentCellIndex>>3);
sizeOfBlock += 1;
currentCellIndex = (((currentCellIndex>>3)+1)<<3);
}
else{
currentCellIndex += 1;
}
}
// If we are at the end of the sub group, move to next (otherwise we have consume a part of it)
if((*iterChildCells)->getEndingIndex() <= currentCellIndex){
++iterChildCells;
// Update morton index
if(iterChildCells != iterChildEndCells && currentCellIndex < (*iterChildCells)->getStartingIndex()){
currentCellIndex = (*iterChildCells)->getStartingIndex();
}
}
}
// Keep the block
cellBlocksPerLevel[idxLevel].push_back(newBlock);
// If group is full
if(sizeOfBlock){
// Create a group
CellGroupClass*const newBlock = new CellGroupClass(currentBlockIndexes[0],
currentBlockIndexes[sizeOfBlock-1]+1,
sizeOfBlock);
// Init cells
for(int cellIdInBlock = 0; cellIdInBlock != sizeOfBlock ; ++cellIdInBlock){
newBlock->newCell(currentBlockIndexes[cellIdInBlock], cellIdInBlock);
CompositeCellClass newNode = newBlock->getCompleteCell(currentBlockIndexes[cellIdInBlock]);
newNode.setMortonIndex(currentBlockIndexes[cellIdInBlock]);
FTreeCoordinate coord;
coord.setPositionFromMorton(currentBlockIndexes[cellIdInBlock], idxLevel);
newNode.setCoordinate(coord);
}
sizeOfBlock = 0;
// Keep the block
cellBlocksPerLevel[idxLevel].push_back(newBlock);
sizeOfBlock = 0;
}
else{
assert(iterChildCells == iterChildEndCells);
}
}
}
}
delete[] currentBlockIndexes;
}
/** This function dealloc the tree by deleting each block */
~FGroupTree(){
for(int idxLevel = 0 ; idxLevel < treeHeight ; ++idxLevel){
......
......@@ -55,23 +55,30 @@ public:
initialize_heteroprio_center_policy_callback = &InitSchedulerCallback;
treeHeight = inTreeHeight;
prioP2MSend = 0;
prioP2M = prioP2MSend+1;
prioM2MSend = prioP2M+1;
prioM2M = prioM2MSend+1;
int incPrio = 0;
prioM2L = prioM2M+1;
prioM2LExtern = prioM2L;
prioM2LMpi = prioM2L;
prioP2MSend = incPrio++;
prioP2M = incPrio++;
prioL2L = prioM2L+1;
prioM2MSend = incPrio++;
prioM2M = incPrio++;
prioP2P = prioL2L + (treeHeight-3)*2+1 +1;
prioP2PExtern = prioP2P;
prioP2PMpi = prioP2P;
prioM2L = incPrio;
prioM2LExtern = incPrio;
prioM2LMpi = incPrio++;
prioL2P = prioP2PMpi+1;
prioL2L = incPrio++;
incPrio += (treeHeight-2)-1 // M2L is done treeHeight-2 times
+(treeHeight-3)-1; // L2L is done treeHeight-3 times
prioP2P = incPrio;
prioP2PExtern = incPrio;
prioP2PMpi = incPrio++;
prioL2P = incPrio++;
assert(incPrio == 6 + (treeHeight-2) + (treeHeight-3));
}
void initSchedulerCallback(unsigned /*sched_ctx_id*/,
......@@ -296,7 +303,7 @@ public:
return prioM2LExtern + (inLevel - 2)*2;
}
int getPrioL2L(const int inLevel) const {
return prioL2L + (inLevel - 2)*2 + 1;
return prioL2L + (inLevel - 2)*2;
}
int getPrioL2P() const {
return prioL2P;
......@@ -308,7 +315,7 @@ public:
return prioP2PExtern;
}
int getPrioM2LMpi(const int inLevel) const {
return prioM2LMpi + inLevel - 2;
return prioM2LMpi + (inLevel - 2)*2;
}
int getPrioP2PMpi() const {
return prioP2PMpi;
......
......@@ -122,6 +122,7 @@ int main(int argc, char* argv[]){
// Put the data into the tree
//GroupOctreeClass groupedTree(NbLevels, groupSize, &tree);
GroupOctreeClass groupedTree(NbLevels, loader.getBoxWidth(), loader.getCenterOfBox(), groupSize, &allParticles);
//GroupOctreeClass groupedTree(NbLevels, loader.getBoxWidth(), loader.getCenterOfBox(), groupSize, &allParticles, false, true);
groupedTree.printInfoBlocks();
// Check tree structure at leaf level
......
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