Commit 7e96583f authored by BLANCHARD Pierre's avatar BLANCHARD Pierre

Implemented adaptive routines for AdaptChebSym FMM kernel, Switched base...

Implemented adaptive routines for AdaptChebSym FMM kernel, Switched base kernel from dense to classic (fft accelerated) Unif FMM kernel in AdaptUnif FMM kernel.
parent dec16fcc
This diff is collapsed.
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
#include "Adaptative/FAdaptiveCell.hpp" #include "Adaptative/FAdaptiveCell.hpp"
#include "Adaptative/FAdaptiveKernelWrapper.hpp" #include "Adaptative/FAdaptiveKernelWrapper.hpp"
#include "Adaptative/FAbstractAdaptiveKernel.hpp" #include "Adaptative/FAbstractAdaptiveKernel.hpp"
//#include "Kernels/Uniform/FUnifKernel.hpp" #include "Kernels/Uniform/FUnifKernel.hpp"
#include "Kernels/Uniform/FUnifDenseKernel.hpp"
#include "Kernels/Uniform/FUnifM2LHandler.hpp" #include "Kernels/Uniform/FUnifM2LHandler.hpp"
class FTreeCoordinate; class FTreeCoordinate;
...@@ -55,15 +54,21 @@ class FTreeCoordinate; ...@@ -55,15 +54,21 @@ class FTreeCoordinate;
*/ */
template< class CellClass, class ContainerClass, class MatrixKernelClass, int ORDER, int NVALS = 1> template< class CellClass, class ContainerClass, class MatrixKernelClass, int ORDER, int NVALS = 1>
class FAdaptiveUnifKernel : FUnifDenseKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS> class FAdaptiveUnifKernel : FUnifKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>
, public FAbstractAdaptiveKernel<CellClass, ContainerClass> { , public FAbstractAdaptiveKernel<CellClass, ContainerClass> {
// //
typedef FUnifDenseKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS> KernelBaseClass; typedef FUnifKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS> KernelBaseClass;
enum {order = ORDER, enum {order = ORDER,
nnodes = KernelBaseClass::nnodes}; nnodes = TensorTraits<ORDER>::nnodes};
/// Needed for M2L operator /// Needed for M2L operator
typedef FUnifM2LHandler<ORDER,MatrixKernelClass::Type> M2LHandlerClass; // // If we choose to pre-assemble adaptive M2L operators
const M2LHandlerClass M2LHandler; // // then we need to provide an adaptive M2L handler
// // and the transfer in Fourier space is straightforward.
// typedef FUnifM2LHandler<ORDER,MatrixKernelClass::Type> M2LHandlerClass;
// const M2LHandlerClass M2LHandler;
const MatrixKernelClass *const MatrixKernel; const MatrixKernelClass *const MatrixKernel;
public: public:
...@@ -82,11 +87,11 @@ public: ...@@ -82,11 +87,11 @@ public:
// * runtime_error is thrown if the required file is not valid). // * runtime_error is thrown if the required file is not valid).
// */ // */
FAdaptiveUnifKernel(const int inTreeHeight, const FReal inBoxWidth, FAdaptiveUnifKernel(const int inTreeHeight, const FReal inBoxWidth,
const FPoint& inBoxCenter, const MatrixKernelClass *const inMatrixKernel) : KernelBaseClass(inTreeHeight, inBoxWidth, inBoxCenter, inMatrixKernel), M2LHandler(inMatrixKernel, inTreeHeight, inBoxWidth), MatrixKernel(inMatrixKernel) const FPoint& inBoxCenter, const MatrixKernelClass *const inMatrixKernel) : KernelBaseClass(inTreeHeight, inBoxWidth, inBoxCenter, inMatrixKernel)/*, M2LHandler(inMatrixKernel, inTreeHeight, inBoxWidth)*/, MatrixKernel(inMatrixKernel)
{} {}
// /** Copy constructor */ // /** Copy constructor */
FAdaptiveUnifKernel(const FAdaptiveUnifKernel& other) FAdaptiveUnifKernel(const FAdaptiveUnifKernel& other)
: KernelBaseClass(other), M2LHandler(other.M2LHandler), MatrixKernel(other.MatrixKernel) : KernelBaseClass(other)/*, M2LHandler(other.M2LHandler)*/, MatrixKernel(other.MatrixKernel)
{ } { }
// //
...@@ -435,7 +440,6 @@ public: ...@@ -435,7 +440,6 @@ public:
// for(int idxPart = 0 ; idxPart < target->getNbParticles() ; ++idxPart){ // for(int idxPart = 0 ; idxPart < target->getNbParticles() ; ++idxPart){
// particlesAttributes[idxPart] += sources->getNbParticles(); // particlesAttributes[idxPart] += sources->getNbParticles();
// } // }
std::cout << "AdapP2P" << std::endl;
} }
bool preferP2M(const ContainerClass* const particles) override { bool preferP2M(const ContainerClass* const particles) override {
......
...@@ -72,6 +72,27 @@ protected: ...@@ -72,6 +72,27 @@ protected:
BoxCorner.getZ() + (FReal(Coordinate.getZ()) + FReal(.5)) * BoxWidthLeaf); BoxCorner.getZ() + (FReal(Coordinate.getZ()) + FReal(.5)) * BoxWidthLeaf);
} }
/**
* @brief Return the position of the center of a cell from its tree
* coordinate
* @param FTreeCoordinate
* @param inLevel the current level of Cell
*/
FPoint getCellCenter(const FTreeCoordinate coordinate, int inLevel)
{
//Set the boxes width needed
FReal widthAtCurrentLevel = BoxWidthLeaf*FReal(1 << (TreeHeight-(inLevel+1)));
FReal widthAtCurrentLevelDiv2 = widthAtCurrentLevel/FReal(2.);
//Set the center real coordinates from box corner and widths.
FReal X = BoxCorner.getX() + FReal(coordinate.getX())*widthAtCurrentLevel + widthAtCurrentLevelDiv2;
FReal Y = BoxCorner.getY() + FReal(coordinate.getY())*widthAtCurrentLevel + widthAtCurrentLevelDiv2;
FReal Z = BoxCorner.getZ() + FReal(coordinate.getZ())*widthAtCurrentLevel + widthAtCurrentLevelDiv2;
return FPoint(X,Y,Z);
}
public: public:
/** /**
* The constructor initializes all constant attributes and it reads the * The constructor initializes all constant attributes and it reads the
......
...@@ -98,7 +98,7 @@ public: ...@@ -98,7 +98,7 @@ public:
{ {
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){ for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 1) apply Sy // 1) apply Sy
FBlas::scal(AbstractBaseClass::nnodes, FReal(0.), ParentCell->getMultipole(idxRhs)); //FBlas::scal(AbstractBaseClass::nnodes, FReal(0.), ParentCell->getMultipole(idxRhs));
for (unsigned int ChildIndex=0; ChildIndex < 8; ++ChildIndex){ for (unsigned int ChildIndex=0; ChildIndex < 8; ++ChildIndex){
if (ChildCells[ChildIndex]){ if (ChildCells[ChildIndex]){
AbstractBaseClass::Interpolator->applyM2M(ChildIndex, ChildCells[ChildIndex]->getMultipole(idxRhs), AbstractBaseClass::Interpolator->applyM2M(ChildIndex, ChildCells[ChildIndex]->getMultipole(idxRhs),
......
...@@ -98,7 +98,7 @@ int main(int argc, char ** argv){ ...@@ -98,7 +98,7 @@ int main(int argc, char ** argv){
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// //
const int NbLevels = FParameters::getValue(argc,argv,"-depth", 7); const int NbLevels = FParameters::getValue(argc,argv,"-depth", 7);
const int SizeSubLevels = FParameters::getValue(argc,argv,"subdepth", 3); const int SizeSubLevels = FParameters::getValue(argc,argv,"-subdepth", 3);
const int sminM = FParameters::getValue(argc,argv,"-sM", P*P*P); const int sminM = FParameters::getValue(argc,argv,"-sM", P*P*P);
const int sminL = FParameters::getValue(argc,argv,"-sL", P*P*P); const int sminL = FParameters::getValue(argc,argv,"-sL", P*P*P);
// //
...@@ -109,7 +109,7 @@ int main(int argc, char ** argv){ ...@@ -109,7 +109,7 @@ int main(int argc, char ** argv){
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
// Not Random Loader // Not Random Loader
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
const std::string fileName(FParameters::getStr(argc,argv,"-fin", "../Data/prolate50.fma")); const std::string fileName(FParameters::getStr(argc,argv,"-fin", "../Data/prolate50.out.fma"));
FFmaGenericLoader loader(fileName); FFmaGenericLoader loader(fileName);
const long int NbPart = loader.getNumberOfParticles() ; const long int NbPart = loader.getNumberOfParticles() ;
// Random Loader // Random Loader
...@@ -127,10 +127,12 @@ int main(int argc, char ** argv){ ...@@ -127,10 +127,12 @@ int main(int argc, char ** argv){
std::cout << " criteria SM: "<< sminM <<std::endl std::cout << " criteria SM: "<< sminM <<std::endl
<< " criteria SL: "<< sminL <<std::endl <<std::endl; << " criteria SL: "<< sminL <<std::endl <<std::endl;
// //
{
counter.tic(); counter.tic();
FReal L= loader.getBoxWidth(); FReal L= loader.getBoxWidth();
FmaRParticle* particles= new FmaRParticle[NbPart]; //FmaRParticle* particles= new FmaRParticle[NbPart];
FmaRWParticle<8,8>* const particles = new FmaRWParticle<8,8>[NbPart];
FPoint minPos(L,L,L), maxPos(-L,-L,-L); FPoint minPos(L,L,L), maxPos(-L,-L,-L);
// //
loader.fillParticle(particles,NbPart); loader.fillParticle(particles,NbPart);
...@@ -146,7 +148,7 @@ int main(int argc, char ** argv){ ...@@ -146,7 +148,7 @@ int main(int argc, char ** argv){
maxPos.setZ(FMath::Max(maxPos.getZ(),PP.getZ())) ; maxPos.setZ(FMath::Max(maxPos.getZ(),PP.getZ())) ;
// //
tree.insert(PP, idxPart, particles[idxPart].getPhysicalValue()); tree.insert(PP, idxPart, particles[idxPart].getPhysicalValue());
}
counter.tac(); counter.tac();
...@@ -167,6 +169,58 @@ int main(int argc, char ** argv){ ...@@ -167,6 +169,58 @@ int main(int argc, char ** argv){
counter.tac(); counter.tac();
std::cout << "Done " << "(@Algorithm = " << counter.elapsed() << " s)." << std::endl; std::cout << "Done " << "(@Algorithm = " << counter.elapsed() << " s)." << std::endl;
//
FReal energy= 0.0 , energyD = 0.0 ;
/////////////////////////////////////////////////////////////////////////////////////////////////
// Compute direct energy
/////////////////////////////////////////////////////////////////////////////////////////////////
for(int idx = 0 ; idx < loader.getNumberOfParticles() ; ++idx){
energyD += particles[idx].getPotential()*particles[idx].getPhysicalValue() ;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// Compare
/////////////////////////////////////////////////////////////////////////////////////////////////
FMath::FAccurater potentialDiff;
FMath::FAccurater fx, fy, fz;
{ // Check that each particle has been summed with all other
// std::cout << "indexPartOrig || DIRECT V fx || FMM V fx" << std::endl;
tree.forEachLeaf([&](LeafClass* leaf){
const FReal*const potentials = leaf->getTargets()->getPotentials();
const FReal*const physicalValues = leaf->getTargets()->getPhysicalValues();
const FReal*const forcesX = leaf->getTargets()->getForcesX();
const FReal*const forcesY = leaf->getTargets()->getForcesY();
const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
const FVector<int>& indexes = leaf->getTargets()->getIndexes();
for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
const int indexPartOrig = indexes[idxPart];
potentialDiff.add(particles[indexPartOrig].getPotential(),potentials[idxPart]);
fx.add(particles[indexPartOrig].getForces()[0],forcesX[idxPart]);
fy.add(particles[indexPartOrig].getForces()[1],forcesY[idxPart]);
fz.add(particles[indexPartOrig].getForces()[2],forcesZ[idxPart]);
energy += potentials[idxPart]*physicalValues[idxPart];
// std::cout << indexPartOrig
// << " " << particles[indexPartOrig].getPotential() << " " << particles[indexPartOrig].getForces()[0]
// << " " << potentials[idxPart] << " " << forcesX[idxPart]
// << std::endl;
}
});
}
delete[] particles;
// Print for information
std::cout << "Potential " << potentialDiff << std::endl;
std::cout << "Fx " << fx << std::endl;
std::cout << "Fy " << fy << std::endl;
std::cout << "Fz " << fz << std::endl;
OctreeClass::Iterator octreeIterator(&tree); OctreeClass::Iterator octreeIterator(&tree);
std::ofstream file("aa.tree", std::ofstream::out ); std::ofstream file("aa.tree", std::ofstream::out );
......
...@@ -94,7 +94,7 @@ int main(int argc, char ** argv){ ...@@ -94,7 +94,7 @@ int main(int argc, char ** argv){
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// //
const int NbLevels = FParameters::getValue(argc,argv,"-depth", 3); const int NbLevels = FParameters::getValue(argc,argv,"-depth", 3);
const int SizeSubLevels = FParameters::getValue(argc,argv,"subdepth", 2); const int SizeSubLevels = FParameters::getValue(argc,argv,"-subdepth", 2);
const int sminM = FParameters::getValue(argc,argv,"-sM", P*P*P); const int sminM = FParameters::getValue(argc,argv,"-sM", P*P*P);
const int sminL = FParameters::getValue(argc,argv,"-sL", P*P*P); const int sminL = FParameters::getValue(argc,argv,"-sL", P*P*P);
// //
......
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