Commit d97868b2 authored by Quentin Khan's avatar Quentin Khan

Merge branch 'master' into 'adaptive'

Conflicts:
	CMakeLists.txt
	Examples/LagrangeInterpolationFMM.cpp
	Src/Components/FBasicParticleContainer.hpp
	Src/Containers/FMpiBufferReader.hpp
	Src/Containers/FMpiBufferWriter.hpp
	Src/Files/FMpiFmaGenericLoader.hpp
	Src/Kernels/Chebyshev/FChebCell.hpp
	Src/Kernels/Chebyshev/FChebKernel.hpp
	Src/Kernels/Chebyshev/FChebM2LHandler.hpp
	Src/Kernels/Chebyshev/FChebSymKernel.hpp
	Src/Kernels/Chebyshev/FChebSymM2LHandler.hpp
	Src/Kernels/Chebyshev/FChebTensorialKernel.hpp
	Src/Kernels/Spherical/FSphericalRotationKernel.hpp
	Tests/GroupTree/testBlockedUniform.cpp
	UTests/utestLagrange.cpp
	UTests/utestMpiTreeBuilder.cpp
parents 97361262 6fa88aa4
// =================================================================================== // See LICENCE file at project root
// Copyright ScalFmm 2014 I
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
//
#ifndef CKERNELAPI_H #ifndef CKERNELAPI_H
#define CKERNELAPI_H #define CKERNELAPI_H
...@@ -891,9 +878,12 @@ void scalfmm_generic_partition(scalfmm_handle handle, FSize nbThings, size_t siz ...@@ -891,9 +878,12 @@ void scalfmm_generic_partition(scalfmm_handle handle, FSize nbThings, size_t siz
/** /**
* @brief This fct will call delete on its arg, in order to free the * @brief This fct will call delete on its arg, in order to free the
* memory allocated inside scalfmm, but given back to the user. * memory allocated inside scalfmm, but given back to the user. Both
* the args are tested, so user can call delete(NULL,array);
* @param array : array of double to be deleted
* @param arrayOfFSize : array of FSize to be deleted
*/ */
void scalfmm_call_delete(void * array); void scalfmm_call_delete(double * array, FSize * arrayOfFSize);
#endif //MPI_VERSION #endif //MPI_VERSION
......
// =================================================================================== // See LICENCE file at project root
// Copyright ScalFmm 2014 I
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
/** /**
* @file This file contains a class that inherits from FScalFMMEngine, * @file This file contains a class that inherits from FScalFMMEngine,
......
// =================================================================================== // See LICENCE file at project root
// Copyright ScalFmm 2014 I
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
/** /**
* @file This file contain a class, gathering all the function that * @file This file contain a class, gathering all the function that
...@@ -428,7 +414,7 @@ public: ...@@ -428,7 +414,7 @@ public:
template<class ContainerClass,class LeafClass,class CellClass> template<class ContainerClass,class LeafClass,class CellClass>
void generic_set_positions(FOctree<FReal,CellClass,ContainerClass,LeafClass> * octree, void generic_set_positions(FOctree<FReal,CellClass,ContainerClass,LeafClass> * octree,
int NbPositions, FReal * X, FReal * Y, FReal * Z, PartType type){ int NbPositions, FReal * X, FReal * Y, FReal * Z, PartType type){
int checkCount = 0; int checkCount = 0;
if(type == SOURCE || type==BOTH){ if(type == SOURCE || type==BOTH){
octree->forEachLeaf([&](LeafClass* leaf){ octree->forEachLeaf([&](LeafClass* leaf){
...@@ -564,7 +550,7 @@ public: ...@@ -564,7 +550,7 @@ public:
template<class ContainerClass,class LeafClass,class CellClass> template<class ContainerClass,class LeafClass,class CellClass>
void generic_get_positions_xyz(FOctree<FReal,CellClass,ContainerClass,LeafClass> * octree, void generic_get_positions_xyz(FOctree<FReal,CellClass,ContainerClass,LeafClass> * octree,
int NbPositions, FReal * positionsToFill, PartType type){ int NbPositions, FReal * positionsToFill, PartType type){
int checkCount = 0; int checkCount = 0;
if(type == SOURCE || type==BOTH){ if(type == SOURCE || type==BOTH){
octree->forEachLeaf([&](LeafClass* leaf){ octree->forEachLeaf([&](LeafClass* leaf){
...@@ -599,7 +585,7 @@ public: ...@@ -599,7 +585,7 @@ public:
template<class ContainerClass,class LeafClass,class CellClass> template<class ContainerClass,class LeafClass,class CellClass>
void generic_get_positions_xyz_npart(FOctree<FReal,CellClass,ContainerClass,LeafClass> * octree, void generic_get_positions_xyz_npart(FOctree<FReal,CellClass,ContainerClass,LeafClass> * octree,
int NbPositions, int * idxOfParticles, FReal * positionsToFill, PartType type){ int NbPositions, int * idxOfParticles, FReal * positionsToFill, PartType type){
int checkCount = 0; int checkCount = 0;
if(type == SOURCE || type==BOTH){ if(type == SOURCE || type==BOTH){
octree->forEachLeaf([&](LeafClass* leaf){ octree->forEachLeaf([&](LeafClass* leaf){
...@@ -654,7 +640,7 @@ public: ...@@ -654,7 +640,7 @@ public:
template<class ContainerClass,class LeafClass,class CellClass> template<class ContainerClass,class LeafClass,class CellClass>
void generic_get_positions(FOctree<FReal,CellClass,ContainerClass,LeafClass> * octree, void generic_get_positions(FOctree<FReal,CellClass,ContainerClass,LeafClass> * octree,
int NbPositions, FReal * X, FReal * Y , FReal * Z, PartType type){ int NbPositions, FReal * X, FReal * Y , FReal * Z, PartType type){
int checkCount = 0; int checkCount = 0;
if(type == SOURCE || type==BOTH){ if(type == SOURCE || type==BOTH){
octree->forEachLeaf([&](LeafClass* leaf){ octree->forEachLeaf([&](LeafClass* leaf){
...@@ -689,7 +675,7 @@ public: ...@@ -689,7 +675,7 @@ public:
template<class ContainerClass,class LeafClass,class CellClass> template<class ContainerClass,class LeafClass,class CellClass>
void generic_get_positions_npart(FOctree<FReal,CellClass,ContainerClass,LeafClass> * octree, void generic_get_positions_npart(FOctree<FReal,CellClass,ContainerClass,LeafClass> * octree,
int NbPositions, int * idxOfParticles,FReal * X, FReal * Y , FReal * Z,PartType type){ int NbPositions, int * idxOfParticles,FReal * X, FReal * Y , FReal * Z,PartType type){
int checkCount = 0; int checkCount = 0;
if(type == SOURCE || type==BOTH){ if(type == SOURCE || type==BOTH){
octree->forEachLeaf([&](LeafClass* leaf){ octree->forEachLeaf([&](LeafClass* leaf){
...@@ -865,12 +851,12 @@ extern "C" void scalfmm_get_physical_values(scalfmm_handle Handle, int nbPhysica ...@@ -865,12 +851,12 @@ extern "C" void scalfmm_get_physical_values(scalfmm_handle Handle, int nbPhysica
extern "C" void scalfmm_set_physical_values_npart(scalfmm_handle Handle, int nbPhysicalValues, extern "C" void scalfmm_set_physical_values_npart(scalfmm_handle Handle, int nbPhysicalValues,
int* idxOfParticles, double * physicalValues, PartType type){ int* idxOfParticles, double * physicalValues, PartType type){
((ScalFmmCoreHandle<double> * ) Handle)->engine->set_physical_values_npart(nbPhysicalValues, ((ScalFmmCoreHandle<double> * ) Handle)->engine->set_physical_values_npart(nbPhysicalValues,
idxOfParticles, physicalValues, type); idxOfParticles, physicalValues, type);
} }
extern "C" void scalfmm_get_physical_values_npart(scalfmm_handle Handle, int nbPhysicalValues, extern "C" void scalfmm_get_physical_values_npart(scalfmm_handle Handle, int nbPhysicalValues,
int* idxOfParticles, double * physicalValues, PartType type){ int* idxOfParticles, double * physicalValues, PartType type){
((ScalFmmCoreHandle<double> * ) Handle)->engine->get_physical_values_npart(nbPhysicalValues, ((ScalFmmCoreHandle<double> * ) Handle)->engine->get_physical_values_npart(nbPhysicalValues,
idxOfParticles, physicalValues, type); idxOfParticles, physicalValues, type);
} }
//To get the result //To get the result
...@@ -1073,6 +1059,13 @@ extern "C" void scalfmm_generic_partition(scalfmm_handle handle, FSize nbThings, ...@@ -1073,6 +1059,13 @@ extern "C" void scalfmm_generic_partition(scalfmm_handle handle, FSize nbThings,
((ScalFmmCoreHandle<double> * ) handle)->engine->generic_partition(nbThings,sizeofthing,arrayOfThing,newArray); ((ScalFmmCoreHandle<double> * ) handle)->engine->generic_partition(nbThings,sizeofthing,arrayOfThing,newArray);
} }
extern "C" void scalfmm_call_delete(double * inDoublePtr,FSize * inFSizePtr){
if(inDoublePtr)
delete [] inDoublePtr;
if(inFSizePtr)
delete [] inFSizePtr;
}
#endif #endif
#endif #endif
// See LICENCE file at project root
/** It should be compiled with C export */ /** It should be compiled with C export */
extern "C" { extern "C" {
#include "CScalfmmApi.h" #include "CScalfmmApi.h"
......
// See LICENCE file at project root
#ifndef FUSERKERNELDISTRENGINE_HPP #ifndef FUSERKERNELDISTRENGINE_HPP
#define FUSERKERNELDISTRENGINE_HPP #define FUSERKERNELDISTRENGINE_HPP
...@@ -431,6 +433,8 @@ public: ...@@ -431,6 +433,8 @@ public:
~FUserKernelDistrEngine(){ ~FUserKernelDistrEngine(){
delete comm; delete comm;
comm = nullptr; comm = nullptr;
delete kernel;
delete octreeDist;
} }
//Qu'est-ce qu'il faut que je surcharge ? //Qu'est-ce qu'il faut que je surcharge ?
...@@ -486,15 +490,20 @@ public: ...@@ -486,15 +490,20 @@ public:
for(int id = 0 ; id<nbPoints ; ++id){ for(int id = 0 ; id<nbPoints ; ++id){
FTreeCoordinate host; FTreeCoordinate host;
arrayToBeSorted[id].position = FPoint<FReal>(particleXYZ[id+0],particleXYZ[id+1],particleXYZ[id+2]); arrayToBeSorted[id].position = FPoint<FReal>(particleXYZ[3*id+0],
particleXYZ[3*id+1],
particleXYZ[3*id+2]);
arrayToBeSorted[id].orIndex = id + Ind.getoriIntervals(myRank).first; arrayToBeSorted[id].orIndex = id + Ind.getoriIntervals(myRank).first;
arrayToBeSorted[id].orOwner = myRank; arrayToBeSorted[id].orOwner = myRank;
//Evaluate Morton Index //Evaluate Morton Index
host.setX(FCoordinateComputer::GetTreeCoordinate<FReal>(particleXYZ[id*3+0] - this->getBoxCorner().getX(),this->getBoxWidth(),this->getBoxWidthAtLeafLevel(), host.setX(FCoordinateComputer::GetTreeCoordinate<FReal>(particleXYZ[id*3+0] - this->getBoxCorner().getX(),
this->getBoxWidth(),this->getBoxWidthAtLeafLevel(),
this->getTreeHeight())); this->getTreeHeight()));
host.setX(FCoordinateComputer::GetTreeCoordinate<FReal>(particleXYZ[id*3+1] - this->getBoxCorner().getY(),this->getBoxWidth(),this->getBoxWidthAtLeafLevel(), host.setX(FCoordinateComputer::GetTreeCoordinate<FReal>(particleXYZ[id*3+1] - this->getBoxCorner().getY(),
this->getBoxWidth(),this->getBoxWidthAtLeafLevel(),
this->getTreeHeight())); this->getTreeHeight()));
host.setX(FCoordinateComputer::GetTreeCoordinate<FReal>(particleXYZ[id*3+2] - this->getBoxCorner().getZ(),this->getBoxWidth(),this->getBoxWidthAtLeafLevel(), host.setX(FCoordinateComputer::GetTreeCoordinate<FReal>(particleXYZ[id*3+2] - this->getBoxCorner().getZ(),
this->getBoxWidth(),this->getBoxWidthAtLeafLevel(),
this->getTreeHeight())); this->getTreeHeight()));
arrayToBeSorted[id].index = host.getMortonIndex(); arrayToBeSorted[id].index = host.getMortonIndex();
} }
...@@ -578,11 +587,11 @@ public: ...@@ -578,11 +587,11 @@ public:
return A*stride; return A*stride;
}); });
std::transform(Ind.getDisplSendVector().begin(),Ind.getDisplSendVector().end(),displSendByte.begin(), std::transform(Ind.getDisplSendVector().begin(),Ind.getDisplSendVector().end(),displSendByte.begin(),
[&](const FSize & A){ [&](const FSize & A){
return A*stride; return A*stride;
}); });
std::transform(Ind.getDisplRecvVector().begin(),Ind.getDisplRecvVector().end(),displRecvByte.begin(), std::transform(Ind.getDisplRecvVector().begin(),Ind.getDisplRecvVector().end(),displRecvByte.begin(),
[&](const FSize & A){ [&](const FSize & A){
return A*stride; return A*stride;
}); });
std::vector<char > recvBuffer; std::vector<char > recvBuffer;
...@@ -603,12 +612,13 @@ public: ...@@ -603,12 +612,13 @@ public:
//Then, i need to find the index where current index //Then, i need to find the index where current index
//is sorted inside currentArray; //is sorted inside currentArray;
FSize idSearch = 0; FSize idSearch = 0;
for(idSearch=0 ; idSearch < Ind.getCount(myRank) && (Ind.getCurrentArrayValue(idSearch) != currentIndex) ; ++idSearch); for(idSearch=0 ; idSearch < Ind.getCount(myRank) && (Ind.getCurrentArrayValue(idSearch) != currentIndex) ; ++idSearch){
memcpy(&output[idSearch*stride],&recvBuffer[idRead*stride],stride); memcpy(&output[idSearch*stride],&recvBuffer[idRead*stride],stride);
}
} }
//C Part //C Part
*newArray = malloc(output.size()); *newArray = new char[output.size()];
memcpy(*newArray,output.data(),output.size()); memcpy(*newArray,output.data(),output.size());
} }
...@@ -696,13 +706,13 @@ public: ...@@ -696,13 +706,13 @@ public:
//Only one config shall work , so let's use it //Only one config shall work , so let's use it
switch(FScalFMMEngine<FReal>::Algorithm){ switch(FScalFMMEngine<FReal>::Algorithm){
case 5: case 5:
{ {
typedef FFmmAlgorithmThreadProc<OctreeClass,CoreCellDist,ContainerClass,CoreKernelClass,LeafClass> AlgoProcClass; typedef FFmmAlgorithmThreadProc<OctreeClass,CoreCellDist,ContainerClass,CoreKernelClass,LeafClass> AlgoProcClass;
AlgoProcClass * algoProc = new AlgoProcClass(*comm,octreeDist,kernel); AlgoProcClass * algoProc = new AlgoProcClass(*comm,octreeDist,kernel);
FScalFMMEngine<FReal>::algoTimer = algoProc; FScalFMMEngine<FReal>::algoTimer = algoProc;
algoProc->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P | FFmmP2P); algoProc->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P | FFmmP2P);
break; break;
} }
default: default:
break; break;
} }
...@@ -714,13 +724,13 @@ public: ...@@ -714,13 +724,13 @@ public:
//Only one config shall work , so let's use it //Only one config shall work , so let's use it
switch(FScalFMMEngine<FReal>::Algorithm){ switch(FScalFMMEngine<FReal>::Algorithm){
case 5: case 5:
{ {
typedef FFmmAlgorithmThreadProc<OctreeClass,CoreCellDist,ContainerClass,CoreKernelClass,LeafClass> AlgoProcClass; typedef FFmmAlgorithmThreadProc<OctreeClass,CoreCellDist,ContainerClass,CoreKernelClass,LeafClass> AlgoProcClass;
AlgoProcClass * algoProc = new AlgoProcClass(*comm,octreeDist,kernel); AlgoProcClass * algoProc = new AlgoProcClass(*comm,octreeDist,kernel);
FScalFMMEngine<FReal>::algoTimer = algoProc; FScalFMMEngine<FReal>::algoTimer = algoProc;
algoProc->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P); algoProc->execute(FFmmP2M | FFmmM2M | FFmmM2L | FFmmL2L | FFmmL2P);
break; break;
} }
default: default:
break; break;
} }
......
// =================================================================================== // See LICENCE file at project root
// Copyright ScalFmm 2014 I
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
/** /**
* @file This file contains a class that inherits from FScalFMMEngine, * @file This file contains a class that inherits from FScalFMMEngine,
......
// =================================================================================== // See LICENCE file at project root
// Copyright ScalFmm 2014 I
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
#ifndef FUSERLEAFCONTAINER_HPP #ifndef FUSERLEAFCONTAINER_HPP
#define FUSERLEAFCONTAINER_HPP #define FUSERLEAFCONTAINER_HPP
......
// See LICENCE file at project root
#ifndef TIMERS_H #ifndef TIMERS_H
#define TIMERS_H #define TIMERS_H
......
// See LICENCE file at project root
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
......
// See LICENCE file at project root
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
......
// See LICENCE file at project root
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
...@@ -175,9 +177,9 @@ void on_leaf(int level, FSize nbParts, const FSize * idxParts, long long morton_ ...@@ -175,9 +177,9 @@ void on_leaf(int level, FSize nbParts, const FSize * idxParts, long long morton_
double pot = 0; double pot = 0;
for(int i=0 ; i<nbParts ; ++i){ for(int i=0 ; i<nbParts ; ++i){
pot += potentials[i]; ptrToUserData->totalEnergy += potentials[i]*(ptrToUserData->myPhyValues[idxParts[i]]);
} }
ptrToUserData->totalEnergy += pot*(ptrToUserData->myPhyValues[idxParts[i]]);
} }
/* printf("I'm leaf at %lld pos, of center [%e %e %e], containing %lld parts\n", */ /* printf("I'm leaf at %lld pos, of center [%e %e %e], containing %lld parts\n", */
/* morton_index,center[0],center[1],center[2],nbParts); */ /* morton_index,center[0],center[1],center[2],nbParts); */
...@@ -319,8 +321,6 @@ int main(int argc, char ** argv){ ...@@ -319,8 +321,6 @@ int main(int argc, char ** argv){
//Only read, so no split needed //Only read, so no split needed
userDatas.insertedPositions = outputArray; // Set the position userDatas.insertedPositions = outputArray; // Set the position
//Need to get the good ones...
double * newPhyValues = malloc(sizeof(double) * outputNbPoint);
//In this part, we store the physicalvalues //In this part, we store the physicalvalues
//Create as many array of forces as there are threads in order to //Create as many array of forces as there are threads in order to
...@@ -364,6 +364,7 @@ int main(int argc, char ** argv){ ...@@ -364,6 +364,7 @@ int main(int argc, char ** argv){
//Dealloc scalfmm handle //Dealloc scalfmm handle
scalfmm_dealloc_handle(Handle,cheb_free_cell); scalfmm_dealloc_handle(Handle,cheb_free_cell);
{//This part will write generated particles to a file at ScalFMM {//This part will write generated particles to a file at ScalFMM
//format in order to verify numercal results //format in order to verify numercal results
/* if(my_rank==0){ */ /* if(my_rank==0){ */
...@@ -395,8 +396,8 @@ int main(int argc, char ** argv){ ...@@ -395,8 +396,8 @@ int main(int argc, char ** argv){
/* } */ /* } */
} }
free(outputIndexes); scalfmm_call_delete(outputArray,outputIndexes);
free(outputArray); scalfmm_call_delete(*outputPhyValPtr,NULL);
MPI_Finalize(); MPI_Finalize();
......