Commit a036c5dd authored by COULAUD Olivier's avatar COULAUD Olivier

Merge commit '87a868c8'

* commit '87a868c8':
  Making ffmper.sh a bit more maintainable. No need to list all the numbers of the interval you want to use.
  Add test for adaptive Uniform kernel and update FUnifCell.
  Provided copy ctor for all Uniform M2L handlers.
parents f06cfcd1 87a868c8
This diff is collapsed.
......@@ -170,6 +170,21 @@ public:
return (NRHS+NLHS)*NVALS*VectorSize * (int) sizeof(FReal) + (NRHS+NLHS)*NVALS*TransformedVectorSize * (int) sizeof(FComplexe);
}
template <class StreamClass>
friend StreamClass& operator<<(StreamClass& output, const FUnifCell<ORDER, NRHS, NLHS, NVALS>& cell){
output <<" Multipole exp NRHS " << NRHS <<" NVALS " <<NVALS << " VectorSize " << cell.getVectorSize() << std::endl;
for (int rhs= 0 ; rhs < NRHS ; ++rhs) {
const FReal* pole = cell.getMultipole(rhs);
for (int val= 0 ; val < NVALS ; ++val) {
output<< " val : " << val << " exp: " ;
for (int i= 0 ; i < cell.getVectorSize() ; ++i) {
output<< pole[i] << " ";
}
output << std::endl;
}
}
return output;
}
};
......
......@@ -211,6 +211,20 @@ public:
}
/*
* Copy constructor
*/
FUnifM2LHandler(const FUnifM2LHandler& other)
: FC(other.FC), Dft(), opt_rc(other.opt_rc)
{
// init DFT
const int steps[dimfft] = {rc};
Dft.buildDFT(steps);
// copy node_diff
memcpy(node_diff,other.node_diff,sizeof(unsigned int)*nnodes*nnodes);
}
~FUnifM2LHandler()
{ }
......@@ -350,8 +364,8 @@ public:
FUnifM2LHandler(const MatrixKernelClass *const MatrixKernel, const unsigned int inTreeHeight, const FReal inRootCellWidth)
: TreeHeight(inTreeHeight),
RootCellWidth(inRootCellWidth),
opt_rc(rc/2+1),
Dft()
Dft(), opt_rc(rc/2+1)
{
// init DFT
const int steps[dimfft] = {rc};
......@@ -370,6 +384,25 @@ public:
}
/*
* Copy constructor
*/
FUnifM2LHandler(const FUnifM2LHandler& other)
: FC(other.FC),
TreeHeight(other.TreeHeight),
RootCellWidth(other.RootCellWidth),
Dft(), opt_rc(other.opt_rc)
{
// init DFT
const int steps[dimfft] = {rc};
Dft.buildDFT(steps);
// copy node_diff
memcpy(node_diff,other.node_diff,sizeof(unsigned int)*nnodes*nnodes);
}
~FUnifM2LHandler()
{
for (unsigned int l=0; l<TreeHeight; ++l)
......
......@@ -184,7 +184,7 @@ static void Compute(const MatrixKernelClass *const MatrixKernel,
template <int ORDER, class MatrixKernelClass, KERNEL_FUNCTION_TYPE TYPE> class FUnifTensorialM2LHandler;
template <int ORDER, class MatrixKernelClass>
class FUnifTensorialM2LHandler<ORDER,MatrixKernelClass,HOMOGENEOUS> : FNoCopyable
class FUnifTensorialM2LHandler<ORDER,MatrixKernelClass,HOMOGENEOUS>
{
enum {order = ORDER,
nnodes = TensorTraits<ORDER>::nnodes,
......@@ -239,6 +239,22 @@ public:
ComputeAndSet(MatrixKernel);
}
/*
* Copy constructor
*/
FUnifTensorialM2LHandler(const FUnifTensorialM2LHandler& other)
: FC(other.FC),
CellWidthExtension(other.CellWidthExtension),
Dft(), opt_rc(other.opt_rc)
{
// init DFT
const int steps[dimfft] = {rc};
Dft.buildDFT(steps);
// copy node_diff
memcpy(node_diff,other.node_diff,sizeof(unsigned int)*nnodes*nnodes);
}
~FUnifTensorialM2LHandler()
{
for (unsigned int d=0; d<ncmp; ++d)
......@@ -358,7 +374,7 @@ public:
template <int ORDER, class MatrixKernelClass>
class FUnifTensorialM2LHandler<ORDER,MatrixKernelClass,NON_HOMOGENEOUS> : FNoCopyable
class FUnifTensorialM2LHandler<ORDER,MatrixKernelClass,NON_HOMOGENEOUS>
{
enum {order = ORDER,
nnodes = TensorTraits<ORDER>::nnodes,
......@@ -422,6 +438,25 @@ public:
ComputeAndSet(MatrixKernel);
}
/*
* Copy constructor
*/
FUnifTensorialM2LHandler(const FUnifTensorialM2LHandler& other)
: FC(other.FC),
TreeHeight(other.TreeHeight),
RootCellWidth(other.RootCellWidth),
CellWidthExtension(other.CellWidthExtension),
Dft(), opt_rc(other.opt_rc)
{
// init DFT
const int steps[dimfft] = {rc};
Dft.buildDFT(steps);
// copy node_diff
memcpy(node_diff,other.node_diff,sizeof(unsigned int)*nnodes*nnodes);
}
~FUnifTensorialM2LHandler()
{
for (unsigned int l=0; l<TreeHeight; ++l)
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// 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".
// ===================================================================================
// ==== CMAKE =====
// @FUSE_BLAS
// ================
#include <iostream>
#include <cstdio>
#include "Utils/FParameters.hpp"
#include "Utils/FTic.hpp"
#include "Containers/FOctree.hpp"
//#include "Containers/FVector.hpp"
//#include "Components/FSimpleLeaf.hpp"
#include "Utils/FPoint.hpp"
#include "Files/FFmaGenericLoader.hpp"
#include "Files/FRandomLoader.hpp"
#include "Components/FBasicKernels.hpp"
#include "Components/FSimpleIndexedLeaf.hpp"
#include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "Adaptative/FAdaptiveCell.hpp"
#include "Adaptative/FAdaptiveKernelWrapper.hpp"
#include "Adaptative/FAbstractAdaptiveKernel.hpp"
//
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "Kernels/Uniform/FUnifCell.hpp"
#include "AdaptiveTree/FAdaptUnifKernel.hpp"
#include "AdaptiveTree/FAdaptTools.hpp"
//
//
#include "Core/FFmmAlgorithm.hpp"
//#include "Core/FFmmAlgorithmThread.hpp"
//#include "Core/FFmmAlgorithmTask.hpp"
/** This program show an example of use of the fmm basic algo
* it also check that each particles is impacted each other particles
*/
void usage() {
std::cout << "Driver to obtain statistics on the octree" << std::endl;
std::cout << "Options "<< std::endl
<< " -help to see the parameters " << std::endl
<< " -depth the depth of the octree "<< std::endl
<< " -subdepth specifies the size of the sub octree " << std::endl
<< " -fin name specifies the name of the particle distribution" << std::endl
<< " -sM s_min^M threshold for Multipole (l+1)^2 for Spherical harmonics"<<std::endl
<< " -sL s_min^L threshold for Local (l+1)^2 for Spherical harmonics"<<std::endl;
}
// Simply create particles and try the kernels
int main(int argc, char ** argv){
//
// accuracy
const unsigned int P = 3 ;
// typedef FTestCell CellClass;
// typedef FAdaptiveTestKernel< CellClass, ContainerClass > KernelClass;
typedef FUnifCell<P> CellClass;
typedef FP2PParticleContainerIndexed<> ContainerClass;
typedef FSimpleIndexedLeaf<ContainerClass> LeafClass;
typedef FInterpMatrixKernelR MatrixKernelClass;
//
typedef FAdaptiveUnifKernel<CellClass,ContainerClass,MatrixKernelClass,P> KernelClass;
//
//
typedef FAdaptiveCell< CellClass, ContainerClass > CellWrapperClass;
typedef FAdaptiveKernelWrapper< KernelClass, CellClass, ContainerClass > KernelWrapperClass;
typedef FOctree< CellWrapperClass, ContainerClass , LeafClass > OctreeClass;
// FFmmAlgorithmTask FFmmAlgorithmThread
typedef FFmmAlgorithm<OctreeClass, CellWrapperClass, ContainerClass, KernelWrapperClass, LeafClass > FmmClass;
///////////////////////What we do/////////////////////////////
std::cout << ">> This executable has to be used to test the FMM algorithm.\n";
//////////////////////////////////////////////////////////////
//
const int NbLevels = FParameters::getValue(argc,argv,"-depth", 7);
const int SizeSubLevels = FParameters::getValue(argc,argv,"subdepth", 3);
const int sminM = FParameters::getValue(argc,argv,"-sM", P*P*P);
const int sminL = FParameters::getValue(argc,argv,"-sL", P*P*P);
//
FTic counter;
//////////////////////////////////////////////////////////////////////////////////
// Not Random Loader
//////////////////////////////////////////////////////////////////////////////////
const std::string fileName(FParameters::getStr(argc,argv,"-fin", "../Data/prolate50.fma"));
FFmaGenericLoader loader(fileName);
const long int NbPart = loader.getNumberOfParticles() ;
// Random Loader
//const int NbPart = FParameters::getValue(argc,argv,"-nb", 2000000);
// FRandomLoader loader(NbPart, 1, FPoint(0.5,0.5,0.5), 1);
//////////////////////////////////////////////////////////////////////////////////
OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
std::cout << "Creating & Inserting " << NbPart << " particles ..." << std::endl;
std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;
std::cout << " criteria SM: "<< sminM <<std::endl
<< " criteria SL: "<< sminL <<std::endl <<std::endl;
//
{
counter.tic();
FReal L= loader.getBoxWidth();
FmaRParticle* particles= new FmaRParticle[NbPart];
FPoint minPos(L,L,L), maxPos(-L,-L,-L);
//
loader.fillParticle(particles,NbPart);
for(int idxPart = 0 ; idxPart < NbPart; ++idxPart){
const FPoint PP(particles[idxPart].getPosition() ) ;
//
minPos.setX(FMath::Min(minPos.getX(),PP.getX())) ;
minPos.setY(FMath::Min(minPos.getY(),PP.getY())) ;
minPos.setZ(FMath::Min(minPos.getZ(),PP.getZ())) ;
maxPos.setX(FMath::Max(maxPos.getX(),PP.getX())) ;
maxPos.setY(FMath::Max(maxPos.getY(),PP.getY())) ;
maxPos.setZ(FMath::Max(maxPos.getZ(),PP.getZ())) ;
//
tree.insert(PP, idxPart, particles[idxPart].getPhysicalValue());
}
counter.tac();
std::cout << "Data are inside the box delimited by "<<std::endl
<< " Min corner: "<< minPos<<std::endl
<< " Max corner: "<< maxPos<<std::endl <<std::endl;
std::cout << "Done " << "(@Creating and Inserting Particles = " << counter.elapsed() << " s)." << std::endl;
}
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
std::cout << "Working on particles ..." << std::endl;
counter.tic();
KernelWrapperClass kernels(NbLevels, loader.getBoxWidth(), loader.getCenterOfBox());; // FTestKernels FBasicKernels
FmmClass algo(&tree,&kernels); //FFmmAlgorithm FFmmAlgorithmThread
algo.execute();
counter.tac();
std::cout << "Done " << "(@Algorithm = " << counter.elapsed() << " s)." << std::endl;
OctreeClass::Iterator octreeIterator(&tree);
std::ofstream file("aa.tree", std::ofstream::out );
//
////////////////////////////////////////////////////////////////////
// Export adaptive tree in our format
////////////////////////////////////////////////////////////////////
//
// -----------------------------------------------------
//
//
// Set Global id
//
long int idCell = setGlobalID(tree);
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
tree.forEachCellLeaf([&](CellWrapperClass* cell, LeafClass* leaf){
file << "Cell Id " << cell->getGlobalId( ) << " Nb particles "<< leaf->getSrc()->getNbParticles()<<std::endl;
});
octreeIterator.gotoTop() ; // here we are at level 1 (first child)
// octreeIterator.moveDown() ;
octreeIterator.gotoLeft();
// octreeIterator.moveDown() ; // We are at the levell 2
std::cout << " Number of Cells: " << idCell <<std::endl;
//
std::cout << "Top of the octree " << octreeIterator.level() << std::endl ;
for(int idxLevel = 1; idxLevel < NbLevels ; ++idxLevel){
file << std::endl << "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"<< std::endl;
file << " Level " << idxLevel <<" Level "<< octreeIterator.level()<< " -- leave level " << std::boolalpha << octreeIterator.isAtLeafLevel() << std::endl;
do{
if(octreeIterator.getCurrentCell()->hasDevelopment()){
file <<"Cell id "<< octreeIterator.getCurrentCell()->getGlobalId( ) << " "<<*(octreeIterator.getCurrentCell())<< std::endl ;
}
} while(octreeIterator.moveRight());
octreeIterator.moveDown() ;
octreeIterator.gotoLeft();
}
std::cout << " END " << std::endl;
// Check
octreeIterator.gotoBottomLeft();
do {
std::cout << " Level " <<octreeIterator.level() <<std::endl;
}while(octreeIterator.moveUp() );
std::cout << " RETURN 0 " << std::endl;
return 0;
}
......@@ -33,15 +33,13 @@ dd=$1
# RUN 1 influence de la taille de la boite sur la precision des calculs
# Regarde size, Nx ny nz energie total, dipole et le temps de calcul
#
PER_SIZE="0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18"
#
pwd
FMMPER_EXE=${FMMPER_GEN_EXE}
rm -f FMM_PER_${DEGRE}.out
echo "# PerSize DOMAIN_SIZE ENERGY"> FMM_PER_${dd}.out
for l in $PER_SIZE
for l in {0..18}
do
OUTPUT=OUTPUT-${dd}-${l}.out
echo "Running per = " ${l}
......
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