Commit c503873f authored by PIACIBELLO Cyrille's avatar PIACIBELLO Cyrille

Both version (user defined kernel and interpolation kernel) provides same features

parent e14f2180
...@@ -101,9 +101,6 @@ typedef void* scalfmm_handle; ...@@ -101,9 +101,6 @@ typedef void* scalfmm_handle;
/** /**
* @brief This function initialize scalfmm datas. * @brief This function initialize scalfmm datas.
* @param TreeHeight Height of the octree.
* @param BoxWidth Width of the entire simulation box.
* @param BoxCenter Coordinate of the center of the box (ie array)
* @param KernelType kernel to be used * @param KernelType kernel to be used
* @return scalfmm_handle (ie void *). This handle will be given to * @return scalfmm_handle (ie void *). This handle will be given to
* every other scalfmm functions. * every other scalfmm functions.
...@@ -111,15 +108,58 @@ typedef void* scalfmm_handle; ...@@ -111,15 +108,58 @@ typedef void* scalfmm_handle;
* Every data will be stored in order to crete later through a builder * Every data will be stored in order to crete later through a builder
* what is needed for the simulation * what is needed for the simulation
*/ */
scalfmm_handle scalfmm_init(int TreeHeight,double BoxWidth,double* BoxCenter, scalfmm_kernel_type KernelType); scalfmm_handle scalfmm_init( scalfmm_kernel_type KernelType);
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
////////////////// Tree Part ////////////// ////////////////// Tree Part //////////////
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
//In order to initate the tree for user defined cell and kernel, we
//define here the call_backs to deal with cells
/**
* @brief Function to init the cells (should be given by the user when
* calling Scalfmm_init_cell)
* @param level level of the cell.
* @param morton_index morton index of the cell to be allocated.
* @param tree_position int[3] position inside the tree (number of boxes in
* each direction)
* @param spatial_position double[3] center of the cell
*/
typedef void* (*Callback_init_cell)(int level, long long morton_index, int* tree_position, double* spatial_position);
/**
* Function to destroy what have bee initialized by the user (should
* be give in Scalfmm_dealloc_handle)
*/
typedef void (*Callback_free_cell)(void*);
/**
* @brief Structure containing user's call_backs in order to
* initialize/free the cell's user data.
*/
typedef struct User_Scalfmm_Cell_Descriptor{
Callback_free_cell user_free_cell;
Callback_init_cell user_init_cell;
}Scalfmm_Cell_Descriptor;
/**
* @brief This function build the tree. If scalfmm_init has been
* called with a user defined kernel, then user_cell_descriptor need
* to be provided
*
* @param TreeHeight Height of the octree.
* @param BoxWidth Width of the entire simulation box.
* @param BoxCenter Coordinate of the center of the box (ie array)
*/
void scalfmm_build_tree(scalfmm_handle handle,int TreeHeight,double BoxWidth,double* BoxCenter,Scalfmm_Cell_Descriptor user_cell_descriptor);
/** /**
* @brief This function insert an array of position into the octree * @brief This function insert an array of position into the octree
* @param Handle scalfmm_handle provided by scalfmm_init. * @param Handle scalfmm_handle provided by scalfmm_init.
...@@ -414,30 +454,14 @@ void scalfmm_user_kernel_config(scalfmm_handle Handle, Scalfmm_Kernel_Descriptor ...@@ -414,30 +454,14 @@ void scalfmm_user_kernel_config(scalfmm_handle Handle, Scalfmm_Kernel_Descriptor
//To fill gestion des cellules utilisateurs
/** /* void scalfmm_init_cell(scalfmm_handle Handle, Callback_init_cell user_cell_initializer); */
* @brief Function to init the cells (should be given by the user when
* calling Scalfmm_init_cell)
* @param level level of the cell.
* @param morton_index morton index of the cell to be allocated.
* @param tree_position int[3] position inside the tree (number of boxes in
* each direction)
* @param spatial_position double[3] center of the cell
*/
typedef void* (*Callback_init_cell)(int level, long long morton_index, int* tree_position, double* spatial_position);
/**
* Function to destroy what have bee initialized by the user (should
* be give in Scalfmm_dealloc_handle)
*/
typedef void (*Callback_free_cell)(void*);
void scalfmm_init_cell(scalfmm_handle Handle, Callback_init_cell user_cell_initializer);
void scalfmm_free_cell(scalfmm_handle Handle, Callback_free_cell user_cell_deallocator);
/* void scalfmm_free_cell(scalfmm_handle Handle, Callback_free_cell user_cell_deallocator); */
/* /\** */
/* *@param Struct defining how scalfmm will handle user's cell data. */
/* *\/ */
/* void scalfmm_user_cell_config(scalfmm_handle Handle, Scalfmm_Cell_Descriptor user_cell_descriptor); */
///////////////// Common kernel part : ///////////////// ///////////////// Common kernel part : /////////////////
......
...@@ -70,15 +70,18 @@ public: ...@@ -70,15 +70,18 @@ public:
* @param BoxCenter double[3] coordinate of the center of the * @param BoxCenter double[3] coordinate of the center of the
* simulation box * simulation box
*/ */
FInterEngine(int TreeHeight, double BoxWidth , double * BoxCenter,scalfmm_kernel_type KernelType) : FInterEngine(scalfmm_kernel_type KernelType) :
kernel(nullptr), matrix(nullptr), octree(nullptr),arranger(nullptr){ kernel(nullptr), matrix(nullptr), octree(nullptr),arranger(nullptr){
kernelType = KernelType;
}
void build_tree(int TreeHeight, double BoxWidth , double * BoxCenter,User_Scalfmm_Cell_Descriptor notUsedHere){
octree = new OctreeClass(TreeHeight,FMath::Min(3,TreeHeight-1),BoxWidth,FPoint(BoxCenter)); octree = new OctreeClass(TreeHeight,FMath::Min(3,TreeHeight-1),BoxWidth,FPoint(BoxCenter));
this->matrix = new MatrixKernelClass(); this->matrix = new MatrixKernelClass();
this->kernel = new InterKernel(TreeHeight,BoxWidth,FPoint(BoxCenter),matrix); this->kernel = new InterKernel(TreeHeight,BoxWidth,FPoint(BoxCenter),matrix);
kernelType = KernelType;
arranger = nullptr;
} }
//TODO free kernel too //TODO free kernel too
~FInterEngine(){ ~FInterEngine(){
delete matrix; delete matrix;
......
...@@ -80,6 +80,10 @@ public: ...@@ -80,6 +80,10 @@ public:
//by specific Engine //by specific Engine
//Function about the tree //Function about the tree
virtual void build_tree(int TreeHeight,double BoxWidth,double* BoxCenter,Scalfmm_Cell_Descriptor user_cell_descriptor){
FAssertLF(0,"Nothing has been done yet, exiting");
}
virtual void tree_insert_particles( int NbPositions, double * arrayX, double * arrayY, double * arrayZ){ virtual void tree_insert_particles( int NbPositions, double * arrayX, double * arrayY, double * arrayZ){
FAssertLF(0,"No tree instancied, exiting ...\n"); FAssertLF(0,"No tree instancied, exiting ...\n");
} }
...@@ -201,15 +205,7 @@ public: ...@@ -201,15 +205,7 @@ public:
FAssertLF(0,"No user kernel defined, exiting ...\n"); FAssertLF(0,"No user kernel defined, exiting ...\n");
} }
virtual void init_cell(Callback_init_cell user_cell_initializer){ virtual void execute_fmm(){
FAssertLF(0,"No user kernel defined, exiting ...\n");
}
virtual void free_cell(Callback_free_cell user_cell_initializer){
FAssertLF(0,"No user kernel defined, exiting ...\n");
}
virtual void execute_fmm(){
FAssertLF(0,"No kernel set, cannot execute anything, exiting ...\n"); FAssertLF(0,"No kernel set, cannot execute anything, exiting ...\n");
} }
...@@ -234,7 +230,9 @@ struct ScalFmmCoreHandle { ...@@ -234,7 +230,9 @@ struct ScalFmmCoreHandle {
extern "C" void scalfmm_build_tree(scalfmm_handle Handle,int TreeHeight,double BoxWidth,double* BoxCenter,Scalfmm_Cell_Descriptor user_cell_descriptor){
((ScalFmmCoreHandle *) Handle)->engine->build_tree(TreeHeight,BoxWidth, BoxCenter, user_cell_descriptor);
}
extern "C" void scalfmm_tree_insert_particles(scalfmm_handle Handle, int NbPositions, double * arrayX, double * arrayY, double * arrayZ){ extern "C" void scalfmm_tree_insert_particles(scalfmm_handle Handle, int NbPositions, double * arrayX, double * arrayY, double * arrayZ){
((ScalFmmCoreHandle *) Handle)->engine->tree_insert_particles(NbPositions, arrayX, arrayY, arrayZ); ((ScalFmmCoreHandle *) Handle)->engine->tree_insert_particles(NbPositions, arrayX, arrayY, arrayZ);
...@@ -391,16 +389,5 @@ extern "C" void scalfmm_user_kernel_config(scalfmm_handle Handle, Scalfmm_Kernel ...@@ -391,16 +389,5 @@ extern "C" void scalfmm_user_kernel_config(scalfmm_handle Handle, Scalfmm_Kernel
((ScalFmmCoreHandle * ) Handle)->engine->user_kernel_config(userKernel,userDatas); ((ScalFmmCoreHandle * ) Handle)->engine->user_kernel_config(userKernel,userDatas);
} }
extern "C" void scalfmm_init_cell(scalfmm_handle Handle, Callback_init_cell user_cell_initializer){
((ScalFmmCoreHandle * ) Handle)->engine->init_cell(user_cell_initializer);
}
extern "C" void scalfmm_free_cell(scalfmm_handle Handle, Callback_free_cell user_cell_deallocator){
((ScalFmmCoreHandle * ) Handle)->engine->free_cell(user_cell_deallocator);
}
// extern "C" void scalfmm_intern_dealloc_handle(scalfmm_handle Handle,Callback_free_cell userDeallocator){
// ((ScalFmmCoreHandle * ) Handle)->engine->intern_dealloc_handle(userDeallocator);
// }
#endif #endif
...@@ -6,13 +6,12 @@ extern "C" { ...@@ -6,13 +6,12 @@ extern "C" {
#include "FInterEngine.hpp" #include "FInterEngine.hpp"
#include "FUserKernelEngine.hpp" #include "FUserKernelEngine.hpp"
extern "C" scalfmm_handle scalfmm_init(int TreeHeight,double BoxWidth,double* BoxCenter, scalfmm_kernel_type KernelType){ extern "C" scalfmm_handle scalfmm_init(/*int TreeHeight,double BoxWidth,double* BoxCenter, */scalfmm_kernel_type KernelType){
ScalFmmCoreHandle * handle = new ScalFmmCoreHandle(); ScalFmmCoreHandle * handle = new ScalFmmCoreHandle();
switch(KernelType){ switch(KernelType){
case 0: case 0:
handle->engine = new FUserKernelEngine(TreeHeight, BoxWidth, BoxCenter, KernelType); handle->engine = new FUserKernelEngine(/*TreeHeight, BoxWidth, BoxCenter, */KernelType);
std::cout<< "User Kernel type unsupported yet" << std::endl;
break; break;
case 1: case 1:
...@@ -23,7 +22,7 @@ extern "C" scalfmm_handle scalfmm_init(int TreeHeight,double BoxWidth,double* Bo ...@@ -23,7 +22,7 @@ extern "C" scalfmm_handle scalfmm_init(int TreeHeight,double BoxWidth,double* Bo
typedef FInterpMatrixKernelR MatrixKernelClass; typedef FInterpMatrixKernelR MatrixKernelClass;
typedef FChebSymKernel<ChebCell,ContainerClass,MatrixKernelClass,7> ChebKernel; typedef FChebSymKernel<ChebCell,ContainerClass,MatrixKernelClass,7> ChebKernel;
handle->engine = new FInterEngine<ChebCell,ChebKernel>(TreeHeight,BoxWidth,BoxCenter, KernelType); handle->engine = new FInterEngine<ChebCell,ChebKernel>(/*TreeHeight,BoxWidth,BoxCenter, */KernelType);
break; break;
case 2: case 2:
//TODO typedefs //TODO typedefs
...@@ -33,7 +32,7 @@ extern "C" scalfmm_handle scalfmm_init(int TreeHeight,double BoxWidth,double* Bo ...@@ -33,7 +32,7 @@ extern "C" scalfmm_handle scalfmm_init(int TreeHeight,double BoxWidth,double* Bo
typedef FInterpMatrixKernelR MatrixKernelClass; typedef FInterpMatrixKernelR MatrixKernelClass;
typedef FUnifKernel<UnifCell,ContainerClass,MatrixKernelClass,7> UnifKernel; typedef FUnifKernel<UnifCell,ContainerClass,MatrixKernelClass,7> UnifKernel;
handle->engine = new FInterEngine<UnifCell,UnifKernel>(TreeHeight,BoxWidth,BoxCenter,KernelType); handle->engine = new FInterEngine<UnifCell,UnifKernel>(/*TreeHeight,BoxWidth,BoxCenter, */KernelType);
break; break;
default: default:
......
...@@ -31,12 +31,32 @@ class CoreCell : public FBasicCell { ...@@ -31,12 +31,32 @@ class CoreCell : public FBasicCell {
// Mutable in order to work with the API // Mutable in order to work with the API
mutable void* userData; mutable void* userData;
//Static members to be initialised before octree creation
static Scalfmm_Cell_Descriptor user_cell_descriptor;
public: public:
static void Init(Scalfmm_Cell_Descriptor cell_descriptor){
user_cell_descriptor=cell_descriptor;
}
static Callback_init_cell GetInit(){
return user_cell_descriptor.user_init_cell;
}
static Callback_free_cell GetFree(){
return user_cell_descriptor.user_free_cell;
}
CoreCell() : userData(nullptr) { CoreCell() : userData(nullptr) {
} }
//We free the cells here
~CoreCell(){ ~CoreCell(){
if(userData){
this->user_cell_descriptor.user_free_cell(userData);
}
} }
/** /**
* @brief setContainer store the ptr to the user data inside our * @brief setContainer store the ptr to the user data inside our
* struct * struct
...@@ -54,6 +74,10 @@ public: ...@@ -54,6 +74,10 @@ public:
} }
}; };
/**
* Define here static member
*/
Scalfmm_Cell_Descriptor CoreCell::user_cell_descriptor;
/** /**
* This class simply call the function pointers from Scalfmm_Kernel_Descriptor. * This class simply call the function pointers from Scalfmm_Kernel_Descriptor.
...@@ -142,8 +166,6 @@ public: ...@@ -142,8 +166,6 @@ public:
}; };
class FUserKernelEngine : public FScalFMMEngine{ class FUserKernelEngine : public FScalFMMEngine{
private: private:
...@@ -165,15 +187,17 @@ private: ...@@ -165,15 +187,17 @@ private:
CoreKernelClass * kernel; CoreKernelClass * kernel;
ArrangerClass * arranger; ArrangerClass * arranger;
public: public:
FUserKernelEngine(int TreeHeight, double BoxWidth , double * BoxCenter, scalfmm_kernel_type KernelType) : FUserKernelEngine(/*int TreeHeight, double BoxWidth , double * BoxCenter, */scalfmm_kernel_type KernelType) :
octree(nullptr), kernel(nullptr), arranger(nullptr){ octree(nullptr), kernel(nullptr), arranger(nullptr){
octree = new OctreeClass(TreeHeight,FMath::Min(3,TreeHeight-1),BoxWidth,FPoint(BoxCenter)); // octree = new OctreeClass(TreeHeight,FMath::Min(3,TreeHeight-1),BoxWidth,FPoint(BoxCenter));
kernelType = KernelType; kernelType = KernelType;
//Kernel is not set now because the user must provide a //Kernel is not set now because the user must provide a
//Scalfmm_Kernel_descriptor //Scalfmm_Kernel_descriptor
} }
~FUserKernelEngine(){ ~FUserKernelEngine(){
delete octree; delete octree;
...@@ -191,12 +215,17 @@ public: ...@@ -191,12 +215,17 @@ public:
} }
} }
void build_tree(int TreeHeight,double BoxWidth,double* BoxCenter,Scalfmm_Cell_Descriptor user_cell_descriptor){
CoreCell::Init(user_cell_descriptor);
this->octree = new OctreeClass(TreeHeight,FMath::Min(3,TreeHeight-1),BoxWidth,FPoint(BoxCenter));
}
void tree_insert_particles( int NbPositions, double * arrayX, double * arrayY, double * arrayZ){ void tree_insert_particles( int NbPositions, double * arrayX, double * arrayY, double * arrayZ){
for(int idPart = 0; idPart<NbPositions ; ++idPart){ for(int idPart = 0; idPart<NbPositions ; ++idPart){
octree->insert(FPoint(arrayX[idPart],arrayY[idPart],arrayZ[idPart]),idPart); octree->insert(FPoint(arrayX[idPart],arrayY[idPart],arrayZ[idPart]),idPart);
} }
nbPart += NbPositions; nbPart += NbPositions;
this->init_cell();
} }
void tree_insert_particles_xyz( int NbPositions, double * XYZ){ void tree_insert_particles_xyz( int NbPositions, double * XYZ){
...@@ -206,19 +235,176 @@ public: ...@@ -206,19 +235,176 @@ public:
nbPart += NbPositions; nbPart += NbPositions;
} }
/**
* To retrieve the positions, in order to move the parts
*/
void get_positions_xyz(int NbPositions, double * positionsToFill){
octree->forEachLeaf([&](LeafClass* leaf){
ContainerClass * sources = leaf->getSrc();
const FVector<int>& indexes = sources->getIndexes();
int nbPartThere = sources->getNbParticles();
for(int idxPart = 0 ; idxPart<nbPartThere ; ++idxPart){
positionsToFill[indexes[idxPart]*3+0] = sources->getPositions()[0][idxPart];
positionsToFill[indexes[idxPart]*3+1] = sources->getPositions()[1][idxPart];
positionsToFill[indexes[idxPart]*3+2] = sources->getPositions()[2][idxPart];
}
});
}
void get_positions_xyz_npart(int NbPositions, int * idxOfParticles, double * positionsToFill){
octree->forEachLeaf([&](LeafClass* leaf){
ContainerClass * sources = leaf->getSrc();
const FVector<int>& indexes = sources->getIndexes();
int nbPartThere = sources->getNbParticles();
for(int idxPart = 0 ; idxPart<nbPartThere ; ++idxPart){
int iterPart = 0;
bool notFoundYet = true;
while(iterPart < NbPositions && notFoundYet){
if(indexes[idxPart] == idxOfParticles[iterPart]){
positionsToFill[indexes[idxPart]*3+0] = sources->getPositions()[0][idxPart];
positionsToFill[indexes[idxPart]*3+1] = sources->getPositions()[1][idxPart];
positionsToFill[indexes[idxPart]*3+2] = sources->getPositions()[2][idxPart];
notFoundYet = false;
}
else{
++iterPart;
}
}
}
});
}
void get_positions( int NbPositions, double * X, double * Y , double * Z){
octree->forEachLeaf([&](LeafClass* leaf){
ContainerClass * sources = leaf->getSrc();
const FVector<int>& indexes = sources->getIndexes();
int nbPartThere = sources->getNbParticles();
for(int idxPart = 0 ; idxPart<nbPartThere ; ++idxPart){
X[indexes[idxPart]] = sources->getPositions()[0][idxPart];
Y[indexes[idxPart]] = sources->getPositions()[1][idxPart];
Z[indexes[idxPart]] = sources->getPositions()[2][idxPart];
}
});
}
void get_positions_npart(int NbPositions, int * idxOfParticles,double * X, double * Y , double * Z){
octree->forEachLeaf([&](LeafClass* leaf){
ContainerClass * sources = leaf->getSrc();
const FVector<int>& indexes = sources->getIndexes();
int nbPartThere = sources->getNbParticles();
for(int idxPart = 0 ; idxPart<nbPartThere ; ++idxPart){
int iterPart = 0;
bool notFoundYet = true;
while(iterPart < NbPositions && notFoundYet){
if(indexes[idxPart] == idxOfParticles[iterPart]){
X[indexes[idxPart]] = sources->getPositions()[0][idxPart];
Y[indexes[idxPart]] = sources->getPositions()[1][idxPart];
Z[indexes[idxPart]] = sources->getPositions()[2][idxPart];
notFoundYet = false;
}
else{
++iterPart;
}
}
}
});
}
//Arranger parts : following function provide a way to move parts
//inside the tree
void add_to_positions_xyz(int NbPositions,double * updatedXYZ){
octree->forEachLeaf([&](LeafClass* leaf){
ContainerClass * sources = leaf->getSrc();
const FVector<int>& indexes = sources->getIndexes();
int nbPartThere = sources->getNbParticles();
for(int idxPart = 0 ; idxPart<nbPartThere ; ++idxPart){
sources->getWPositions()[0][idxPart] += updatedXYZ[indexes[idxPart]*3+0];
sources->getWPositions()[1][idxPart] += updatedXYZ[indexes[idxPart]*3+1];
sources->getWPositions()[2][idxPart] += updatedXYZ[indexes[idxPart]*3+2];
}
});
}
void add_to_positions(int NbPositions,double * X, double * Y , double * Z){
octree->forEachLeaf([&](LeafClass* leaf){
ContainerClass * sources = leaf->getSrc();
const FVector<int>& indexes = sources->getIndexes();
int nbPartThere = sources->getNbParticles();
for(int idxPart = 0 ; idxPart<nbPartThere ; ++idxPart){
sources->getWPositions()[0][idxPart] += X[indexes[idxPart]];
sources->getWPositions()[1][idxPart] += Y[indexes[idxPart]];
sources->getWPositions()[2][idxPart] += Z[indexes[idxPart]];
}
});
}
void set_positions_xyz(int NbPositions, double * updatedXYZ){
octree->forEachLeaf([&](LeafClass* leaf){
ContainerClass * sources = leaf->getSrc();
const FVector<int>& indexes = sources->getIndexes();
int nbPartThere = sources->getNbParticles();
for(int idxPart = 0 ; idxPart<nbPartThere ; ++idxPart){
sources->getWPositions()[0][idxPart] = updatedXYZ[indexes[idxPart]*3+0];
sources->getWPositions()[1][idxPart] = updatedXYZ[indexes[idxPart]*3+1];
sources->getWPositions()[2][idxPart] = updatedXYZ[indexes[idxPart]*3+2];
}
});
}
void set_positions(int NbPositions, double * X, double * Y, double * Z){
octree->forEachLeaf([&](LeafClass* leaf){
ContainerClass * sources = leaf->getSrc();
const FVector<int>& indexes = sources->getIndexes();
int nbPartThere = sources->getNbParticles();
for(int idxPart = 0 ; idxPart<nbPartThere ; ++idxPart){
sources->getWPositions()[0][idxPart] = X[indexes[idxPart]];
sources->getWPositions()[1][idxPart] = Y[indexes[idxPart]];
sources->getWPositions()[2][idxPart] = Z[indexes[idxPart]];
}
});
}
void update_tree(){
if(arranger){
arranger->rearrange();
//then, we need to re-allocate cells user data for the
//cells created during the process and free user datas for
//the cells removed during the process
init_cell();
}
else{
if(Algorithm == 2){ //case in wich the periodic algorithm is used
arranger = new ArrangerClassPeriodic(octree);
arranger->rearrange();
}
else{
arranger = new ArrangerClass(octree);
arranger->rearrange();
init_cell();
}
}
}
/* /*
* Call the user allocator on userDatas member field of each cell * Call the user allocator on userDatas member field of each cell
*/ */
void init_cell(Callback_init_cell user_cell_initializer){ void init_cell(){
if(user_cell_initializer){
double boxwidth = octree->getBoxWidth(); double boxwidth = octree->getBoxWidth();
FPoint BoxCenter = octree->getBoxCenter(); FPoint BoxCenter = octree->getBoxCenter();
double boxCorner[3]; double boxCorner[3];
boxCorner[0] = BoxCenter.getX() - boxwidth/2.0; boxCorner[0] = BoxCenter.getX() - boxwidth/2.0;
boxCorner[1] = BoxCenter.getY() - boxwidth/2.0; boxCorner[1] = BoxCenter.getY() - boxwidth/2.0;
boxCorner[2] = BoxCenter.getZ() - boxwidth/2.0; boxCorner[2] = BoxCenter.getZ() - boxwidth/2.0;
//apply user function on each cell //apply user function on each cell
octree->forEachCellWithLevel([&](CoreCell * currCell,const int currLevel){ octree->forEachCellWithLevel([&](CoreCell * currCell,const int currLevel){
if(!(currCell->getContainer())){
FTreeCoordinate currCoord = currCell->getCoordinate(); FTreeCoordinate currCoord = currCell->getCoordinate();
int arrayCoord[3] = {currCoord.getX(),currCoord.getY(),currCoord.getZ()}; int arrayCoord[3] = {currCoord.getX(),currCoord.getY