Commit cf873373 authored by berenger-bramas's avatar berenger-bramas

Move to a relative diff in M2L based on array index.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@369 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 3a23a677
......@@ -56,7 +56,7 @@ public:
* @param size the number of neighbors
* @param inLevel the current level of the computation
*/
virtual void M2L(CellClass* const FRestrict local, const CellClass* distantNeighbors[189],
virtual void M2L(CellClass* const FRestrict local, const CellClass* distantNeighbors[343],
const int size, const int inLevel) = 0;
/**
......@@ -108,19 +108,6 @@ public:
// Periodic methods
//////////////////////////////////////////////////////////////////////////////
/**
* M2L
* Multipole to local
* @param local the element to fill using distant neighbors
* @param distantNeighbors is an array containing fathers's direct neighbors's child - direct neigbors
* @param neighborsRelativePositions the relative position of the neighbors (can be -2,-2,-2)
* @param size the number of neighbors
* @param inLevel the current level of the computation
*/
virtual void M2L(CellClass* const FRestrict local, const CellClass* distantNeighbors[189],
const FTreeCoordinate neighborsRelativePositions[189], const int size, const int level) = 0;
/**
* P2P
* Particles to particles
......
......@@ -74,11 +74,6 @@ public:
// ------------------- Periodic --------------------
/** Before Downward */
void M2L(CellClass* const FRestrict , const CellClass* [189], const FTreeCoordinate [189], const int , const int ) {
}
/** After Downward */
void P2P(const MortonIndex ,
ContainerClass* const FRestrict , const ContainerClass* const FRestrict ,
......
......@@ -44,7 +44,7 @@ public:
}
/** During upward */
void M2M(CellClass* const FRestrict pole, const CellClass *const FRestrict *const FRestrict child, const int ) {
void M2M(CellClass* const FRestrict pole, const CellClass *const FRestrict *const FRestrict child, const int /*level*/) {
// A parent represents the sum of the child
for(int idx = 0 ; idx < 8 ; ++idx){
......@@ -55,16 +55,16 @@ public:
}
/** Before Downward */
void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[189], const int size, const int ) {
void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[343], const int /*size*/, const int /*level*/) {
// The pole is impacted by what represent other poles
for(int idx = 0 ; idx < size ; ++idx){
pole->setDataDown(pole->getDataDown() + distantNeighbors[idx]->getDataUp());
for(int idx = 0 ; idx < 343 ; ++idx){
if(distantNeighbors[idx]) pole->setDataDown(pole->getDataDown() + distantNeighbors[idx]->getDataUp());
}
}
/** During Downward */
void L2L(const CellClass*const FRestrict local, CellClass* FRestrict *const FRestrict child, const int) {
void L2L(const CellClass*const FRestrict local, CellClass* FRestrict *const FRestrict child, const int /*level*/) {
// Each child is impacted by the father
for(int idx = 0 ; idx < 8 ; ++idx){
......
......@@ -20,14 +20,6 @@ template< class ParticleClass, class CellClass, class ContainerClass>
class FTestPeriodicKernels : public FTestKernels<ParticleClass,CellClass,ContainerClass> {
public:
/** Before Downward */
void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[189], const FTreeCoordinate [189], const int size, const int ) {
// The pole is impacted by what represent other poles
for(int idx = 0 ; idx < size ; ++idx){
pole->setDataDown(pole->getDataDown() + distantNeighbors[idx]->getDataUp());
}
}
/** After Downward */
void P2P(const MortonIndex ,
......
This diff is collapsed.
......@@ -161,13 +161,13 @@ private:
typename OctreeClass::Iterator avoidGotoLeftIterator(octreeIterator);
const CellClass* neighbors[189];
const CellClass* neighbors[343];
// for each levels
for(int idxLevel = 2 ; idxLevel < OctreeHeight ; ++idxLevel ){
// for each cells
do{
const int counter = tree->getDistantNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel);
const int counter = tree->getInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel);
FDEBUG(computationCounter.tic());
if(counter) kernels->M2L( octreeIterator.getCurrentCell() , neighbors, counter, idxLevel);
FDEBUG(computationCounter.tac());
......
......@@ -162,16 +162,15 @@ private:
typename OctreeClass::Iterator octreeIterator(tree);
typename OctreeClass::Iterator avoidGotoLeftIterator(octreeIterator);
const CellClass* neighbors[189];
FTreeCoordinate relativePosition[189];
const CellClass* neighbors[343];
// for each levels
for(int idxLevel = 1 ; idxLevel < OctreeHeight ; ++idxLevel ){
// for each cells
do{
const int counter = tree->getDistantNeighbors(neighbors, relativePosition, octreeIterator.getCurrentGlobalCoordinate(), idxLevel);
const int counter = tree->getPeriodicInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel);
FDEBUG(computationCounter.tic());
if(counter) kernels->M2L( octreeIterator.getCurrentCell() , neighbors, relativePosition, counter, idxLevel);
if(counter) kernels->M2L( octreeIterator.getCurrentCell() , neighbors, counter, idxLevel);
FDEBUG(computationCounter.tac());
} while(octreeIterator.moveRight());
avoidGotoLeftIterator.moveDown();
......@@ -285,28 +284,26 @@ private:
{
// We say that we are in the child index 0
// So we can compute one time the relative indexes
FTreeCoordinate relativePosition[189];
{
int counterPosition = 0;
for(int idxX = -2 ; idxX <= 3 ; ++idxX){
for(int idxY = -2 ; idxY <= 3 ; ++idxY){
for(int idxZ = -2 ; idxZ <= 3 ; ++idxZ){
if( FMath::Abs(idxX) > 1 || FMath::Abs(idxY) > 1 || FMath::Abs(idxZ) > 1){
relativePosition[counterPosition++].setPosition( idxX, idxY, idxZ);
}
const CellClass* neighbors[343];
memset(neighbors, 0, sizeof(CellClass*) * 343);
for(int idxX = -2 ; idxX <= 3 ; ++idxX){
for(int idxY = -2 ; idxY <= 3 ; ++idxY){
for(int idxZ = -2 ; idxZ <= 3 ; ++idxZ){
if( FMath::Abs(idxX) > 1 || FMath::Abs(idxY) > 1 || FMath::Abs(idxZ) > 1){
neighbors[(((idxX+3)*7) + (idxY+3))*7 + (idxZ + 3)] = reinterpret_cast<const CellClass*>(~0);
}
}
}
}
const CellClass* neighbors[189];
const int counter = 189;
for(int idxLevel = 0 ; idxLevel < periodicLimit ; ++idxLevel ){
for(int idxNeigh = 0 ; idxNeigh < 189 ; ++idxNeigh){
neighbors[idxNeigh] = &upperCells[idxLevel];
for(int idxNeigh = 0 ; idxNeigh < 343 ; ++idxNeigh){
if(neighbors[idxNeigh]){
neighbors[idxNeigh] = &upperCells[idxLevel];
}
}
kernels->M2L( &upperCells[idxLevel] , neighbors, relativePosition, counter, -idxLevel);
kernels->M2L( &upperCells[idxLevel] , neighbors, counter, -idxLevel);
}
}
......
......@@ -188,7 +188,7 @@ private:
#pragma omp parallel
{
KernelClass*const myThreadkernels = kernels[omp_get_thread_num()];
const CellClass* neighbors[189];
const CellClass* neighbors[343];
#pragma omp single nowait
{
......@@ -202,7 +202,7 @@ private:
for(int idxLevel = 2 ; idxLevel < OctreeHeight ; ++idxLevel ){
// for each cells
do{
const int counter = tree->getDistantNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel);
const int counter = tree->getInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(), idxLevel);
if(counter){
#pragma omp task
{
......
......@@ -237,11 +237,11 @@ private:
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
const CellClass* neighbors[189];
const CellClass* neighbors[343];
#pragma omp for schedule(dynamic) nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
const int counter = tree->getDistantNeighbors(neighbors, iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel);
const int counter = tree->getInteractionNeighbors(neighbors, iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel);
if(counter) myThreadkernels->M2L( iterArray[idxCell].getCurrentCell() , neighbors, counter, idxLevel);
}
}
......
......@@ -490,10 +490,11 @@ private:
// Which cell potentialy needs other data and in the same time
// are potentialy needed by other
int neighborsPosition[189];
MortonIndex neighborsIndexes[189];
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
// Find the M2L neigbors of a cell
const int counter = getDistantNeighbors(iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel,neighborsIndexes);
const int counter = getInteractionNeighbors(iterArray[idxCell].getCurrentGlobalCoordinate(), idxLevel, neighborsIndexes, neighborsPosition);
memset(alreadySent, false, sizeof(bool) * nbProcess);
bool needOther = false;
......@@ -635,14 +636,14 @@ private:
octreeIterator = avoidGotoLeftIterator;
FDEBUG(computationCounter.tic());
#pragma omp parallel
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
const CellClass* neighbors[189];
const CellClass* neighbors[343];
#pragma omp for schedule(dynamic) nowait
#pragma omp for schedule(dynamic) nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
const int counter = tree->getDistantNeighbors(neighbors, iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel);
const int counter = tree->getInteractionNeighbors(neighbors, iterArray[idxCell].getCurrentGlobalCoordinate(), idxLevel);
if(counter) myThreadkernels->M2L( iterArray[idxCell].getCurrentCell() , neighbors, counter, idxLevel);
}
}
......@@ -711,17 +712,18 @@ private:
// Compute this cells
FDEBUG(computationCounter.tic());
#pragma omp parallel
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
MortonIndex neighborsIndex[189];
const CellClass* neighbors[189];
CellClass neighborsData[189];
int neighborsPosition[189];
const CellClass* neighbors[343];
#pragma omp for schedule(dynamic) nowait
#pragma omp for schedule(dynamic) nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
// compute indexes
const int counterNeighbors = getDistantNeighbors(iterArray[idxCell].getCurrentGlobalCoordinate(), idxLevel, neighborsIndex);
const int counterNeighbors = getInteractionNeighbors(iterArray[idxCell].getCurrentGlobalCoordinate(), idxLevel, neighborsIndex, neighborsPosition);
int counter = 0;
// does we receive this index from someone?
......@@ -729,13 +731,15 @@ private:
const void* const cellFromOtherProc = tempTree.getCell(neighborsIndex[idxNeig], idxLevel);
if(cellFromOtherProc){
neighborsData[counter].deserializeUp(cellFromOtherProc);
neighbors[counter] = &neighborsData[counter];
neighborsData[counter].setMortonIndex(neighborsIndex[idxNeig]);
neighbors[ neighborsPosition[counter] ] = &neighborsData[counter];
++counter;
}
}
// need to compute
if(counter){
myThreadkernels->M2L( iterArray[idxCell].getCurrentCell() , neighbors, counter, idxLevel);
memset(neighbors, 0, 343 * sizeof(CellClass*));
}
}
}
......@@ -1266,7 +1270,7 @@ private:
return idxNeig;
}
int getDistantNeighbors(const FTreeCoordinate& workingCell,const int inLevel, MortonIndex inNeighbors[189]) const{
int getInteractionNeighbors(const FTreeCoordinate& workingCell,const int inLevel, MortonIndex inNeighbors[189], int inNeighborsPosition[189]) const{
// Then take each child of the parent's neighbors if not in directNeighbors
// Father coordinate
......@@ -1288,19 +1292,19 @@ private:
// if we are not on the current cell
if( idxX || idxY || idxZ ){
const FTreeCoordinate other(parentCell.getX() + idxX,parentCell.getY() + idxY,parentCell.getZ() + idxZ);
const MortonIndex mortonOther = other.getMortonIndex(inLevel-1);
const FTreeCoordinate otherParent(parentCell.getX() + idxX,parentCell.getY() + idxY,parentCell.getZ() + idxZ);
const MortonIndex mortonOther = otherParent.getMortonIndex(inLevel-1);
// For each child
for(int idxCousin = 0 ; idxCousin < 8 ; ++idxCousin){
const FTreeCoordinate potentialNeighbor((other.getX()<<1) | (idxCousin>>2 & 1),
(other.getY()<<1) | (idxCousin>>1 & 1),
(other.getZ()<<1) | (idxCousin&1));
const int xdiff = ((otherParent.getX()<<1) | ( (idxCousin>>2) & 1)) - workingCell.getX();
const int ydiff = ((otherParent.getY()<<1) | ( (idxCousin>>1) & 1)) - workingCell.getY();
const int zdiff = ((otherParent.getZ()<<1) | (idxCousin&1)) - workingCell.getZ();
// Test if it is a direct neighbor
if(FMath::Abs(workingCell.getX() - potentialNeighbor.getX()) > 1 ||
FMath::Abs(workingCell.getY() - potentialNeighbor.getY()) > 1 ||
FMath::Abs(workingCell.getZ() - potentialNeighbor.getZ()) > 1){
if(FMath::Abs(xdiff) > 1 || FMath::Abs(ydiff) > 1 || FMath::Abs(zdiff) > 1){
// add to neighbors
inNeighborsPosition[idxNeighbors] = (( (xdiff+3) * 7) + (ydiff+3)) * 7 + zdiff + 3;
inNeighbors[idxNeighbors++] = (mortonOther << 3) | idxCousin;
}
}
......
......@@ -566,10 +566,11 @@ private:
// Which cell potentialy needs other data and in the same time
// are potentialy needed by other
int neighborsPosition[189];
MortonIndex neighborsIndexes[189];
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
// Find the M2L neigbors of a cell
const int counter = getDistantNeighbors(iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel,neighborsIndexes);
const int counter = getPeriodicInteractionNeighbors(iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel,neighborsIndexes, neighborsPosition);
memset(alreadySent, false, sizeof(bool) * nbProcess);
bool needOther = false;
......@@ -712,17 +713,15 @@ private:
octreeIterator = avoidGotoLeftIterator;
FDEBUG(computationCounter.tic());
#pragma omp parallel
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
const CellClass* neighbors[189];
FTreeCoordinate relativePosition[189];
#pragma omp for schedule(dynamic) nowait
#pragma omp for schedule(dynamic) nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
const int counter = tree->getDistantNeighbors(neighbors, relativePosition, iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel);
if(counter) myThreadkernels->M2L( iterArray[idxCell].getCurrentCell() , neighbors, relativePosition, counter, idxLevel);
const int counter = tree->getPeriodicInteractionNeighbors(neighbors, iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel);
if(counter) myThreadkernels->M2L( iterArray[idxCell].getCurrentCell() , neighbors, counter, idxLevel);
}
}
FDEBUG(computationCounter.tac());
......@@ -786,35 +785,35 @@ private:
// Compute this cells
FDEBUG(computationCounter.tic());
#pragma omp parallel
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
MortonIndex neighborsIndex[189];
FTreeCoordinate relativePosition[189];
const CellClass* neighbors[189];
CellClass neighborsData[189];
int neighborsPosition[189];
const CellClass* neighbors[343];
#pragma omp for schedule(dynamic) nowait
#pragma omp for schedule(dynamic) nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
// compute indexes
const int counterNeighbors = getDistantNeighbors(iterArray[idxCell].getCurrentGlobalCoordinate(), idxLevel,
neighborsIndex, relativePosition);
const int counterNeighbors = getPeriodicInteractionNeighbors(iterArray[idxCell].getCurrentGlobalCoordinate(), idxLevel,
neighborsIndex, neighborsPosition);
int counter = 0;
// does we receive this index from someone?
for(int idxNeig = 0 ;idxNeig < counterNeighbors ; ++idxNeig){
const void* const cellFromOtherProc = tempTree.getCell(neighborsIndex[idxNeig], idxLevel);
if(cellFromOtherProc){
relativePosition[counter] = relativePosition[idxNeig];
neighborsData[counter].deserializeUp(cellFromOtherProc);
neighbors[counter] = &neighborsData[counter];
neighborsData[counter].setMortonIndex(neighborsIndex[idxNeig]);
neighbors[ neighborsPosition[counter] ] = &neighborsData[counter];
++counter;
}
}
// need to compute
if(counter){
myThreadkernels->M2L( iterArray[idxCell].getCurrentCell() , neighbors, relativePosition, counter, idxLevel);
myThreadkernels->M2L( iterArray[idxCell].getCurrentCell() , neighbors, counter, idxLevel);
memset(neighbors, 0, 343 * sizeof(CellClass*));
}
}
}
......@@ -1371,12 +1370,8 @@ private:
return idxNeig;
}
int getDistantNeighbors(const FTreeCoordinate& workingCell,const int inLevel, MortonIndex inNeighbors[189]){
FTreeCoordinate relativePosition[189];
return getDistantNeighbors(workingCell, inLevel, inNeighbors, relativePosition);
}
int getDistantNeighbors(const FTreeCoordinate& workingCell,const int inLevel, MortonIndex inNeighbors[189], FTreeCoordinate inRelativePosition[189]) const{
int getPeriodicInteractionNeighbors(const FTreeCoordinate& workingCell,const int inLevel, MortonIndex inNeighbors[189], int inNeighborsPosition[189]) const{
// Then take each child of the parent's neighbors if not in directNeighbors
// Father coordinate
......@@ -1410,20 +1405,15 @@ private:
// For each child
for(int idxCousin = 0 ; idxCousin < 8 ; ++idxCousin){
const FTreeCoordinate potentialNeighbor((otherParent.getX()<<1) | (idxCousin>>2 & 1),
(otherParent.getY()<<1) | (idxCousin>>1 & 1),
(otherParent.getZ()<<1) | (idxCousin&1));
const FTreeCoordinate relativePosition(potentialNeighbor.getX() - workingCell.getX(),
potentialNeighbor.getY() - workingCell.getY(),
potentialNeighbor.getZ() - workingCell.getZ());
const int xdiff = ((otherParent.getX()<<1) | ( (idxCousin>>2) & 1)) - workingCell.getX();
const int ydiff = ((otherParent.getY()<<1) | ( (idxCousin>>1) & 1)) - workingCell.getY();
const int zdiff = ((otherParent.getZ()<<1) | (idxCousin&1)) - workingCell.getZ();
// Test if it is a direct neighbor
if(FMath::Abs(relativePosition.getX()) > 1 ||
FMath::Abs(relativePosition.getY()) > 1 ||
FMath::Abs(relativePosition.getZ()) > 1){
if(FMath::Abs(xdiff) > 1 || FMath::Abs(ydiff) > 1 || FMath::Abs(zdiff) > 1){
// add to neighbors
inRelativePosition[idxNeighbors] = relativePosition;
inNeighbors[idxNeighbors++] = mortonOtherParent | idxCousin;
inNeighborsPosition[idxNeighbors] = (( (xdiff+3) * 7) + (ydiff+3)) * 7 + zdiff + 3;
inNeighbors[idxNeighbors++] = (mortonOtherParent << 3) | idxCousin;
}
}
}
......@@ -1461,30 +1451,27 @@ private:
{
// We say that we are in the child index 0
// So we can compute one time the relative indexes
FTreeCoordinate relativePosition[189];
{
int counterPosition = 0;
for(int idxX = -2 ; idxX <= 3 ; ++idxX){
for(int idxY = -2 ; idxY <= 3 ; ++idxY){
for(int idxZ = -2 ; idxZ <= 3 ; ++idxZ){
if( FMath::Abs(idxX) > 1 || FMath::Abs(idxY) > 1 || FMath::Abs(idxZ) > 1){
relativePosition[counterPosition++].setPosition( idxX, idxY, idxZ);
}
const CellClass* neighbors[343];
memset(neighbors, 0, sizeof(CellClass*) * 343);
for(int idxX = -2 ; idxX <= 3 ; ++idxX){
for(int idxY = -2 ; idxY <= 3 ; ++idxY){
for(int idxZ = -2 ; idxZ <= 3 ; ++idxZ){
if( FMath::Abs(idxX) > 1 || FMath::Abs(idxY) > 1 || FMath::Abs(idxZ) > 1){
neighbors[(((idxX+3)*7) + (idxY+3))*7 + (idxZ + 3)] = reinterpret_cast<const CellClass*>(~0);
}
}
}
}
const CellClass* neighbors[189];
const int counter = 189;
for(int idxLevel = 0 ; idxLevel < periodicLimit ; ++idxLevel ){
for(int idxNeigh = 0 ; idxNeigh < 189 ; ++idxNeigh){
neighbors[idxNeigh] = &upperCells[idxLevel];
for(int idxNeigh = 0 ; idxNeigh < 343 ; ++idxNeigh){
if(neighbors[idxNeigh]){
neighbors[idxNeigh] = &upperCells[idxLevel];
}
}
kernels[0]->M2L( &upperCells[idxLevel] , neighbors, relativePosition, counter, -idxLevel);
kernels[0]->M2L( &upperCells[idxLevel] , neighbors, counter, -idxLevel);
}
}
// Finally L2L until level 0
......
......@@ -238,27 +238,27 @@ public:
#pragma omp parallel
{
KernelClass * const myThreadkernels = kernels[omp_get_thread_num()];
const CellClass* neighbors[189];
const CellClass* neighbors[343];
#pragma omp for schedule(dynamic) nowait
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
CellClass* const currentCell = iterArray[idxCell].getCurrentCell();
if(currentCell->hasTargetsChild()){
const int counter = tree->getDistantNeighbors(neighbors, iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel);
int offsetTargetNeighbors = 0;
for(int idxRealNeighbors = 0 ; idxRealNeighbors < counter ; ++idxRealNeighbors, ++offsetTargetNeighbors){
if(neighbors[idxRealNeighbors]->hasSrcChild()){
if(idxRealNeighbors != offsetTargetNeighbors){
neighbors[offsetTargetNeighbors] = neighbors[idxRealNeighbors];
const int counter = tree->getInteractionNeighbors(neighbors, iterArray[idxCell].getCurrentGlobalCoordinate(),idxLevel);
if( counter ){
int counterWithSrc = 0;
for(int idxRealNeighbors = 0 ; idxRealNeighbors < 343 ; ++idxRealNeighbors ){
if(neighbors[idxRealNeighbors] && neighbors[idxRealNeighbors]->hasSrcChild()){
++counterWithSrc;
}
else{
neighbors[idxRealNeighbors] = 0;
}
}
else{
--offsetTargetNeighbors;
if(counterWithSrc){
myThreadkernels->M2L( currentCell , neighbors, counterWithSrc, idxLevel);
}
}
if(offsetTargetNeighbors){
myThreadkernels->M2L( currentCell , neighbors, offsetTargetNeighbors, idxLevel);
}
}
}
}
......
......@@ -180,7 +180,7 @@ public:
typename OctreeClass::Iterator avoidGotoLeftIterator(octreeIterator);
const CellClass* neighbors[189];
const CellClass* neighbors[343];
// for each levels
for(int idxLevel = 2 ; idxLevel < OctreeHeight ; ++idxLevel ){
......@@ -189,21 +189,21 @@ public:
FDEBUG(computationCounter.tic());
CellClass* const currentCell = octreeIterator.getCurrentCell();
if(currentCell->hasTargetsChild()){
const int counter = tree->getDistantNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(),idxLevel);
int offsetTargetNeighbors = 0;
for(int idxRealNeighbors = 0 ; idxRealNeighbors < counter ; ++idxRealNeighbors, ++offsetTargetNeighbors){
if(neighbors[idxRealNeighbors]->hasSrcChild()){
if(idxRealNeighbors != offsetTargetNeighbors){
neighbors[offsetTargetNeighbors] = neighbors[idxRealNeighbors];
const int counter = tree->getInteractionNeighbors(neighbors, octreeIterator.getCurrentGlobalCoordinate(),idxLevel);
if( counter ){
int counterWithSrc = 0;
for(int idxRealNeighbors = 0 ; idxRealNeighbors < 343 ; ++idxRealNeighbors ){
if(neighbors[idxRealNeighbors] && neighbors[idxRealNeighbors]->hasSrcChild()){
++counterWithSrc;
}
else{
neighbors[idxRealNeighbors] = 0;
}
}
else{
--offsetTargetNeighbors;
if(counterWithSrc){
kernels->M2L( currentCell , neighbors, counterWithSrc, idxLevel);
}
}
if(offsetTargetNeighbors){
kernels->M2L( currentCell , neighbors, offsetTargetNeighbors, idxLevel);
}
}
FDEBUG(computationCounter.tac());
FDEBUG(totalComputation += computationCounter.elapsed());
......
......@@ -161,7 +161,7 @@ public:
}
/** M2L with a cell and all the existing neighbors */
virtual void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[189],
virtual void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[343],
const int size, const int inLevel) = 0;
/** L2L with a cell and all its child */
......@@ -295,11 +295,6 @@ public:
// Periodic
///////////////////////////////////////////////////////////////////////////////
/** Before Downward */
virtual void M2L(CellClass* const FRestrict local, const CellClass* distantNeighbors[189],
const FTreeCoordinate neighborsRelativePositions[189],
const int size, const int inLevel) = 0;
/** After Downward */
void P2P(const MortonIndex inCurrentIndex,
......
......@@ -120,33 +120,14 @@ public:
}
/** M2L with a cell and all the existing neighbors */
void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[189],
const int size, const int inLevel) {
const FTreeCoordinate& coordCenter = pole->getCoordinate();
void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[343],
const int /*size*/, const int inLevel) {
// For all neighbors compute M2L
for(int idxNeigh = 0 ; idxNeigh < size ; ++idxNeigh){
const FTreeCoordinate& coordNeighbors = distantNeighbors[idxNeigh]->getCoordinate();
const FComplexe* const transitionVector = &preM2LTransitions[inLevel + Parent::periodicLevels]
[indexM2LTransition((coordCenter.getX() - coordNeighbors.getX()),
(coordCenter.getY() - coordNeighbors.getY()),
(coordCenter.getZ() - coordNeighbors.getZ()))];
multipoleToLocal(pole->getLocal(), distantNeighbors[idxNeigh]->getMultipole(), transitionVector);
}
}
/** Before Downward */
void M2L(CellClass* const FRestrict local, const CellClass* distantNeighbors[189],
const FTreeCoordinate neighborsRelativePositions[189],
const int size, const int inLevel) {
// For all neighbors compute M2L
for(int idxNeigh = 0 ; idxNeigh < size ; ++idxNeigh){
const FComplexe* const transitionVector = &preM2LTransitions[inLevel + Parent::periodicLevels]
[indexM2LTransition(neighborsRelativePositions[idxNeigh].getX(),
neighborsRelativePositions[idxNeigh].getY(),
neighborsRelativePositions[idxNeigh].getZ())];
multipoleToLocal(local->getLocal(), distantNeighbors[idxNeigh]->getMultipole(), transitionVector);
for(int idxNeigh = 0 ; idxNeigh < 343 ; ++idxNeigh){
if( distantNeighbors[idxNeigh] ){
const FComplexe* const transitionVector = &preM2LTransitions[inLevel + Parent::periodicLevels][idxNeigh];
multipoleToLocal(pole->getLocal(), distantNeighbors[idxNeigh]->getMultipole(), transitionVector);
}
}
}
......
......@@ -120,33 +120,14 @@ public:
}
/** M2L with a cell and all the existing neighbors */
void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[189],
const int size, const int inLevel) {
const FTreeCoordinate& coordCenter = pole->getCoordinate();
void M2L(CellClass* const FRestrict pole, const CellClass* distantNeighbors[343],
const int /*size*/, const int inLevel) {
// For all neighbors compute M2L
for(int idxNeigh = 0 ; idxNeigh < size ; ++idxNeigh){
const FTreeCoordinate& coordNeighbors = distantNeighbors[idxNeigh]->getCoordinate();
const FComplexe* const transitionVector = &preM2LTransitions[inLevel + Parent::periodicLevels]
[indexM2LTransition((coordCenter.getX() - coordNeighbors.getX()),
(coordCenter.getY() - coordNeighbors.getY()),
(coordCenter.getZ() - coordNeighbors.getZ()))];
multipoleToLocal(pole->getLocal(), distantNeighbors[idxNeigh]->getMultipole(), transitionVector);
}
}
/** Before Downward */
void M2L(CellClass* const FRestrict local, const CellClass* distantNeighbors[189],
const FTreeCoordinate neighborsRelativePositions[189],
const int size, const int inLevel) {
// For all neighbors compute M2L
for(int idxNeigh = 0 ; idxNeigh < size ; ++idxNeigh){
const FComplexe* const transitionVector = &preM2LTransitions[inLevel + Parent::periodicLevels]
[indexM2LTransition(neighborsRelativePositions[idxNeigh].getX(),
neighborsRelativePositions[idxNeigh].getY(),
neighborsRelativePositions[idxNeigh].getZ())];
multipoleToLocal(local->getLocal(), distantNeighbors[idxNeigh]->getMultipole(), transitionVector);
for(int idxNeigh = 0 ; idxNeigh < 343 ; ++idxNeigh){
if( distantNeighbors[idxNeigh] ){
const FComplexe* const transitionVector = &preM2LTransitions[inLevel + Parent::periodicLevels][idxNeigh];
multipoleToLocal(pole->getLocal(), distantNeighbors[idxNeigh]->getMultipole(), transitionVector);
}
}
}
......