Commit df89a39a authored by PIACIBELLO Cyrille's avatar PIACIBELLO Cyrille
parents 2a4e97de 6d1a89c0
I don't know if theses ideas are relevant since ScallFMM is only supposed to be a library, but as an everyday UNIX // GNU/Linux user, some things struck me.
* About the -f / -infile / -fin argument
For some reason, all tests have similar arguments that differs in name from one to another.
I suggest that this should be standardized as "-if" for "input file" and "-of" for "output file" just like in the dd UNIX command.
Therefore we won't spend anymore time wondering what the proper argument for the tool is.
* About arguments in general
Maybe it would be clearer to use one or two letters when using a single hyphen-minus and full words when using a double hyphen-minus.
Here's an exemple to make my idea clearer:
-h | --help
-v | --verbose
-d | --depth
-sd | --subdepth
-if | --input
-of | --output
etc...
......@@ -42,7 +42,7 @@
#ifdef _OPENMP
#include "Core/FFmmAlgorithmThread.hpp"
#else
#include "Core/FFmmAlgorithmThread.hpp"
#include "Core/FFmmAlgorithm.hpp"
#endif
/**
......
......@@ -83,8 +83,8 @@ void genDistusage() {
<< " Distributions " << std::endl
<< " Uniform on " << std::endl
<< " -unitCube uniform distribution on unit cube" <<std::endl
<< " -cuboid uniform distribution on rectangular cuboid of size a:a:c" <<std::endl
<< " -lengths a:a:c - default value for R is 1.0:1.0:2.0" <<std::endl
<< " -cuboid uniform distribution on rectangular cuboid of size a:b:c" <<std::endl
<< " -lengths a:b:c - default values are 1.0:1.0:2.0" <<std::endl
<< " -unitSphere uniform distribution on unit sphere" <<std::endl
<< " -sphere uniform distribution on sphere of radius given by" <<std::endl
<< " -radius R - default value for R is 2.0" <<std::endl
......@@ -163,7 +163,7 @@ int main(int argc, char ** argv){
std::string dd(":"),aspectRatio = FParameters::getStr(argc,argv,"-lengths", "1:1:2");
FReal A,B,C ;
size_t pos = aspectRatio.find(":"); aspectRatio.replace(pos,1," ");
pos = aspectRatio.find(":"); aspectRatio.replace(pos,1," ");
pos = aspectRatio.find(":"); aspectRatio.replace(pos,1," ");
std::stringstream ss(aspectRatio); ss >>A >> B >> C ;
unifRandonPointsOnCube(NbPoints, A,B,C,particles) ;
BoxWith = FMath::Max(A,FMath::Max(B,C) );
......@@ -232,7 +232,8 @@ int main(int argc, char ** argv){
else {
name += ".fma";
}
FFmaGenericWriter writer(name,binaryMode) ;
std::cout << "Write "<< NbPoints <<" Particles in file " << name <<std::endl;
FFmaGenericWriter writer(name) ;
writer.writeHeader(Centre,BoxWith, NbPoints, *ppart) ;
writer.writeArrayOfParticles(ppart, NbPoints);
//
......
......@@ -56,17 +56,21 @@ public:
FPoint getPosition() const{
return FPoint(data[0],data[1],data[2]);
}
/* //Get a FPoint from the position
FPoint* getPosition() {
return static_cast<FPoint* >(&data);
}*/
//Set the position from a FPoint
/// Set the position from a FPoint
void setPosition(FPoint & inPoint){
data[0] = inPoint.getX();
data[1] = inPoint.getY();
data[2] = inPoint.getZ();
}
//Set the position from a three FReal values
void setPosition(const FReal& inX, const FReal& inY, const FReal &inZ){
data[0] = inX;
data[1] = inY;
data[2] = inZ;
}
//Get a FReal from the physicalValue
FReal getPhysicalValue() const{
return data[3];
......@@ -76,6 +80,10 @@ public:
FReal* setPhysicalValue() {
return &data[3];
}
//Set the physicalValue
void setPhysicalValue(const FReal& Q) {
data[3] = Q;
}
//Get a FReal from the potential
FReal getPotential() const{
......@@ -88,7 +96,11 @@ public:
FAssertLF(WRITE>4,"Cannot set Potential with WRITE<=4");
return &data[4];
}
// Set the potential
void setPotential(const FReal& P) {
FAssertLF(WRITE>4,"Cannot set Potential with WRITE<=4");
data[4] = P;
}
//Get a ptr to read the forces
FReal* getForces() {
FAssertLF(WRITE>7,"Cannot access to forces[] with READ<=8");
......@@ -100,6 +112,14 @@ public:
FAssertLF(WRITE>7,"Cannot set Forces[] with WRITE<=7");
return &data[5];
}
//Set the forces from three values
void setForces(const FReal& inFX, const FReal& inFY, const FReal &inFZ){
FAssertLF(WRITE>7,"Cannot set Forces[] with WRITE<=7");
data[5] = inFX;
data[6] = inFY;
data[7] = inFZ;
}
//Get directly a ptr to the data
FReal * getPtrFirstData(){
......@@ -481,6 +501,13 @@ public:
template <class dataPart>
void fillParticle(dataPart *dataToRead, const int N){
int otherDataRead = typeData[1] - (*dataToRead).getReadDataNumber() ;
if (otherDataRead < 0){
std::cerr << " Error in fFFmaGenericLoader::illParticle(dataPart *dataToRead, const int N)" <<std::endl
<< " Wrong number of value to read, Expected (in file) " << typeData[1]
<< " asked in structure " <<(*dataToRead).getReadDataNumber() <<std::endl;
std::exit(EXIT_FAILURE);
}
std::cout << " typeData[1] "<< typeData[1] << " "<<(*dataToRead).getReadDataNumber() <<" otherDataRead "<<otherDataRead <<std::endl;
if(binaryFile && otherDataRead == 0 ){
file->read((char*)((*dataToRead).getPtrFirstData()), sizeof(FReal)*(N*(*dataToRead).getReadDataNumber()));
}
......
......@@ -50,7 +50,7 @@ protected:
/// Needed for P2M, M2M, L2L and L2P operators
const FSmartPointer<InterpolatorClass,FSmartPointerMemory> Interpolator;
/// Needed for P2P operator
const FSmartPointer<MatrixKernelClass,FSmartPointerMemory> MatrixKernel;
/*const*/ FSmartPointer<MatrixKernelClass,FSmartPointerMemory> MatrixKernel;
/// Height of the entire oct-tree
const unsigned int TreeHeight;
/// Corner of oct-tree box
......@@ -63,7 +63,7 @@ protected:
const FReal BoxWidthExtension;
/// Parameter to pass to matrix kernel (material specific or anything)
const double MatParam;
const FReal MatParam;
/**
* Compute center of leaf cell from its tree coordinate.
......@@ -87,7 +87,7 @@ public:
const FReal inBoxWidth,
const FPoint& inBoxCenter,
const FReal inBoxWidthExtension = 0.0,
const double inMatParam = 0.0)
const FReal inMatParam = 0.0)
: Interpolator(new InterpolatorClass(inTreeHeight,
inBoxWidth,
inBoxWidthExtension)),
......@@ -109,6 +109,10 @@ public:
const InterpolatorClass * getPtrToInterpolator() const
{ return Interpolator.getPtr(); }
MatrixKernelClass * getPtrMatrixKernel()
{return MatrixKernel; }
virtual void P2M(CellClass* const LeafCell,
const ContainerClass* const SourceParticles) = 0;
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
// Copyright ScalFmm 2011 INRIA
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the FMM.
//
......
......@@ -18,18 +18,19 @@
#include <stdexcept>
#include "../../Utils/FPoint.hpp"
#include "../../Utils/FNoCopyable.hpp"
#include "../../Utils/FMath.hpp"
#include "../../Utils/FBlas.hpp"
#include "Utils/FPoint.hpp"
#include "Utils/FNoCopyable.hpp"
#include "Utils/FMath.hpp"
#include "Utils/FBlas.hpp"
// extendable
enum KERNEL_FUNCTION_IDENTIFIER {ONE_OVER_R,
ONE_OVER_R_SQUARED,
LENNARD_JONES_POTENTIAL,
R_IJ,
R_IJK};
R_IJK,
ONE_OVER_RH
};
// probably not extendable :)
enum KERNEL_FUNCTION_TYPE {HOMOGENEOUS, NON_HOMOGENEOUS};
......@@ -50,7 +51,7 @@ enum KERNEL_FUNCTION_TYPE {HOMOGENEOUS, NON_HOMOGENEOUS};
* Let there be a kernel \f$K\f$ such that \f$X_i=K_{ij}Y_j\f$
* with \f$X\f$ the lhs of size NLHS and \f$Y\f$ the rhs of size NRHS.
* The table applyTab provides the indices in the reduced storage table
* corresponding to the application scheme depicted ealier.
* corresponding to the application scheme depicted earlier.
*
* PB: BEWARE! Homogeneous matrix kernels do not support cell width extension
* yet. Is it possible to find a reference width and a scale factor such that
......@@ -79,7 +80,7 @@ struct FInterpMatrixKernelR : FInterpAbstractMatrixKernel
static const unsigned int NRHS = 1; //< dim of mult exp
static const unsigned int NLHS = 1; //< dim of loc exp
FInterpMatrixKernelR(const double = 0.0, const unsigned int = 0) {}
FInterpMatrixKernelR(const FReal = 0.0, const unsigned int = 0) {}
// returns position in reduced storage
int getPosition(const unsigned int) const
......@@ -111,6 +112,50 @@ struct FInterpMatrixKernelR : FInterpAbstractMatrixKernel
};
/// One over r when the box size is rescaled to 1
struct FInterpMatrixKernelRH :FInterpMatrixKernelR{
static const KERNEL_FUNCTION_TYPE Type = HOMOGENEOUS;
static const KERNEL_FUNCTION_IDENTIFIER Identifier = ONE_OVER_RH;
static const unsigned int NCMP = 1; //< number of components
static const unsigned int NPV = 1; //< dim of physical values
static const unsigned int NPOT = 1; //< dim of potentials
static const unsigned int NRHS = 1; //< dim of mult exp
static const unsigned int NLHS = 1; //< dim of loc exp
FReal LX,LY,LZ ;
FInterpMatrixKernelRH(const FReal = 0.0, const unsigned int = 0) : LX(1.0),LY(1.0),LZ(1.0)
{ }
FReal evaluate(const FPoint& x, const FPoint& y) const
{
const FPoint xy(x-y);
return FReal(1.) / FMath::Sqrt(LX*xy.getX()*xy.getX() +
LY*xy.getY()*xy.getY() +
LZ*xy.getZ()*xy.getZ());
}
void setCoeff(const FReal& a, const FReal& b, const FReal& c)
{LX= a ; LY = b ; LZ = c ;}
// returns position in reduced storage
int getPosition(const unsigned int) const
{return 0;}
void evaluateBlock(const FPoint& x, const FPoint& y, FReal* block) const
{
block[0]=this->evaluate(x,y);
}
FReal getScaleFactor(const FReal RootCellWidth, const int TreeLevel) const
{
const FReal CellWidth(RootCellWidth / FReal(FMath::pow(2, TreeLevel)));
return getScaleFactor(CellWidth);
}
FReal getScaleFactor(const FReal CellWidth) const
{
return FReal(2.) / CellWidth;
}
};
/// One over r^2
......@@ -124,7 +169,7 @@ struct FInterpMatrixKernelRR : FInterpAbstractMatrixKernel
static const unsigned int NRHS = 1; //< dim of mult exp
static const unsigned int NLHS = 1; //< dim of loc exp
FInterpMatrixKernelRR(const double = 0.0, const unsigned int = 0) {}
FInterpMatrixKernelRR(const FReal = 0.0, const unsigned int = 0) {}
// returns position in reduced storage
int getPosition(const unsigned int) const
......@@ -168,7 +213,7 @@ struct FInterpMatrixKernelLJ : FInterpAbstractMatrixKernel
static const unsigned int NRHS = 1; //< dim of mult exp
static const unsigned int NLHS = 1; //< dim of loc exp
FInterpMatrixKernelLJ(const double = 0.0, const unsigned int = 0) {}
FInterpMatrixKernelLJ(const FReal = 0.0, const unsigned int = 0) {}
// returns position in reduced storage
int getPosition(const unsigned int) const
......@@ -257,9 +302,9 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel
const unsigned int _i,_j;
// Material Parameters
const double _CoreWidth2; // if >0 then kernel is NON homogeneous
const FReal _CoreWidth2; // if >0 then kernel is NON homogeneous
FInterpMatrixKernel_R_IJ(const double CoreWidth = 0.0, const unsigned int d = 0)
FInterpMatrixKernel_R_IJ(const FReal CoreWidth = 0.0, const unsigned int d = 0)
: _i(indexTab[d]), _j(indexTab[d+NCMP]), _CoreWidth2(CoreWidth*CoreWidth)
{}
......@@ -268,7 +313,7 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel
{return applyTab[n];}
// returns Core Width squared
double getCoreWidth2() const
FReal getCoreWidth2() const
{return _CoreWidth2;}
FReal evaluate(const FPoint& x, const FPoint& y) const
......@@ -278,7 +323,7 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel
xy.getY()*xy.getY() +
xy.getZ()*xy.getZ() + _CoreWidth2);
const FReal one_over_r3 = one_over_r*one_over_r*one_over_r;
double ri,rj;
FReal ri,rj;
if(_i==0) ri=xy.getX();
else if(_i==1) ri=xy.getY();
......@@ -304,7 +349,7 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel
xy.getY()*xy.getY() +
xy.getZ()*xy.getZ() + _CoreWidth2);
const FReal one_over_r3 = one_over_r*one_over_r*one_over_r;
const double r[3] = {xy.getX(),xy.getY(),xy.getZ()};
const FReal r[3] = {xy.getX(),xy.getY(),xy.getZ()};
for(unsigned int d=0;d<NCMP;++d){
unsigned int i = indexTab[d];
......@@ -354,9 +399,9 @@ struct FInterpMatrixKernel_R_IJK : FInterpAbstractMatrixKernel
const unsigned int _i,_j,_k;
// Material Parameters
const double _CoreWidth2; // if >0 then kernel is NON homogeneous
const FReal _CoreWidth2; // if >0 then kernel is NON homogeneous
FInterpMatrixKernel_R_IJK(const double CoreWidth = 0.0, const unsigned int d = 0)
FInterpMatrixKernel_R_IJK(const FReal CoreWidth = 0.0, const unsigned int d = 0)
: _i(indexTab[d]), _j(indexTab[d+NCMP]), _k(indexTab[d+2*NCMP]), _CoreWidth2(CoreWidth*CoreWidth)
{}
......@@ -365,7 +410,7 @@ struct FInterpMatrixKernel_R_IJK : FInterpAbstractMatrixKernel
{return applyTab[n];}
// returns Core Width squared
double getCoreWidth2() const
FReal getCoreWidth2() const
{return _CoreWidth2;}
FReal evaluate(const FPoint& x, const FPoint& y) const
......@@ -378,7 +423,7 @@ struct FInterpMatrixKernel_R_IJK : FInterpAbstractMatrixKernel
xy.getZ()*xy.getZ() + _CoreWidth2);
const FReal one_over_r2 = one_over_r*one_over_r;
const FReal one_over_r3 = one_over_r2*one_over_r;
double ri,rj,rk;
FReal ri,rj,rk;
if(_i==0) ri=xy.getX();
else if(_i==1) ri=xy.getY();
......@@ -425,7 +470,7 @@ struct FInterpMatrixKernel_R_IJK : FInterpAbstractMatrixKernel
const FReal one_over_r2 = one_over_r*one_over_r;
const FReal one_over_r3 = one_over_r2*one_over_r;
const double r[3] = {xy.getX(),xy.getY(),xy.getZ()};
const FReal r[3] = {xy.getX(),xy.getY(),xy.getZ()};
for(unsigned int d=0;d<NCMP;++d){
unsigned int i = indexTab[d];
......@@ -484,7 +529,7 @@ public:
const unsigned int _ny, const FPoint *const _py,
const FReal *const _weights = NULL,
const unsigned int idxK = 0,
const double matparam = 0.0)
const FReal matparam = 0.0)
: Kernel(matparam,idxK), nx(_nx), ny(_ny), px(_px), py(_py), weights(_weights) {}
void operator()(const unsigned int xbeg, const unsigned int xend,
......
......@@ -29,6 +29,25 @@ struct DirectInteractionComputer<ONE_OVER_R, 1>
}
};
//! Specialization for Laplace potential on Non uniform domain
template <>
struct DirectInteractionComputer<ONE_OVER_RH, 1>
{
template <typename ContainerClass>
static void P2P( ContainerClass* const FRestrict TargetParticles,
ContainerClass* const NeighborSourceParticles[27]){
FP2P::FullMutual(TargetParticles,NeighborSourceParticles,14);
}
//
template <typename ContainerClass>
static void P2PRemote( ContainerClass* const FRestrict inTargets,
ContainerClass* const inNeighbors[27],
const int inSize){
FP2P::FullRemote(inTargets,inNeighbors,inSize);
}
};
/*! Specialization for Lennard-Jones potential */
template <>
......
......@@ -174,7 +174,7 @@ public:
// allocate 8 arrays per level
ChildParentInterpolator = new FReal**[TreeHeight];
for (unsigned int l=0; l<TreeHeight; ++l){
for ( int l=0; l<TreeHeight; ++l){
ChildParentInterpolator[l] = new FReal*[8];
for (unsigned int c=0; c<8; ++c)
ChildParentInterpolator[l][c]=nullptr;
......@@ -207,7 +207,7 @@ public:
*/
~FUnifInterpolator()
{
for (unsigned int l=0; l<TreeHeight; ++l)
for ( int l=0; l<TreeHeight; ++l)
for (unsigned int child=0; child<8; ++child)
if(ChildParentInterpolator[l][child] != nullptr)
delete [] ChildParentInterpolator[l][child];
......
// ===================================================================================
// Copyright ScalFmm 2014 INRIA
//
// 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 FGENERATEDISTRIBUTION_HPP
#define FGENERATEDISTRIBUTION_HPP
// @author O. Coulaud
#include <cstdlib>
#include <ctime>
......@@ -54,7 +69,7 @@ void unifRandonPointsOnUnitCube(const int N , FReal * points) {
//! \param Lz the the Z-length of the cube
//! \param points array of size 4*N and stores data as follow x,y,z,0,x,y,z,0....
//! \example generateDistributions.cpp
void unifRandonPointsOnCube(const int N , const FReal Lx, const FReal Ly, const FReal Lz, FReal * points) {
void unifRandonPointsOnCube(const int& N , const FReal& Lx, const FReal &Ly, const FReal& Lz, FReal * points) {
//
unifRandonPointsOnUnitCube(N , points) ;
int j =0 ;
......
......@@ -41,7 +41,7 @@ private:
public:
/** Default constructor (sets position to 0/0/0) */
FPoint(){
data[0] = data[1] = data[2] = FReal(0);
data[0] = data[1] = data[2] = FReal(0.0);
}
/** Constructor from an array */
......@@ -243,7 +243,7 @@ public:
/**
* Affect to all dim the other position
* @param other the value to afect
* @param other the value to affect
* @return the current object after being affected
*/
FPoint& operator+=(const FPoint& other){
......@@ -252,10 +252,20 @@ public:
this->data[2] += other.data[2];
return *this;
}
/**
* Divide to all dim the other position
* @param other the value to affect
* @return the current object after being affected
*/
FPoint& operator/=(const FPoint& other){
this->data[0] /= other.data[0];
this->data[1] /= other.data[1];
this->data[2] /= other.data[2];
return *this;
}
/**
* Affect to all dim the other position
* @param other the value to afect
* @param other the value to affect
* @return the current object after being affected
*/
FPoint& operator*=(const FReal value){
......@@ -289,7 +299,7 @@ public:
/**
* Operator F3Position minus F3Position
* This substract one from anther
* This subtract one from anther
* @param inPosition the position to reduce
* @param inOther the position to decrease/substract inPosition
* @return the resulting position
......@@ -300,7 +310,7 @@ public:
/**
* Operator F3Position plus F3Position
* This substract one from anther
* This subtract one from anther
* @param inPosition the position to reduce
* @param inOther the position to increase inPosition
* @return the resulting position
......@@ -309,6 +319,7 @@ public:
return FPoint(inPosition.data[0] + inOther.data[0], inPosition.data[1] + inOther.data[1], inPosition.data[2] + inOther.data[2]);
}
/**
* Operator stream FPoint to std::ostream
* This can be used to simpldata[1] write out a position
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger 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".
// ===================================================================================
#ifndef FTEMPLATE_HPP
#define FTEMPLATE_HPP
///////////////////////////////////////////////////////////////////////////////////////
/// This file provide useful method to work with template.
/// It provide solution in order to build several methods
/// and run them accordingly to a given condition.
/// We recommand to look at the testTemplateExample.cpp in order
/// to see the usage.
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
/// FForAll : Compile all and exec all
///////////////////////////////////////////////////////////////////////////////////////
#include <functional>
namespace FForAll{
template <class IterType, const IterType CurrentIter, const IterType iterTo, const IterType IterStep,
class Func, bool IsNotOver, typename... Args>
struct Evaluator{
static void Run(Args... args){
Func::template For<CurrentIter>(args...);
Evaluator<IterType, CurrentIter+IterStep, iterTo, IterStep, Func, (CurrentIter+IterStep < iterTo), Args...>::Run(args...);
}
};
template <class IterType, const IterType CurrentIter, const IterType iterTo, const IterType IterStep,
class Func, typename... Args>
struct Evaluator< IterType, CurrentIter, iterTo, IterStep, Func, false, Args...>{
static void Run(Args... args){
}
};
template <class IterType, const IterType IterFrom, const IterType iterTo, const IterType IterStep,
class Func, typename... Args>
void For(Args... args){
Evaluator<IterType, IterFrom, iterTo, IterStep, Func, (IterFrom<iterTo), Args...>::Run(args...);
}
}
///////////////////////////////////////////////////////////////////////////////////////
/// FRunIf : Compile all and exec only one (if the template variable is equal to
/// the first variable)
///////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
namespace FRunIf{
template <class IterType, const IterType CurrentIter, const IterType iterTo, const IterType IterStep,
class Func, bool IsNotOver, typename... Args>
struct Evaluator{
static void Run(IterType value, Args... args){
if(CurrentIter == value){
Func::template Run<CurrentIter>(args...);
}
else{
Evaluator<IterType, CurrentIter+IterStep, iterTo, IterStep, Func, (CurrentIter+IterStep < iterTo), Args...>::Run(value, args...);
}
}
};
template <class IterType, const IterType CurrentIter, const IterType iterTo, const IterType IterStep,
class Func, typename... Args>
struct Evaluator< IterType, CurrentIter, iterTo, IterStep, Func, false, Args...>{
static void Run(IterType value, Args... args){
std::cout << __FUNCTION__ << " no matching value found\n";
}
};
template <class IterType, const IterType IterFrom, const IterType iterTo, const IterType IterStep,
class Func, typename... Args>
void Run(IterType value, Args... args){
Evaluator<IterType, IterFrom, iterTo, IterStep, Func, (IterFrom<iterTo), Args...>::Run(value, args...);
}
}
///////////////////////////////////////////////////////////////////////////////////////
/// FRunIfFunctional : Compile all and exec only those whose respect a condition
///////////////////////////////////////////////////////////////////////////////////////
namespace FRunIfFunctional{
template <class IterType, const IterType CurrentIter, const IterType iterTo, const IterType IterStep,
class Func, bool IsNotOver, typename... Args>
struct Evaluator{
static void Run(std::function<bool(IterType)> test, Args... args){
if(test(CurrentIter)){
Func::template Run<CurrentIter>(args...);
}
Evaluator<IterType, CurrentIter+IterStep, iterTo, IterStep, Func, (CurrentIter+IterStep < iterTo), Args...>::Run(test, args...);
}
};
template <class IterType, const IterType CurrentIter, const IterType iterTo, const IterType IterStep,
class Func, typename... Args>
struct Evaluator< IterType, CurrentIter, iterTo, IterStep, Func, false, Args...>{
static void Run(std::function<bool(IterType)> test, Args... args){
}
};
template <class IterType, const IterType IterFrom, const IterType iterTo, const IterType IterStep,
class Func, typename... Args>
void Run(std::function<bool(IterType)> test, Args... args){
Evaluator<IterType, IterFrom, iterTo, IterStep, Func, (IterFrom<iterTo), Args...>::Run(test, args...);
}
}
#endif // FTEMPLATE_HPP
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger 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".
// ===================================================================================