Commit a78cc320 authored by BLANCHARD Pierre's avatar BLANCHARD Pierre
Browse files

Fixed handling of non homogeneous kernels of interactions (aka matrix kernel)...

Fixed handling of non homogeneous kernels of interactions (aka matrix kernel) in Uniform kernel (TODO Fix in Chebyshev if relevant), Introduced blockwise evaluation of tensorial matrix kernel (+redesign precomputation), added input parameter in AbstractUnifKernel (for OptiDis non singular Ra_{ijk} or any matrix kernel requiring an extra parameter), +divers test fixing.
parent ca0bf8b8
...@@ -51,6 +51,16 @@ unsigned int Compress(const FReal epsilon, const unsigned int ninteractions, ...@@ -51,6 +51,16 @@ unsigned int Compress(const FReal epsilon, const unsigned int ninteractions,
* size \f$\ell^3\times r\f$, and \f$316\f$ \f$C_t\f$, each of size \f$r\times * size \f$\ell^3\times r\f$, and \f$316\f$ \f$C_t\f$, each of size \f$r\times
* r\f$. * r\f$.
* *
* PB: FChebM2LHandler does not seem to support non_homogeneous kernels!
* In fact nothing appears to handle this here (i.e. adapt scaling and storage
* to MatrixKernelClass::Type). Given the relatively important cost of the
* Chebyshev variant, it is probably a choice not to have implemented this
* feature here but instead in the ChebyshevSym variant. But what if the
* kernel is non homogeneous and non symmetric (e.g. Dislocations)...
*
* TODO Specialize class (see UnifM2LHandler) OR prevent from using this
* class with non homogeneous kernels ?!
*
* @tparam ORDER interpolation order \f$\ell\f$ * @tparam ORDER interpolation order \f$\ell\f$
*/ */
template <int ORDER, class MatrixKernelClass> template <int ORDER, class MatrixKernelClass>
......
...@@ -55,7 +55,7 @@ enum KERNEL_FUNCTION_TYPE {HOMOGENEOUS, NON_HOMOGENEOUS}; ...@@ -55,7 +55,7 @@ enum KERNEL_FUNCTION_TYPE {HOMOGENEOUS, NON_HOMOGENEOUS};
* *
*/ */
struct FInterpAbstractMatrixKernel : FNoCopyable struct FInterpAbstractMatrixKernel : FNoCopyable
{ {
virtual ~FInterpAbstractMatrixKernel(){} // to remove warning virtual ~FInterpAbstractMatrixKernel(){} // to remove warning
virtual FReal evaluate(const FPoint&, const FPoint&) const = 0; virtual FReal evaluate(const FPoint&, const FPoint&) const = 0;
// I need both functions because required arguments are not always given // I need both functions because required arguments are not always given
...@@ -68,13 +68,14 @@ struct FInterpAbstractMatrixKernel : FNoCopyable ...@@ -68,13 +68,14 @@ struct FInterpAbstractMatrixKernel : FNoCopyable
/// One over r /// One over r
struct FInterpMatrixKernelR : FInterpAbstractMatrixKernel struct FInterpMatrixKernelR : FInterpAbstractMatrixKernel
{ {
static const KERNEL_FUNCTION_TYPE Type = HOMOGENEOUS; static const KERNEL_FUNCTION_TYPE Type = /*NON_*/HOMOGENEOUS;
static const KERNEL_FUNCTION_IDENTIFIER Identifier = ONE_OVER_R; static const KERNEL_FUNCTION_IDENTIFIER Identifier = ONE_OVER_R;
static const unsigned int DIM = 1; //PB: dimension of kernel static const unsigned int DIM = 1; //PB: dimension of kernel
static const unsigned int NIDX = 1; //PB: number of indices
static const unsigned int NRHS = 1; static const unsigned int NRHS = 1;
static const unsigned int NLHS = 1; static const unsigned int NLHS = 1;
FInterpMatrixKernelR(const unsigned int = 0) {} FInterpMatrixKernelR(const double = 0.0, const unsigned int = 0) {}
// returns position in reduced storage // returns position in reduced storage
int getPosition(const unsigned int) const int getPosition(const unsigned int) const
...@@ -98,6 +99,19 @@ struct FInterpMatrixKernelR : FInterpAbstractMatrixKernel ...@@ -98,6 +99,19 @@ struct FInterpMatrixKernelR : FInterpAbstractMatrixKernel
{ {
return FReal(2.) / CellWidth; return FReal(2.) / CellWidth;
} }
// FReal getScaleFactor(const FReal, const int) const
// {
// // return 1 because non homogeneous kernel functions cannot be scaled!!!
// return FReal(1.);
// }
//
// FReal getScaleFactor(const FReal) const
// {
// // return 1 because non homogeneous kernel functions cannot be scaled!!!
// return FReal(1.);
// }
}; };
...@@ -108,10 +122,11 @@ struct FInterpMatrixKernelRR : FInterpAbstractMatrixKernel ...@@ -108,10 +122,11 @@ struct FInterpMatrixKernelRR : FInterpAbstractMatrixKernel
static const KERNEL_FUNCTION_TYPE Type = HOMOGENEOUS; static const KERNEL_FUNCTION_TYPE Type = HOMOGENEOUS;
static const KERNEL_FUNCTION_IDENTIFIER Identifier = ONE_OVER_R_SQUARED; static const KERNEL_FUNCTION_IDENTIFIER Identifier = ONE_OVER_R_SQUARED;
static const unsigned int DIM = 1; //PB: dimension of kernel static const unsigned int DIM = 1; //PB: dimension of kernel
static const unsigned int NIDX = 1; //PB: number of indices
static const unsigned int NRHS = 1; static const unsigned int NRHS = 1;
static const unsigned int NLHS = 1; static const unsigned int NLHS = 1;
FInterpMatrixKernelRR(const unsigned int = 0) {} FInterpMatrixKernelRR(const double = 0.0, const unsigned int = 0) {}
// returns position in reduced storage // returns position in reduced storage
int getPosition(const unsigned int) const int getPosition(const unsigned int) const
...@@ -145,10 +160,11 @@ struct FInterpMatrixKernelLJ : FInterpAbstractMatrixKernel ...@@ -145,10 +160,11 @@ struct FInterpMatrixKernelLJ : FInterpAbstractMatrixKernel
static const KERNEL_FUNCTION_TYPE Type = NON_HOMOGENEOUS; static const KERNEL_FUNCTION_TYPE Type = NON_HOMOGENEOUS;
static const KERNEL_FUNCTION_IDENTIFIER Identifier = LENNARD_JONES_POTENTIAL; static const KERNEL_FUNCTION_IDENTIFIER Identifier = LENNARD_JONES_POTENTIAL;
static const unsigned int DIM = 1; //PB: dimension of kernel static const unsigned int DIM = 1; //PB: dimension of kernel
static const unsigned int NIDX = 1; //PB: number of indices
static const unsigned int NRHS = 1; static const unsigned int NRHS = 1;
static const unsigned int NLHS = 1; static const unsigned int NLHS = 1;
FInterpMatrixKernelLJ(const unsigned int = 0) {} FInterpMatrixKernelLJ(const double = 0.0, const unsigned int = 0) {}
// returns position in reduced storage // returns position in reduced storage
int getPosition(const unsigned int) const int getPosition(const unsigned int) const
...@@ -193,7 +209,8 @@ struct FInterpMatrixKernel_IOR : FInterpAbstractMatrixKernel ...@@ -193,7 +209,8 @@ struct FInterpMatrixKernel_IOR : FInterpAbstractMatrixKernel
static const KERNEL_FUNCTION_TYPE Type = HOMOGENEOUS; static const KERNEL_FUNCTION_TYPE Type = HOMOGENEOUS;
static const KERNEL_FUNCTION_IDENTIFIER Identifier = ID_OVER_R; static const KERNEL_FUNCTION_IDENTIFIER Identifier = ID_OVER_R;
static const unsigned int DIM = 6; //PB: dimension of kernel static const unsigned int DIM = 6; //PB: dimension of kernel
const unsigned int indexTab[12]={0,0,0,1,1,2, static const unsigned int NIDX = 2; //PB: number of indices
static constexpr unsigned int indexTab[12]={0,0,0,1,1,2,
0,1,2,1,2,2}; 0,1,2,1,2,2};
static const unsigned int NRHS = 3; static const unsigned int NRHS = 3;
static const unsigned int NLHS = 3; static const unsigned int NLHS = 3;
...@@ -205,7 +222,7 @@ struct FInterpMatrixKernel_IOR : FInterpAbstractMatrixKernel ...@@ -205,7 +222,7 @@ struct FInterpMatrixKernel_IOR : FInterpAbstractMatrixKernel
const unsigned int _i,_j; const unsigned int _i,_j;
FInterpMatrixKernel_IOR(const unsigned int d = 0) FInterpMatrixKernel_IOR(const double = 0.0, const unsigned int d = 0)
: _i(indexTab[d]), _j(indexTab[d+DIM]) : _i(indexTab[d]), _j(indexTab[d+DIM])
{} {}
...@@ -225,6 +242,22 @@ struct FInterpMatrixKernel_IOR : FInterpAbstractMatrixKernel ...@@ -225,6 +242,22 @@ struct FInterpMatrixKernel_IOR : FInterpAbstractMatrixKernel
} }
void evaluateBlock(const FPoint& x, const FPoint& y, FReal* block) const
{
const FPoint xy(x-y);
const FReal one_over_r = FReal(1.)/xy.norm();
for(unsigned int d=0;d<DIM;++d){
// unsigned int i = indexTab[d];
// unsigned int j = indexTab[d+DIM];
// if(i==j)
block[d] = one_over_r;
// else
// block[d] = 0.0;
}
}
FReal getScaleFactor(const FReal RootCellWidth, const int TreeLevel) const FReal getScaleFactor(const FReal RootCellWidth, const int TreeLevel) const
{ {
const FReal CellWidth(RootCellWidth / FReal(FMath::pow(2, TreeLevel))); const FReal CellWidth(RootCellWidth / FReal(FMath::pow(2, TreeLevel)));
...@@ -246,19 +279,20 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel ...@@ -246,19 +279,20 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel
static const KERNEL_FUNCTION_TYPE Type = HOMOGENEOUS; static const KERNEL_FUNCTION_TYPE Type = HOMOGENEOUS;
static const KERNEL_FUNCTION_IDENTIFIER Identifier = R_IJ; static const KERNEL_FUNCTION_IDENTIFIER Identifier = R_IJ;
static const unsigned int DIM = 6; //PB: dimension of kernel static const unsigned int DIM = 6; //PB: dimension of kernel
const unsigned int indexTab[12]={0,0,0,1,1,2, static const unsigned int NIDX = 2; //PB: number of indices
0,1,2,1,2,2}; static constexpr unsigned int indexTab[DIM*NIDX]={0,0,0,1,1,2,
0,1,2,1,2,2};
static const unsigned int NRHS = 3; static const unsigned int NRHS = 3;
static const unsigned int NLHS = 3; static const unsigned int NLHS = 3;
// store positions in sym tensor // store positions in sym tensor (when looping over NRHSxNLHS)
const unsigned int applyTab[9]={0,1,2, const unsigned int applyTab[9]={0,1,2,
1,3,4, 1,3,4,
2,4,5}; 2,4,5};
const unsigned int _i,_j; const unsigned int _i,_j;
FInterpMatrixKernel_R_IJ(const unsigned int d = 0) FInterpMatrixKernel_R_IJ(const double = 0.0, const unsigned int d = 0)
: _i(indexTab[d]), _j(indexTab[d+DIM]) : _i(indexTab[d]), _j(indexTab[d+DIM])
{} {}
...@@ -283,8 +317,6 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel ...@@ -283,8 +317,6 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel
else if(_j==2) rj=xy.getZ(); else if(_j==2) rj=xy.getZ();
else throw std::runtime_error("Update j!"); else throw std::runtime_error("Update j!");
// return xy.getX() * xy.getX() * one_over_r3; //PB: test r0^2/R^3
if(_i==_j) if(_i==_j)
return one_over_r - ri * ri * one_over_r3; return one_over_r - ri * ri * one_over_r3;
else else
...@@ -292,6 +324,24 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel ...@@ -292,6 +324,24 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel
} }
void evaluateBlock(const FPoint& x, const FPoint& y, FReal* block) const
{
const FPoint xy(x-y);
const FReal one_over_r = FReal(1.)/xy.norm();
const FReal one_over_r3 = one_over_r*one_over_r*one_over_r;
const double r[3] = {xy.getX(),xy.getY(),xy.getZ()};
for(unsigned int d=0;d<DIM;++d){
unsigned int i = indexTab[d];
unsigned int j = indexTab[d+DIM];
if(i==j)
block[d] = one_over_r - r[i] * r[i] * one_over_r3;
else
block[d] = - r[i] * r[j] * one_over_r3;
}
}
FReal getScaleFactor(const FReal RootCellWidth, const int TreeLevel) const FReal getScaleFactor(const FReal RootCellWidth, const int TreeLevel) const
{ {
const FReal CellWidth(RootCellWidth / FReal(FMath::pow(2, TreeLevel))); const FReal CellWidth(RootCellWidth / FReal(FMath::pow(2, TreeLevel)));
...@@ -307,27 +357,27 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel ...@@ -307,27 +357,27 @@ struct FInterpMatrixKernel_R_IJ : FInterpAbstractMatrixKernel
}; };
/// R_{,ijk} /// R_{,ijk}
struct FInterpMatrixKernel_R_IJK : FInterpAbstractMatrixKernel struct FInterpMatrixKernel_R_IJK : FInterpAbstractMatrixKernel
{ {
static const KERNEL_FUNCTION_TYPE Type = HOMOGENEOUS; static const KERNEL_FUNCTION_TYPE Type = HOMOGENEOUS;
static const KERNEL_FUNCTION_IDENTIFIER Identifier = R_IJK; static const KERNEL_FUNCTION_IDENTIFIER Identifier = R_IJK;
static const unsigned int DIM = 10; //PB: dimension of kernel static const unsigned int DIM = 10; //PB: dimension of kernel
const unsigned int indexTab[30]={0,0,0,1,1,1,2,2,2,0, static const unsigned int NIDX = 3; //PB: number of indices
0,1,2,0,1,2,0,1,2,1, static constexpr unsigned int indexTab[DIM*NIDX]={0,0,0,1,1,1,2,2,2,0,
0,1,2,0,1,2,0,1,2,2}; 0,1,2,0,1,2,0,1,2,1,
0,1,2,0,1,2,0,1,2,2};
static const unsigned int NRHS = 3; static const unsigned int NRHS = 3;
static const unsigned int NLHS = 3; static const unsigned int NLHS = 3;
// store positions in sym tensor // store positions in sym tensor (when looping over NRHSxNLHS)
const unsigned int applyTab[27]={0,3,6,3,1,9,6,9,2, const unsigned int applyTab[27]={0,3,6,3,1,9,6,9,2,
3,1,9,1,4,7,9,7,5, 3,1,9,1,4,7,9,7,5,
6,9,2,9,7,5,2,5,8}; 6,9,2,9,7,5,2,5,8};
const unsigned int _i,_j,_k; const unsigned int _i,_j,_k;
FInterpMatrixKernel_R_IJK(const unsigned int d = 0) FInterpMatrixKernel_R_IJK(const double = 0.0, const unsigned int d = 0)
: _i(indexTab[d]), _j(indexTab[d+DIM]), _k(indexTab[d+2*DIM]) : _i(indexTab[d]), _j(indexTab[d+DIM]), _k(indexTab[d+2*DIM])
{} {}
......
...@@ -59,6 +59,8 @@ protected: ...@@ -59,6 +59,8 @@ protected:
const FReal BoxWidth; const FReal BoxWidth;
/// Width of a leaf cell box /// Width of a leaf cell box
const FReal BoxWidthLeaf; const FReal BoxWidthLeaf;
/// Parameter to pass to matrix kernel (material specific or anything)
const double MatParam;
/** /**
* Compute center of leaf cell from its tree coordinate. * Compute center of leaf cell from its tree coordinate.
...@@ -79,14 +81,16 @@ public: ...@@ -79,14 +81,16 @@ public:
* runtime_error is thrown if the required file is not valid). * runtime_error is thrown if the required file is not valid).
*/ */
FAbstractUnifKernel(const int inTreeHeight, FAbstractUnifKernel(const int inTreeHeight,
const FReal inBoxWidth, const FReal inBoxWidth,
const FPoint& inBoxCenter) const FPoint& inBoxCenter,
const double inMatParam = 0.0)
: Interpolator(new InterpolatorClass()), : Interpolator(new InterpolatorClass()),
MatrixKernel(new MatrixKernelClass()), MatrixKernel(new MatrixKernelClass(inMatParam)),
TreeHeight(inTreeHeight), TreeHeight(inTreeHeight),
BoxCorner(inBoxCenter - inBoxWidth / FReal(2.)), BoxCorner(inBoxCenter - inBoxWidth / FReal(2.)),
BoxWidth(inBoxWidth), BoxWidth(inBoxWidth),
BoxWidthLeaf(BoxWidth / FReal(FMath::pow(2, inTreeHeight - 1))) BoxWidthLeaf(BoxWidth / FReal(FMath::pow(2, inTreeHeight - 1))),
MatParam(inMatParam)
{ {
/* empty */ /* empty */
} }
......
...@@ -45,7 +45,7 @@ class FUnifKernel ...@@ -45,7 +45,7 @@ class FUnifKernel
: public FAbstractUnifKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS> : public FAbstractUnifKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>
{ {
// private types // private types
typedef FUnifM2LHandler<ORDER,MatrixKernelClass> M2LHandlerClass; typedef FUnifM2LHandler<ORDER,MatrixKernelClass::Type> M2LHandlerClass;
// using from // using from
typedef FAbstractUnifKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS> typedef FAbstractUnifKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>
...@@ -61,17 +61,13 @@ public: ...@@ -61,17 +61,13 @@ public:
* runtime_error is thrown if the required file is not valid). * runtime_error is thrown if the required file is not valid).
*/ */
FUnifKernel(const int inTreeHeight, FUnifKernel(const int inTreeHeight,
const FReal inBoxWidth, const FReal inBoxWidth,
const FPoint& inBoxCenter) const FPoint& inBoxCenter)
: FAbstractUnifKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>(inTreeHeight, : FAbstractUnifKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>(inTreeHeight,inBoxWidth,inBoxCenter),
inBoxWidth, M2LHandler(new M2LHandlerClass(AbstractBaseClass::MatrixKernel.getPtr(),
inBoxCenter), inTreeHeight,
M2LHandler(new M2LHandlerClass()) inBoxWidth))// PB: for non homogeneous case
{ { }
// read precomputed compressed m2l operators from binary file
//M2LHandler->ReadFromBinaryFileAndSet(); // PB: TODO?
M2LHandler->ComputeAndSet();
}
void P2M(CellClass* const LeafCell, void P2M(CellClass* const LeafCell,
...@@ -133,16 +129,17 @@ public: ...@@ -133,16 +129,17 @@ public:
const int /*NumSourceCells*/, const int /*NumSourceCells*/,
const int TreeLevel) const int TreeLevel)
{ {
const FReal CellWidth(AbstractBaseClass::BoxWidth / FReal(FMath::pow(2, TreeLevel)));
const FReal scale(AbstractBaseClass::MatrixKernel.getPtr()->getScaleFactor(CellWidth));
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){ for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
FComplexe *const TransformedLocalExpansion = TargetCell->getTransformedLocal(idxRhs); FComplexe *const TransformedLocalExpansion = TargetCell->getTransformedLocal(idxRhs);
const FReal CellWidth(AbstractBaseClass::BoxWidth / FReal(FMath::pow(2, TreeLevel)));
for (int idx=0; idx<343; ++idx){ for (int idx=0; idx<343; ++idx){
if (SourceCells[idx]){ if (SourceCells[idx]){
M2LHandler->applyFC(idx, CellWidth, SourceCells[idx]->getTransformedMultipole(idxRhs), M2LHandler->applyFC(idx, TreeLevel, scale,
SourceCells[idx]->getTransformedMultipole(idxRhs),
TransformedLocalExpansion); TransformedLocalExpansion);
} }
} }
} }
......
This diff is collapsed.
...@@ -38,14 +38,15 @@ class FTreeCoordinate; ...@@ -38,14 +38,15 @@ class FTreeCoordinate;
* *
* PB: 3 IMPORTANT remarks !!! * PB: 3 IMPORTANT remarks !!!
* *
* 1) Handling tensorial kernels (DIM,NRHS,NLHS) and having multiple rhs (NVALS) * 1) Handling tensorial kernels (DIM,NRHS,NLHS) and having multiple rhs
* are considered 2 separate features and are currently combined. * (NVALS) are considered 2 distinct features and are currently combined.
* *
* 2) When it comes to applying M2L it is NOT much faster to loop over NRHSxNLHS * 2) When it comes to applying M2L it is NOT much faster to loop over
* inside applyM2L (at least for the Lagrange case). * NRHSxNLHS inside applyM2L (at least for the Lagrange case).
* 2-bis) The evaluation of the kernel matrix (see M2LHandler) should be done at once * 2-bis) During precomputation the tensorial matrix kernels are evaluated
* instead of compo-by-compo (TODO). On the other hand, the ChebyshevSym tensorial kernel * blockwise, but this is not always possible.
* requires the matrix kernel to be evaluated compo-by-compo since we currently use a scalar ACA. * In fact, in the ChebyshevSym variant the matrix kernel needs to be
* evaluated compo-by-compo since we currently use a scalar ACA.
* *
* 3) We currently use multiple 1D FFT instead of multidim FFT. * 3) We currently use multiple 1D FFT instead of multidim FFT.
* TODO switch to multidim if relevant in considered range of size * TODO switch to multidim if relevant in considered range of size
...@@ -66,7 +67,7 @@ class FUnifTensorialKernel ...@@ -66,7 +67,7 @@ class FUnifTensorialKernel
protected://PB: for OptiDis protected://PB: for OptiDis
// private types // private types
typedef FUnifTensorialM2LHandler<ORDER,MatrixKernelClass> M2LHandlerClass; typedef FUnifTensorialM2LHandler<ORDER,MatrixKernelClass,MatrixKernelClass::Type> M2LHandlerClass;
// using from // using from
typedef FAbstractUnifKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS> typedef FAbstractUnifKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>
...@@ -83,16 +84,13 @@ public: ...@@ -83,16 +84,13 @@ public:
*/ */
FUnifTensorialKernel(const int inTreeHeight, FUnifTensorialKernel(const int inTreeHeight,
const FReal inBoxWidth, const FReal inBoxWidth,
const FPoint& inBoxCenter) const FPoint& inBoxCenter,
: FAbstractUnifKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>(inTreeHeight, const double inMatParam = 0.0)
inBoxWidth, : FAbstractUnifKernel< CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>(inTreeHeight,inBoxWidth,inBoxCenter,inMatParam),
inBoxCenter), M2LHandler(new M2LHandlerClass(AbstractBaseClass::MatrixKernel.getPtr(),
M2LHandler(new M2LHandlerClass()) inTreeHeight,
{ inBoxWidth))// PB: for non homogeneous case
// read precomputed compressed m2l operators from binary file { }
//M2LHandler->ReadFromBinaryFileAndSet(); // PB: TODO?
M2LHandler->ComputeAndSet();
}
void P2M(CellClass* const LeafCell, void P2M(CellClass* const LeafCell,
...@@ -150,6 +148,7 @@ public: ...@@ -150,6 +148,7 @@ public:
const int TreeLevel) const int TreeLevel)
{ {
const FReal CellWidth(AbstractBaseClass::BoxWidth / FReal(FMath::pow(2, TreeLevel))); const FReal CellWidth(AbstractBaseClass::BoxWidth / FReal(FMath::pow(2, TreeLevel)));
const FReal scale(AbstractBaseClass::MatrixKernel.getPtr()->getScaleFactor(CellWidth));
for(int idxV = 0 ; idxV < NVALS ; ++idxV){ for(int idxV = 0 ; idxV < NVALS ; ++idxV){
for (int idxLhs=0; idxLhs < nLhs; ++idxLhs){ for (int idxLhs=0; idxLhs < nLhs; ++idxLhs){
...@@ -163,12 +162,15 @@ public: ...@@ -163,12 +162,15 @@ public:
int idxMul = idxV*nRhs + idxRhs; int idxMul = idxV*nRhs + idxRhs;
// update kernel index such that: x_i = K_{ij}y_j // update kernel index such that: x_i = K_{ij}y_j
int idxK = idxLhs*nRhs + idxRhs; int idxK = idxLhs*nRhs + idxRhs;
// get index in matrix kernel
unsigned int d
= AbstractBaseClass::MatrixKernel.getPtr()->getPosition(idxK);
for (int idx=0; idx<343; ++idx){ for (int idx=0; idx<343; ++idx){
if (SourceCells[idx]){ if (SourceCells[idx]){
M2LHandler->applyFC(idx, CellWidth, M2LHandler->applyFC(idx, TreeLevel, scale, d,
SourceCells[idx]->getTransformedMultipole(idxMul), SourceCells[idx]->getTransformedMultipole(idxMul),
TransformedLocalExpansion,idxK); TransformedLocalExpansion);
} }
} }
......
...@@ -122,12 +122,12 @@ int main(int argc, char* argv[]) ...@@ -122,12 +122,12 @@ int main(int argc, char* argv[])
{ // begin Lagrange kernel { // begin Lagrange kernel
// accuracy // accuracy
const unsigned int ORDER = 3; const unsigned int ORDER = 5;
// typedefs // typedefs
typedef FP2PParticleContainerIndexed<> ContainerClass; typedef FP2PParticleContainerIndexed<> ContainerClass;
typedef FSimpleLeaf< ContainerClass > LeafClass; typedef FSimpleLeaf< ContainerClass > LeafClass;
//typedef FInterpMatrixKernelLJ MatrixKernelClass; // typedef FInterpMatrixKernelLJ MatrixKernelClass;
typedef FInterpMatrixKernelR MatrixKernelClass; typedef FInterpMatrixKernelR MatrixKernelClass;
typedef FUnifCell<ORDER> CellClass; typedef FUnifCell<ORDER> CellClass;
typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass; typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
......
...@@ -68,8 +68,8 @@ int main(int argc, char* argv[]) ...@@ -68,8 +68,8 @@ int main(int argc, char* argv[])
// typedefs // typedefs
typedef FInterpMatrixKernel_R_IJ MatrixKernelClass; // typedef FInterpMatrixKernel_R_IJ MatrixKernelClass;
// typedef FInterpMatrixKernel_IOR MatrixKernelClass; typedef FInterpMatrixKernel_IOR MatrixKernelClass;
const KERNEL_FUNCTION_IDENTIFIER MK_ID = MatrixKernelClass::Identifier; const KERNEL_FUNCTION_IDENTIFIER MK_ID = MatrixKernelClass::Identifier;
const unsigned int NRHS = MatrixKernelClass::NRHS; const unsigned int NRHS = MatrixKernelClass::NRHS;
......
...@@ -509,11 +509,21 @@ int main(int, char **){ ...@@ -509,11 +509,21 @@ int main(int, char **){
counter++; counter++;
} }
// std::cout << "Check Potential, forceX, forceY, forceZ " << std::endl;
// for(int idxPart = 0 ; idxPart < 20 ; ++idxPart){
// std::cout << approx_p[idxPart] << ", "<< p[idxPart] << "|| ";
// std::cout << approx_f[idxPart] << ", "<< f[idxPart] << "|| ";
// std::cout << approx_f[idxPart+M] << ", "<< f[idxPart+M] << "|| ";
// std::cout << approx_f[idxPart+2*M] << ", "<< f[idxPart+2*M] << "|| ";
// std::cout << std::endl;
// }
// std::cout << std::endl;