Commit c82fe260 authored by BLANCHARD Pierre's avatar BLANCHARD Pierre

Major modification! Defined rigoreous target-source convention: p(x)=sum_y...

Major modification! Defined rigoreous target-source convention: p(x)=sum_y K(x,y)w(y) with x=target and y=source. Direct computation is done by calling MutualParticles(Target params,Source params) or P2P(Target, Source); Kernel matrices evaluation is done by calling evaluate(x=target,y=source) which returns k(x,y)=k(x-y).
parent 14a6b1c0
......@@ -134,13 +134,13 @@ int main(int argc, char ** argv){
//
for(int idxOther = 0; idxOther < nbParticles ; ++idxOther){
if( idxOther != idxTarget ){
FP2P::NonMutualParticles(
particles[idxOther].getPosition().getX(), particles[idxOther].getPosition().getY(),
particles[idxOther].getPosition().getZ(),particles[idxOther].getPhysicalValue(),
particles[idxTarget].getPosition().getX(), particles[idxTarget].getPosition().getY(),
particles[idxTarget].getPosition().getZ(),particles[idxTarget].getPhysicalValue(),
&particles[idxTarget].setForces()[0],&particles[idxTarget].setForces()[1],
&particles[idxTarget].setForces()[2],particles[idxTarget].setPotential(),&MatrixKernel);
FP2P::NonMutualParticles(particles[idxTarget].getPosition().getX(), particles[idxTarget].getPosition().getY(),
particles[idxTarget].getPosition().getZ(),particles[idxTarget].getPhysicalValue(),
&particles[idxTarget].setForces()[0],&particles[idxTarget].setForces()[1],
&particles[idxTarget].setForces()[2],particles[idxTarget].setPotential(),
particles[idxOther].getPosition().getX(), particles[idxOther].getPosition().getY(),
particles[idxOther].getPosition().getZ(),particles[idxOther].getPhysicalValue(),
&MatrixKernel);
}
}
} // end for
......
......@@ -40,15 +40,16 @@ enum KERNEL_FUNCTION_TYPE {HOMOGENEOUS, NON_HOMOGENEOUS};
* It can either be scalar (NCMP=1) or tensorial (NCMP>1) depending on the
* dimension of the equation considered. NCMP denotes the number of components
* that are actually stored (e.g. 6 for a \f$3\times3\f$ symmetric tensor).
* Notes on application scheme:
* 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.
*
* Notes on the application scheme:
* Let there be a kernel \f$K\f$ such that \f$Potential_i(X)X=K_{ij}(X,Y)PhysicalValue_j(Y)\f$
* with \f$Potential\f$ the lhs of size NLHS and \f$PhysicalValues\f$ the rhs of size NRHS.
* The table applyTab provides the indices in the reduced storage table
* 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
* only 1 set of M2L ops can be used for all levels??
* only 1 set of M2L opt can be used for all levels??
*
*/
template <class FReal>
......@@ -76,52 +77,61 @@ struct FInterpMatrixKernelR : FInterpAbstractMatrixKernel<FReal>
FInterpMatrixKernelR() {}
// copy ctor
FInterpMatrixKernelR(const FInterpMatrixKernelR& /*other*/)
{}
FInterpMatrixKernelR(const FInterpMatrixKernelR& /*other*/) {}
static const char* getID() { return "ONE_OVER_R"; }
static const char* getID() { return "ONE_OVER_R"; }
static void printInfo() { std::cout << "K(x,y)=1/r with r=|x-y|" << std::endl; }
// returns position in reduced storage
int getPosition(const unsigned int) const
{return 0;}
// returns coefficient of mutual interaction
// 1 for symmetric kernels
// -1 for antisymmetric kernels
// somethings else if other property of symmetry
FReal getMutualCoefficient() const{ return FReal(1.); }
// evaluate interaction
template <class ValueClass>
ValueClass evaluate(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2) const
ValueClass evaluate(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs) const
{
const ValueClass diffx = (x1-x2);
const ValueClass diffy = (y1-y2);
const ValueClass diffz = (z1-z2);
// diff = t-s
const ValueClass diffx = (xt-xs);
const ValueClass diffy = (yt-ys);
const ValueClass diffz = (zt-zs);
return FMath::One<ValueClass>() / FMath::Sqrt(diffx*diffx + diffy*diffy + diffz*diffz);
}
// evaluate interaction (blockwise)
template <class ValueClass>
void evaluateBlock(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2, ValueClass* block) const
void evaluateBlock(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs,
ValueClass* block) const
{
block[0] = this->evaluate(x1,y1,z1,x2,y2,z2);
block[0] = this->evaluate(xt,yt,zt,xs,ys,zs);
}
// evaluate interaction and derivative (blockwise)
template <class ValueClass>
void evaluateBlockAndDerivative(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2,
void evaluateBlockAndDerivative(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs,
ValueClass block[1], ValueClass blockDerivative[3]) const
{
const ValueClass diffx = (x1-x2);
const ValueClass diffy = (y1-y2);
const ValueClass diffz = (z1-z2);
const ValueClass diffx = (xt-xs);
const ValueClass diffy = (yt-ys);
const ValueClass diffz = (zt-zs);
const ValueClass one_over_r = FMath::One<ValueClass>() / FMath::Sqrt(diffx*diffx + diffy*diffy + diffz*diffz);
const ValueClass one_over_r3 = one_over_r*one_over_r*one_over_r;
block[0] = one_over_r;
blockDerivative[0] = one_over_r3 * diffx;
blockDerivative[1] = one_over_r3 * diffy;
blockDerivative[2] = one_over_r3 * diffz;
blockDerivative[0] = - one_over_r3 * diffx;
blockDerivative[1] = - one_over_r3 * diffy;
blockDerivative[2] = - one_over_r3 * diffz;
}
FReal getScaleFactor(const FReal RootCellWidth, const int TreeLevel) const
......@@ -135,15 +145,15 @@ struct FInterpMatrixKernelR : FInterpAbstractMatrixKernel<FReal>
return FReal(2.) / CellWidth;
}
FReal evaluate(const FPoint<FReal>& p1, const FPoint<FReal>& p2) const {
return evaluate<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ());
FReal evaluate(const FPoint<FReal>& pt, const FPoint<FReal>& ps) const {
return evaluate<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ());
}
void evaluateBlock(const FPoint<FReal>& p1, const FPoint<FReal>& p2, FReal* block) const{
evaluateBlock<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block);
void evaluateBlock(const FPoint<FReal>& pt, const FPoint<FReal>& ps, FReal* block) const{
evaluateBlock<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ(), block);
}
void evaluateBlockAndDerivative(const FPoint<FReal>& p1, const FPoint<FReal>& p2,
void evaluateBlockAndDerivative(const FPoint<FReal>& pt, const FPoint<FReal>& ps,
FReal block[1], FReal blockDerivative[3]) const {
evaluateBlockAndDerivative<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block, blockDerivative);
evaluateBlockAndDerivative<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ(), block, blockDerivative);
}
};
......@@ -158,24 +168,27 @@ struct FInterpMatrixKernelRH :FInterpMatrixKernelR<FReal>{
static const unsigned int NLHS = 1; //< dim of loc exp
FReal LX,LY,LZ ;
FInterpMatrixKernelRH() : LX(1.0),LY(1.0),LZ(1.0)
{ }
FInterpMatrixKernelRH()
: LX(1.0),LY(1.0),LZ(1.0)
{ }
// copy ctor
FInterpMatrixKernelRH(const FInterpMatrixKernelRH& other)
:FInterpMatrixKernelR<FReal>(other), LX(other.LX), LY(other.LY), LZ(other.LZ)
: FInterpMatrixKernelR<FReal>(other), LX(other.LX), LY(other.LY), LZ(other.LZ)
{}
static const char* getID() { return "ONE_OVER_RH"; }
static const char* getID() { return "ONE_OVER_RH"; }
static void printInfo() { std::cout << "K(x,y)=1/rh with rh=sqrt(L_i*(x_i-y_i)^2)" << std::endl; }
// evaluate interaction
template <class ValueClass>
ValueClass evaluate(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2) const
ValueClass evaluate(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs) const
{
const ValueClass diffx = (x1-x2);
const ValueClass diffy = (y1-y2);
const ValueClass diffz = (z1-z2);
const ValueClass diffx = (xt-xs);
const ValueClass diffy = (yt-ys);
const ValueClass diffz = (zt-zs);
return FMath::One<ValueClass>() / FMath::Sqrt(FMath::ConvertTo<ValueClass,FReal>(LX)*diffx*diffx +
FMath::ConvertTo<ValueClass,FReal>(LY)*diffy*diffy +
FMath::ConvertTo<ValueClass,FReal>(LZ)*diffz*diffz);
......@@ -185,23 +198,29 @@ struct FInterpMatrixKernelRH :FInterpMatrixKernelR<FReal>{
// returns position in reduced storage
int getPosition(const unsigned int) const
{return 0;}
// returns coefficient of mutual interaction
// 1 for symmetric kernels
// -1 for antisymmetric kernels
// somethings else if other property of symmetry
FReal getMutualCoefficient() const{ return FReal(1.); }
template <class ValueClass>
void evaluateBlock(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2, ValueClass* block) const
void evaluateBlock(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs,
ValueClass* block) const
{
block[0]=this->evaluate(x1,y1,z1,x2,y2,z2);
block[0]=this->evaluate(xt,yt,zt,xs,ys,zs);
}
// evaluate interaction and derivative (blockwise)
template <class ValueClass>
void evaluateBlockAndDerivative(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2,
void evaluateBlockAndDerivative(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs,
ValueClass block[1], ValueClass blockDerivative[3]) const
{
const ValueClass diffx = (x1-x2);
const ValueClass diffy = (y1-y2);
const ValueClass diffz = (z1-z2);
const ValueClass diffx = (xt-xs);
const ValueClass diffy = (yt-ys);
const ValueClass diffz = (zt-zs);
const ValueClass one_over_rL = FMath::One<ValueClass>() / FMath::Sqrt(FMath::ConvertTo<ValueClass,FReal>(LX)*diffx*diffx +
FMath::ConvertTo<ValueClass,FReal>(LY)*diffy*diffy +
FMath::ConvertTo<ValueClass,FReal>(LZ)*diffz*diffz);
......@@ -226,15 +245,15 @@ struct FInterpMatrixKernelRH :FInterpMatrixKernelR<FReal>{
return FReal(2.) / CellWidth;
}
FReal evaluate(const FPoint<FReal>& p1, const FPoint<FReal>& p2) const{
return evaluate<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ());
FReal evaluate(const FPoint<FReal>& pt, const FPoint<FReal>& ps) const{
return evaluate<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ());
}
void evaluateBlock(const FPoint<FReal>& p1, const FPoint<FReal>& p2, FReal* block) const{
evaluateBlock<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block);
void evaluateBlock(const FPoint<FReal>& pt, const FPoint<FReal>& ps, FReal* block) const{
evaluateBlock<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ(), block);
}
void evaluateBlockAndDerivative(const FPoint<FReal>& p1, const FPoint<FReal>& p2,
void evaluateBlockAndDerivative(const FPoint<FReal>& pt, const FPoint<FReal>& ps,
FReal block[1], FReal blockDerivative[3]) const {
evaluateBlockAndDerivative<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block, blockDerivative);
evaluateBlockAndDerivative<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ(), block, blockDerivative);
}
};
......@@ -253,48 +272,52 @@ struct FInterpMatrixKernelRR : FInterpAbstractMatrixKernel<FReal>
FInterpMatrixKernelRR() {}
// copy ctor
FInterpMatrixKernelRR(const FInterpMatrixKernelRR& /*other*/)
{}
FInterpMatrixKernelRR(const FInterpMatrixKernelRR& /*other*/) {}
static const char* getID() { return "ONE_OVER_R_SQUARED"; }
static const char* getID() { return "ONE_OVER_R_SQUARED"; }
static void printInfo() { std::cout << "K(x,y)=1/r^2 with r=|x-y|" << std::endl; }
// returns position in reduced storage
int getPosition(const unsigned int) const
{return 0;}
// returns coefficient of mutual interaction
// 1 for symmetric kernels
// -1 for antisymmetric kernels
// somethings else if other property of symmetry
FReal getMutualCoefficient() const{ return FReal(1.); }
// evaluate interaction
template <class ValueClass>
ValueClass evaluate(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2) const
ValueClass evaluate(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs) const
{
const ValueClass diffx = (x1-x2);
const ValueClass diffy = (y1-y2);
const ValueClass diffz = (z1-z2);
return FMath::One<ValueClass>() / FReal(diffx*diffx +
diffy*diffy +
diffz*diffz);
const ValueClass diffx = (xt-xs);
const ValueClass diffy = (yt-ys);
const ValueClass diffz = (zt-zs);
return FMath::One<ValueClass>() / FReal(diffx*diffx+diffy*diffy+diffz*diffz);
}
// evaluate interaction (blockwise)
template <class ValueClass>
void evaluateBlock(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2, ValueClass* block) const
void evaluateBlock(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs,
ValueClass* block) const
{
block[0]=this->evaluate(x1,y1,z1,x2,y2,z2);
block[0]=this->evaluate(xt,yt,zt,xs,ys,zs);
}
// evaluate interaction and derivative (blockwise)
template <class ValueClass>
void evaluateBlockAndDerivative(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2,
void evaluateBlockAndDerivative(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs,
ValueClass block[1], ValueClass blockDerivative[3]) const
{
const ValueClass diffx = (x1-x2);
const ValueClass diffy = (y1-y2);
const ValueClass diffz = (z1-z2);
const ValueClass r2 = (diffx*diffx +
diffy*diffy +
diffz*diffz);
const ValueClass diffx = (xt-xs);
const ValueClass diffy = (yt-ys);
const ValueClass diffz = (zt-zs);
const ValueClass r2 = (diffx*diffx+diffy*diffy+diffz*diffz);
const ValueClass one_over_r2 = FMath::One<ValueClass>() / (r2);
const ValueClass one_over_r4 = one_over_r2*one_over_r2;
......@@ -318,15 +341,15 @@ struct FInterpMatrixKernelRR : FInterpAbstractMatrixKernel<FReal>
return FReal(4.) / (CellWidth*CellWidth);
}
FReal evaluate(const FPoint<FReal>& p1, const FPoint<FReal>& p2) const{
return evaluate<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ());
FReal evaluate(const FPoint<FReal>& pt, const FPoint<FReal>& ps) const{
return evaluate<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ());
}
void evaluateBlock(const FPoint<FReal>& p1, const FPoint<FReal>& p2, FReal* block) const{
evaluateBlock<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block);
void evaluateBlock(const FPoint<FReal>& pt, const FPoint<FReal>& ps, FReal* block) const{
evaluateBlock<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ(), block);
}
void evaluateBlockAndDerivative(const FPoint<FReal>& p1, const FPoint<FReal>& p2,
void evaluateBlockAndDerivative(const FPoint<FReal>& pt, const FPoint<FReal>& ps,
FReal block[1], FReal blockDerivative[3]) const {
evaluateBlockAndDerivative<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block, blockDerivative);
evaluateBlockAndDerivative<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ(), block, blockDerivative);
}
};
......@@ -346,26 +369,31 @@ struct FInterpMatrixKernelLJ : FInterpAbstractMatrixKernel<FReal>
FInterpMatrixKernelLJ() {}
// copy ctor
FInterpMatrixKernelLJ(const FInterpMatrixKernelLJ& /*other*/)
{}
FInterpMatrixKernelLJ(const FInterpMatrixKernelLJ& /*other*/) {}
static const char* getID() { return "LENNARD_JONES_POTENTIAL"; }
static const char* getID() { return "LENNARD_JONES_POTENTIAL"; }
static void printInfo() { std::cout << "K(x,y)=1/r with r=|x-y|" << std::endl; }
// returns position in reduced storage
int getPosition(const unsigned int) const
{return 0;}
// returns coefficient of mutual interaction
// 1 for symmetric kernels
// -1 for antisymmetric kernels
// somethings else if other property of symmetry
FReal getMutualCoefficient() const{ return FReal(1.); }
// evaluate interaction
template <class ValueClass>
ValueClass evaluate(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2) const
ValueClass evaluate(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs) const
{
const ValueClass diffx = (x1-x2);
const ValueClass diffy = (y1-y2);
const ValueClass diffz = (z1-z2);
const ValueClass r = FMath::Sqrt(diffx*diffx +
diffy*diffy +
diffz*diffz);
const ValueClass diffx = (xt-xs);
const ValueClass diffy = (yt-ys);
const ValueClass diffz = (zt-zs);
const ValueClass r = FMath::Sqrt(diffx*diffx+diffy*diffy+diffz*diffz);
const ValueClass r3 = r*r*r;
const ValueClass one_over_r6 = FMath::One<ValueClass>() / (r3*r3);
//return one_over_r6 * one_over_r6;
......@@ -375,24 +403,23 @@ struct FInterpMatrixKernelLJ : FInterpAbstractMatrixKernel<FReal>
// evaluate interaction (blockwise)
template <class ValueClass>
void evaluateBlock(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2, ValueClass* block) const
void evaluateBlock(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs,
ValueClass* block) const
{
block[0]=this->evaluate(x1,y1,z1,x2,y2,z2);
block[0]=this->evaluate(xt,yt,zt,xs,ys,zs);
}
// evaluate interaction and derivative (blockwise)
template <class ValueClass>
void evaluateBlockAndDerivative(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2,
void evaluateBlockAndDerivative(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs,
ValueClass block[1], ValueClass blockDerivative[3]) const
{
const ValueClass diffx = (x1-x2);
const ValueClass diffy = (y1-y2);
const ValueClass diffz = (z1-z2);
const ValueClass r = FMath::Sqrt(diffx*diffx +
diffy*diffy +
diffz*diffz);
const ValueClass diffx = (xt-xs);
const ValueClass diffy = (yt-ys);
const ValueClass diffz = (zt-zs);
const ValueClass r = FMath::Sqrt(diffx*diffx+diffy*diffy+diffz*diffz);
const ValueClass r2 = r*r;
const ValueClass r3 = r2*r;
const ValueClass one_over_r6 = FMath::One<ValueClass>() / (r3*r3);
......@@ -421,15 +448,15 @@ struct FInterpMatrixKernelLJ : FInterpAbstractMatrixKernel<FReal>
FReal evaluate(const FPoint<FReal>& p1, const FPoint<FReal>& p2) const{
return evaluate<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ());
FReal evaluate(const FPoint<FReal>& pt, const FPoint<FReal>& ps) const{
return evaluate<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ());
}
void evaluateBlock(const FPoint<FReal>& p1, const FPoint<FReal>& p2, FReal* block) const{
evaluateBlock<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block);
void evaluateBlock(const FPoint<FReal>& pt, const FPoint<FReal>& ps, FReal* block) const{
evaluateBlock<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ(), block);
}
void evaluateBlockAndDerivative(const FPoint<FReal>& p1, const FPoint<FReal>& p2,
void evaluateBlockAndDerivative(const FPoint<FReal>& pt, const FPoint<FReal>& ps,
FReal block[1], FReal blockDerivative[3]) const {
evaluateBlockAndDerivative<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block, blockDerivative);
evaluateBlockAndDerivative<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ(), block, blockDerivative);
}
};
......@@ -449,54 +476,59 @@ struct FInterpMatrixKernelAPLUSRR : FInterpAbstractMatrixKernel<FReal>
FInterpMatrixKernelAPLUSRR(const FReal inCoreWidth = .25)
: CoreWidth(inCoreWidth)
{}
{}
// copy ctor
FInterpMatrixKernelAPLUSRR(const FInterpMatrixKernelAPLUSRR& other)
: CoreWidth(other.CoreWidth)
{}
static const char* getID() { return "ONE_OVER_A_PLUS_RR"; }
static const char* getID() { return "ONE_OVER_A_PLUS_RR"; }
static void printInfo() { std::cout << "K(x,y)=1/r with r=|x-y|" << std::endl; }
// returns position in reduced storage
int getPosition(const unsigned int) const
{return 0;}
// returns coefficient of mutual interaction
// 1 for symmetric kernels
// -1 for antisymmetric kernels
// somethings else if other property of symmetry
FReal getMutualCoefficient() const{ return FReal(1.); }
// evaluate interaction
template <class ValueClass>
ValueClass evaluate(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2) const
ValueClass evaluate(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs) const
{
const ValueClass diffx = (x1-x2);
const ValueClass diffy = (y1-y2);
const ValueClass diffz = (z1-z2);
return FMath::One<ValueClass>() / (FMath::ConvertTo<ValueClass,FReal>(CoreWidth) + // WHY FReal??
diffx*diffx +
diffy*diffy +
diffz*diffz);
const ValueClass diffx = (xt-xs);
const ValueClass diffy = (yt-ys);
const ValueClass diffz = (zt-zs);
const ValueClass r2 = (diffx*diffx+diffy*diffy+diffz*diffz);
return FMath::One<ValueClass>() / (r2 + FMath::ConvertTo<ValueClass,FReal>(CoreWidth));
}
// evaluate interaction (blockwise)
template <class ValueClass>
void evaluateBlock(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2, ValueClass* block) const
void evaluateBlock(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs,
ValueClass* block) const
{
block[0]=this->evaluate(x1,y1,z1,x2,y2,z2);
block[0]=this->evaluate(xt,yt,zt,xs,ys,zs);
}
// evaluate interaction and derivative (blockwise)
template <class ValueClass>
void evaluateBlockAndDerivative(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2,
void evaluateBlockAndDerivative(const ValueClass& xt, const ValueClass& yt, const ValueClass& zt,
const ValueClass& xs, const ValueClass& ys, const ValueClass& zs,
ValueClass block[1], ValueClass blockDerivative[3]) const
{
const ValueClass diffx = (x1-x2);
const ValueClass diffy = (y1-y2);
const ValueClass diffz = (z1-z2);
const ValueClass r2 = (diffx*diffx +
diffy*diffy +
diffz*diffz);
const ValueClass one_over_a_plus_r2 = FMath::One<ValueClass>() / (FMath::ConvertTo<ValueClass,FReal>(CoreWidth)+r2);
const ValueClass diffx = (xt-xs);
const ValueClass diffy = (yt-ys);
const ValueClass diffz = (zt-zs);
const ValueClass r2 = (diffx*diffx+diffy*diffy+diffz*diffz);
const ValueClass one_over_a_plus_r2 = FMath::One<ValueClass>() / (r2 + FMath::ConvertTo<ValueClass,FReal>(CoreWidth));
const ValueClass one_over_a_plus_r2_squared = one_over_a_plus_r2*one_over_a_plus_r2;
block[0] = one_over_a_plus_r2;
......@@ -521,240 +553,22 @@ struct FInterpMatrixKernelAPLUSRR : FInterpAbstractMatrixKernel<FReal>
return FReal(1.0);
}
FReal evaluate(const FPoint<FReal>& p1, const FPoint<FReal>& p2) const{
return evaluate<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ());
FReal evaluate(const FPoint<FReal>& pt, const FPoint<FReal>& ps) const{
return evaluate<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ());
}
void evaluateBlock(const FPoint<FReal>& p1, const FPoint<FReal>& p2, FReal* block) const{
evaluateBlock<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block);
void evaluateBlock(const FPoint<FReal>& pt, const FPoint<FReal>& ps, FReal* block) const{
evaluateBlock<FReal>(pt.getX(), pt.getY(), pt.getZ(), ps.getX(), ps.getY(), ps.getZ(), block);
}
void evaluateBlockAndDerivative(const FPoint<FReal>& p1, const FPoint<FReal>& p2,
void evaluateBlockAndDerivative(const FPoint<FReal>& pt, const FPoint<FReal>& ps,
FReal block[1], FReal blockDerivative[3]) const {
evaluateBlockAndDerivative<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block, blockDerivative);
evaluateBlockAndDerivative<FReal>(pt.