diff --git a/Addons/CKernelApi/Src/CScalfmmApi.h b/Addons/CKernelApi/Src/CScalfmmApi.h index 5684e0c68d9a409e10d3925c380a15e6c6201837..8e2271c561a31927bf5e117061c16469f12b5994 100644 --- a/Addons/CKernelApi/Src/CScalfmmApi.h +++ b/Addons/CKernelApi/Src/CScalfmmApi.h @@ -481,6 +481,9 @@ typedef void (*Callback_P2P)(FSize nbParticles, const FSize* particleIndexes, FS /** * @brief Function to be filled by user's P2P + * @attention This function is symmetrc, thus when a call is done + * between target and cell[27], the user needs to apply the target + * field onto the 27 cells too. * @param nbParticles number of particle in current leaf * @param particleIndexes indexes of particles currently computed * @param sourceCell array of the neighbors source cells @@ -500,6 +503,20 @@ typedef void (*Callback_P2PFull)(FSize nbParticles, const FSize* particleIndexes */ typedef void (*Callback_P2PInner)(FSize nbParticles, const FSize* particleIndexes, void* userData); +/** + * @brief Function to be filled by user's P2P + * @param nbParticles number of particle in current leaf + * @param particleIndexes indexes of particles currently computed + * @param nbSourceParticles number of particles in source leaf + * @param sourceParticleIndexes indexes of cource particles currently computed + * @param userData datas specific to the user's kernel + * @attention The fact that this callback is defined (and thus + * different from NULL or nullptr) means that it will be used, and + * thus if a call is done with cell1 as source and cell2 as target, no + * call will be done with cell2 as source and cell1 as target. + */ +typedef void (*Callback_P2PSym)(FSize nbParticles, const FSize* particleIndexes, FSize nbSourceParticles, const FSize* sourceParticleIndexes, void* userData); + /** * @brief Function to be filled by user's method to reset a user's cell * @param level level of the cell. @@ -527,6 +544,7 @@ typedef struct User_Scalfmm_Kernel_Descriptor { Callback_P2P p2p; Callback_P2PFull p2p_full; Callback_P2PInner p2pinner; + Callback_P2PSym p2p_sym; }Scalfmm_Kernel_Descriptor; diff --git a/Addons/CKernelApi/Src/FInterEngine.hpp b/Addons/CKernelApi/Src/FInterEngine.hpp index a53486c7dec303bfac880df23fb2593f5df038d1..d2165dbf17792c19e03401acdb9beb1a6277caf3 100644 --- a/Addons/CKernelApi/Src/FInterEngine.hpp +++ b/Addons/CKernelApi/Src/FInterEngine.hpp @@ -746,6 +746,7 @@ public: AlgoClassSeq* algoSeq = new AlgoClassSeq(octree,kernel); algoSeq->execute(); FScalFMMEngine<FReal>::algoTimer = algoSeq; + FScalFMMEngine<FReal>::abstrct = algoSeq; break; } case 1: @@ -754,6 +755,7 @@ public: AlgoClassThread* algoThread = new AlgoClassThread(octree,kernel); algoThread->execute(); FScalFMMEngine<FReal>::algoTimer = algoThread; + FScalFMMEngine<FReal>::abstrct = algoThread; break; } case 2: @@ -770,6 +772,7 @@ public: AlgoClassTargetSource* algoTS = new AlgoClassTargetSource(octree,kernel); algoTS->execute(); FScalFMMEngine<FReal>::algoTimer = algoTS; + FScalFMMEngine<FReal>::abstrct = algoTS; break; } default : diff --git a/Addons/CKernelApi/Src/FScalFMMEngine.hpp b/Addons/CKernelApi/Src/FScalFMMEngine.hpp index adb906ad03b5964e4842d4e53fdeab265aff1a52..1f33068f5c369e65d02930dd15c1e4bae89b6308 100644 --- a/Addons/CKernelApi/Src/FScalFMMEngine.hpp +++ b/Addons/CKernelApi/Src/FScalFMMEngine.hpp @@ -47,7 +47,7 @@ #include "Components/FTypedLeaf.hpp" #include "Containers/FOctree.hpp" #include "Utils/FTemplate.hpp" - +#include "Core/FCoreCommon.hpp" /** * @class FScalFMMEngine @@ -62,16 +62,19 @@ protected: FVector<bool>* progress; int nbPart; FAlgorithmTimers * algoTimer; - + FAbstractAlgorithm * abstrct; public: - FScalFMMEngine() : Algorithm(multi_thread), progress(nullptr), nbPart(0), algoTimer(nullptr){ + FScalFMMEngine() : Algorithm(multi_thread), progress(nullptr), nbPart(0), algoTimer(nullptr), abstrct(nullptr){ progress = new FVector<bool>(); } virtual ~FScalFMMEngine() { - if(algoTimer){ - delete algoTimer; + //Do not delete algoTimer because abstract and algoTimer are two pointers on the same thing + if(abstrct){ + delete abstrct; + abstrct = nullptr; + algoTimer = nullptr; } delete progress; } diff --git a/Addons/CKernelApi/Src/FScalfmmApiInit.cpp b/Addons/CKernelApi/Src/FScalfmmApiInit.cpp index 7edf2e827567ea9efa3f87d90a21808ce07d25db..6a712d1b08cc88a3da51f86f6f352429781e5e12 100644 --- a/Addons/CKernelApi/Src/FScalfmmApiInit.cpp +++ b/Addons/CKernelApi/Src/FScalfmmApiInit.cpp @@ -5,7 +5,7 @@ extern "C" { #include "FInterEngine.hpp" #include "FUserKernelEngine.hpp" -//#include "FAdaptEngine.hpp" + extern "C" scalfmm_handle scalfmm_init(/*int TreeHeight,double BoxWidth,double* BoxCenter, */scalfmm_kernel_type KernelType, scalfmm_algorithm algo){ diff --git a/Addons/CKernelApi/Src/FUserKernelEngine.hpp b/Addons/CKernelApi/Src/FUserKernelEngine.hpp index 1eaf3fecf43bd69aae8b29591f2b6d31f826b23b..aa5f2b2bbddab99fa171971798d1943587411133 100644 --- a/Addons/CKernelApi/Src/FUserKernelEngine.hpp +++ b/Addons/CKernelApi/Src/FUserKernelEngine.hpp @@ -164,6 +164,8 @@ public: ContainerClass* const neighbors[27], const int ){ if(kernel.p2pinner) kernel.p2pinner(targets->getNbParticles(), targets->getIndexes().data(), userData); + + if(kernel.p2p_full){ //Create the arrays of size and indexes FSize nbPartPerNeighbors[27]; @@ -180,11 +182,21 @@ public: } kernel.p2p_full(targets->getNbParticles(),targets->getIndexes().data(),indicesPerNeighbors,nbPartPerNeighbors,userData); } - if(kernel.p2p){ - for(int idx = 0 ; idx < 27 ; ++idx){ + if(kernel.p2p_sym){ + for(int idx = 0 ; idx < 14 ; ++idx){ if( neighbors[idx] ){ - kernel.p2p(targets->getNbParticles(), targets->getIndexes().data(), - neighbors[idx]->getNbParticles(), neighbors[idx]->getIndexes().data(), userData); + kernel.p2p_sym(targets->getNbParticles(), targets->getIndexes().data(), + neighbors[idx]->getNbParticles(), neighbors[idx]->getIndexes().data(), userData); + } + } + } + else{ + if(kernel.p2p){ + for(int idx = 0 ; idx < 27 ; ++idx){ + if( neighbors[idx] ){ + kernel.p2p(targets->getNbParticles(), targets->getIndexes().data(), + neighbors[idx]->getNbParticles(), neighbors[idx]->getIndexes().data(), userData); + } } } } @@ -535,14 +547,13 @@ public: void execute_fmm(){ FAssertLF(kernel,"No kernel set, please use scalfmm_user_kernel_config before calling the execute routine ... Exiting \n"); - FAbstractAlgorithm * abstrct = nullptr; switch(FScalFMMEngine<FReal>::Algorithm){ case 0: { typedef FFmmAlgorithm<OctreeClass,CoreCell,ContainerClass,CoreKernelClass,LeafClass> AlgoClassSeq; AlgoClassSeq * algoSeq = new AlgoClassSeq(octree,kernel); FScalFMMEngine<FReal>::algoTimer = algoSeq; - abstrct = algoSeq; + FScalFMMEngine<FReal>::abstrct = algoSeq; //algoSeq->execute(); will be done later break; } @@ -551,7 +562,7 @@ public: typedef FFmmAlgorithmThread<OctreeClass,CoreCell,ContainerClass,CoreKernelClass,LeafClass> AlgoClassThread; AlgoClassThread* algoThread = new AlgoClassThread(octree,kernel); FScalFMMEngine<FReal>::algoTimer = algoThread; - abstrct = algoThread; + FScalFMMEngine<FReal>::abstrct = algoThread; //algoThread->execute(); will be done later break; } @@ -568,24 +579,25 @@ public: typedef FFmmAlgorithmThreadTsm<OctreeClass,CoreCell,ContainerClass,CoreKernelClass,LeafClass> AlgoClassTargetSource; AlgoClassTargetSource* algoTS = new AlgoClassTargetSource(octree,kernel); FScalFMMEngine<FReal>::algoTimer = algoTS; - abstrct = algoTS; + FScalFMMEngine<FReal>::abstrct = algoTS; //algoTS->execute(); will be done later break; } default : std::cout<< "No algorithm found (probably for strange reasons) : "<< FScalFMMEngine<FReal>::Algorithm <<" exiting" << std::endl; } + if (FScalFMMEngine<FReal>::Algorithm != 2){ if(upperLimit != 2){ - abstrct->execute(FFmmP2M | FFmmM2M | FFmmM2L, upperLimit, treeHeight); + (FScalFMMEngine<FReal>::abstrct)->execute(FFmmP2M | FFmmM2M | FFmmM2L, upperLimit, treeHeight); printf("\tUpPass finished\n"); internal_M2L(); printf("\tStrange M2L finished\n"); - abstrct->execute(FFmmL2L | FFmmL2P | FFmmP2P, upperLimit, treeHeight); + (FScalFMMEngine<FReal>::abstrct)->execute(FFmmL2L | FFmmL2P | FFmmP2P, upperLimit, treeHeight); printf("\tDownPass finished\n"); } else{ - abstrct->execute(); + (FScalFMMEngine<FReal>::abstrct)->execute(); } } } diff --git a/Addons/CKernelApi/Tests/testChebInterface.c b/Addons/CKernelApi/Tests/testChebInterface.c index 29382f0d9b5ec4fdf1c148f395b11aee45893ae0..95d972e6ea3664d4135655a48eaa700293b1f30f 100644 --- a/Addons/CKernelApi/Tests/testChebInterface.c +++ b/Addons/CKernelApi/Tests/testChebInterface.c @@ -65,7 +65,7 @@ void cheb_resetCell(int level, long long morton_index, int* tree_position, doubl * @param number of particle (no default value) */ int main(int argc, char ** av){ - //omp_set_num_threads(1); + omp_set_num_threads(1); printf("Start\n"); if(argc<2){ printf("Use : %s nb_part (optionnal : TreeHeight) \nexiting\n",av[0]); @@ -149,6 +149,7 @@ int main(int argc, char ** av){ kernel.m2l_full = cheb_m2l_full; kernel.l2l = cheb_l2l; kernel.l2p = cheb_l2p; + kernel.p2p_sym = NULL; kernel.p2p_full = cheb_p2pFull; kernel.p2pinner = NULL; kernel.p2p = NULL;