Commit c1700fb0 authored by COULAUD Olivier's avatar COULAUD Olivier

Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/scalfmm/scalfmm

# By bramas
# Via bramas
* 'master' of git+ssh://scm.gforge.inria.fr//gitroot/scalfmm/scalfmm:
  I prefer not to leave the email addresses into the main directory
  Move a utest file from main directory to ToRemove
  Move the NON public directories from Tests to ToRemove
  Remove old adaptive, rename adaptative, try to fix files
  Rename the modules dir in CMakeModules
  Update the read me
  Rename the todo file
  Update the readme.txt
parents bec4a210 31ddccf5
......@@ -8,7 +8,7 @@ STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" insource)
if(insource)
MESSAGE(FATAL_ERROR "${PROJECT_NAME} requires an out of source build. Goto ./Build and tapes cmake ../")
endif(insource)
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Modules)
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMakeModules)
#
# MPI option has to be set before project, cannot be changed in the cache!
......
ScalFmm, Inria, Please read the licence.
To compile:
---------------------------------------------------
---------------------------------------------------
To compile:
==========
# Go to
cd scalfmm/Build
# Use cmake first by
......@@ -19,8 +22,11 @@ ccmake ..
make
# And access executables in scalfmm/Build/Tests/{Release,Debug}/.....
Build the doc
---------------------------------------------------
---------------------------------------------------
Build the doc:
=============
In scalfmm/Doc you can find several pdf and .tex file about
the implementation, kernels and data structure.
......@@ -32,3 +38,28 @@ make doc
browser scalfmm/Build/Doc/html/index.html
---------------------------------------------------
---------------------------------------------------
Getting help and having news from us:
====================================
You can subscribe to the scalfmm users mailing list ( scalfmm-public-users@lists.gforge.inria.fr, http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/scalfmm-public-users ). Very low trafic (~ 2 mails per year) just to know when a news version or an improvement is available.
Contact the developers at : scalfmm-public-support@lists.gforge.inria.fr
---------------------------------------------------
---------------------------------------------------
What inside :
=============
× Src : The Core of Scalfmm is under the Src directory. Users should not need to modify the source.
One can want to implement its own kernel or even its own parallelization whithout modifying the sources.
× Data : example of particles distributions
× Examples : examples of very common usage of Scalfmm
× Doc : should contains the generated Doc
× UTests : contains some unit tests (it can be a good example to understand some features)
× Tests : examples to know how to use scalfmm/put particles in the tree/iterate on the tree...
× Utils : some scripts to work with the data files.
#ifndef FABSTRACTADAPTATIVEKERNEL
#define FABSTRACTADAPTATIVEKERNEL
#ifndef FABSTRACTADAPTIVEKERNEL
#define FABSTRACTADAPTIVEKERNEL
/**
* This class represent the method that an adaptative kernel must implement.
* This class represent the method that an adaptive kernel must implement.
* There are two kinds of operators, the first one represent computation and the others
* should return the cretiria to know when the P2M should be performed.
*/
......
......@@ -19,9 +19,9 @@
#include "Utils/FPoint.hpp"
#include "Adaptative/FAdaptiveCell.hpp"
#include "Adaptative/FAdaptiveKernelWrapper.hpp"
#include "Adaptative/FAbstractAdaptiveKernel.hpp"
#include "Adaptive/FAdaptiveCell.hpp"
#include "Adaptive/FAdaptiveKernelWrapper.hpp"
#include "Adaptive/FAbstractAdaptiveKernel.hpp"
#include "Kernels/Chebyshev/FChebSymKernel.hpp"
class FTreeCoordinate;
......
......@@ -19,9 +19,9 @@
#include "Utils/FPoint.hpp"
#include "Adaptative/FAdaptiveCell.hpp"
#include "Adaptative/FAdaptiveKernelWrapper.hpp"
#include "Adaptative/FAbstractAdaptiveKernel.hpp"
#include "Adaptive/FAdaptiveCell.hpp"
#include "Adaptive/FAdaptiveKernelWrapper.hpp"
#include "Adaptive/FAbstractAdaptiveKernel.hpp"
#include "Kernels/Uniform/FUnifKernel.hpp"
#include "Kernels/Uniform/FUnifM2LHandler.hpp"
......
......@@ -43,9 +43,9 @@
#include "Kernels/Chebyshev/FChebCell.hpp"
#include "AdaptiveTree/FAdaptChebSymKernel.hpp"
#include "Adaptative/FAdaptiveCell.hpp"
#include "Adaptative/FAdaptiveKernelWrapper.hpp"
#include "Adaptative/FAbstractAdaptiveKernel.hpp"
#include "Adaptive/FAdaptiveCell.hpp"
#include "Adaptive/FAdaptiveKernelWrapper.hpp"
#include "Adaptive/FAbstractAdaptiveKernel.hpp"
//
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "Kernels/Chebyshev/FChebCell.hpp"
......
......@@ -40,14 +40,14 @@
#include "Components/FSimpleIndexedLeaf.hpp"
#include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "Adaptative/FAdaptiveCell.hpp"
#include "Adaptative/FAdaptiveKernelWrapper.hpp"
#include "Adaptative/FAbstractAdaptiveKernel.hpp"
#include "Adaptive/FAdaptiveCell.hpp"
#include "Adaptive/FAdaptiveKernelWrapper.hpp"
#include "Adaptive/FAbstractAdaptiveKernel.hpp"
//
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "Kernels/Uniform/FUnifCell.hpp"
#include "AdaptiveTree/FAdaptUnifKernel.hpp"
#include "AdaptiveTree/FAdaptTools.hpp"
#include "Adaptive/FAdaptUnifKernel.hpp"
#include "Adaptive/FAdaptTools.hpp"
//
//
#include "Core/FFmmAlgorithm.hpp"
......
......@@ -41,9 +41,9 @@
#include "../../Src/Files/FRandomLoader.hpp"
#include "../../Src/Adaptative/FAdaptiveCell.hpp"
#include "../../Src/Adaptative/FAdaptiveKernelWrapper.hpp"
#include "../../Src/Adaptative/FAbstractAdaptiveKernel.hpp"
#include "../../Src/Adaptive/FAdaptiveCell.hpp"
#include "../../Src/Adaptive/FAdaptiveKernelWrapper.hpp"
#include "../../Src/Adaptive/FAbstractAdaptiveKernel.hpp"
template< class CellClass, class ContainerClass>
class FAdaptiveTestKernel : public FTestKernels<CellClass, ContainerClass>, public FAbstractAdaptiveKernel<CellClass, ContainerClass> {
......
......@@ -42,9 +42,9 @@
#include "../../Src/Files/FRandomLoader.hpp"
#include "../../Src/Adaptative/FAdaptiveCell.hpp"
#include "../../Src/Adaptative/FAdaptiveKernelWrapper.hpp"
#include "../../Src/Adaptative/FAbstractAdaptiveKernel.hpp"
#include "../../Src/Adaptive/FAdaptiveCell.hpp"
#include "../../Src/Adaptive/FAdaptiveKernelWrapper.hpp"
#include "../../Src/Adaptive/FAbstractAdaptiveKernel.hpp"
template< class CellClass, class ContainerClass>
class FAdaptiveStatsKernel : public FAbstractKernels<CellClass, ContainerClass>, public FAbstractAdaptiveKernel<CellClass, ContainerClass> {
......
#ifndef FADAPTCHEBSYMKERNEL_HPP
#define FADAPTCHEBSYMKERNEL_HPP
// ===================================================================================
// Copyright ScalFmm 2011 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".
// ===================================================================================
#include "Utils/FGlobal.hpp"
#include "Utils/FPoint.hpp"
#include "Adaptive/FAdaptiveCell.hpp"
#include "Adaptive/FAdaptiveKernelWrapper.hpp"
#include "Adaptive/FAbstractAdaptiveKernel.hpp"
#include "Kernels/Chebyshev/FChebSymKernel.hpp"
class FTreeCoordinate;
// ==== CMAKE =====
// @FUSE_BLAS
// ================
// for verbosity only!!!
//#define COUNT_BLOCKED_INTERACTIONS
// if timings should be logged
//#define LOG_TIMINGS
/**
* @author O. Coulaud
* @class FAdaptChebSymKernel
* @brief
* Please read the license
*
* This kernels implement the Chebyshev interpolation based FMM operators
* exploiting the symmetries in the far-field. It implements all interfaces
* (P2P, P2M, M2M, M2L, L2L, L2P) which are required by the FFmmAlgorithm and
* FFmmAlgorithmThread.
*
* @tparam CellClass Type of cell
* @tparam ContainerClass Type of container to store particles
* @tparam MatrixKernelClass Type of matrix kernel function
* @tparam ORDER Chebyshev interpolation order
*/
template< class CellClass, class ContainerClass, class MatrixKernelClass, int ORDER, int NVALS = 1>
class FAdaptiveChebSymKernel : FChebSymKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>
, public FAbstractAdaptiveKernel<CellClass, ContainerClass> {
//
typedef FChebSymKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS> KernelBaseClass;
enum {order = ORDER,
nnodes = TensorTraits<ORDER>::nnodes};
const MatrixKernelClass *const MatrixKernel;
public:
using KernelBaseClass::P2M;
using KernelBaseClass::M2M;
using KernelBaseClass::M2L;
using KernelBaseClass::finishedLevelM2L;
using KernelBaseClass::L2L;
using KernelBaseClass::L2P;
using KernelBaseClass::P2P;
using KernelBaseClass::P2PRemote;
// /**
// * The constructor initializes all constant attributes and it reads the
// * precomputed and compressed M2L operators from a binary file (an
// * runtime_error is thrown if the required file is not valid).
// */
FAdaptiveChebSymKernel(const int inTreeHeight, const FReal inBoxWidth,
const FPoint& inBoxCenter, const MatrixKernelClass *const inMatrixKernel) : KernelBaseClass(inTreeHeight, inBoxWidth, inBoxCenter, inMatrixKernel), MatrixKernel(inMatrixKernel)
{}
// /** Copy constructor */
FAdaptiveChebSymKernel(const FAdaptiveChebSymKernel& other)
: KernelBaseClass(other), MatrixKernel(other.MatrixKernel)
{ }
//
// /** Destructor */
~FAdaptiveChebSymKernel()
{
//this->~KernelBaseClass() ;
}
void P2M(CellClass* const pole, const int cellLevel, const ContainerClass* const particles) override {
const FPoint CellCenter(KernelBaseClass::getCellCenter(pole->getCoordinate(),cellLevel));
const FReal BoxWidth = KernelBaseClass::BoxWidth / FMath::pow(2.0,cellLevel);
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 1) apply Sy
KernelBaseClass::Interpolator->applyP2M(CellCenter, BoxWidth,
pole->getMultipole(idxRhs), particles);
}
}
void M2M(CellClass* const pole, const int poleLevel, const CellClass* const subCell, const int subCellLevel) override {
const FPoint subCellCenter(KernelBaseClass::getCellCenter(subCell->getCoordinate(),subCellLevel));
const FReal subCellWidth(KernelBaseClass::BoxWidth / FReal(FMath::pow(2.0,subCellLevel)));
const FPoint poleCellCenter(KernelBaseClass::getCellCenter(pole->getCoordinate(),poleLevel));
const FReal poleCellWidth(KernelBaseClass::BoxWidth / FReal(FMath::pow(2.0, poleLevel)));
////////////////////////////////////////////////////////////////////////////
/// p^6 version
// allocate memory
FReal* subChildParentInterpolator = new FReal [nnodes * nnodes];
// set child info
FPoint ChildRoots[nnodes], localChildRoots[nnodes];
FChebTensor<ORDER>::setRoots(subCellCenter, subCellWidth, ChildRoots);
// map global position of roots to local position in parent cell
const map_glob_loc map(poleCellCenter, poleCellWidth);
for (unsigned int n=0; n<nnodes; ++n)
map(ChildRoots[n], localChildRoots[n]);
// assemble child - parent - interpolator
KernelBaseClass::Interpolator->assembleInterpolator(nnodes, localChildRoots, subChildParentInterpolator);
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 1) apply Sy (using tensor product M2M with an interpolator computed on the fly)
// Do NOT reset multipole expansion !
//FBlas::scal(nnodes, FReal(0.), pole->getMultipole(idxRhs));
/// p^6 version
FBlas::gemtva(nnodes, nnodes, FReal(1.),
subChildParentInterpolator,
const_cast<FReal*>(subCell->getMultipole(idxRhs)), pole->getMultipole(idxRhs));
}// NVALS
}
void P2L(CellClass* const local, const int localLevel, const ContainerClass* const particles) override {
// Target cell: local
const FReal localCellWidth(KernelBaseClass::BoxWidth / FReal(FMath::pow(2.0, localLevel)));
const FPoint localCellCenter(KernelBaseClass::getCellCenter(local->getCoordinate(),localLevel));
// interpolation points of target (X) cell
FPoint X[nnodes];
FChebTensor<order>::setRoots(localCellCenter, localCellWidth, X);
// read positions
const FReal*const positionsX = particles->getPositions()[0];
const FReal*const positionsY = particles->getPositions()[1];
const FReal*const positionsZ = particles->getPositions()[2];
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// read physicalValue
const FReal*const physicalValues = particles->getPhysicalValues();
// apply P2L
for (unsigned int idxPart=0; idxPart<particles->getNbParticles(); ++idxPart){
const FPoint y = FPoint(positionsX[idxPart],
positionsY[idxPart],
positionsZ[idxPart]);
for (unsigned int m=0; m<nnodes; ++m)
local->getLocal(idxRhs)[m]+=MatrixKernel->evaluate(X[m], y) * physicalValues[idxPart];
}
}// NVALS
}
void M2L(CellClass* const local, const int localLevel, const CellClass* const pole, const int poleLevel) override {
// Source cell: pole
const FReal poleCellWidth(KernelBaseClass::BoxWidth / FReal(FMath::pow(2.0, poleLevel)));
const FPoint poleCellCenter(KernelBaseClass::getCellCenter(pole->getCoordinate(),poleLevel));
// Target cell: local
const FReal localCellWidth(KernelBaseClass::BoxWidth / FReal(FMath::pow(2.0, localLevel)));
const FPoint localCellCenter(KernelBaseClass::getCellCenter(local->getCoordinate(),localLevel));
// interpolation points of source (Y) and target (X) cell
FPoint X[nnodes], Y[nnodes];
FChebTensor<order>::setRoots(poleCellCenter, poleCellWidth, Y);
FChebTensor<order>::setRoots(localCellCenter, localCellWidth, X);
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// Dense M2L
const FReal *const MultipoleExpansion = pole->getMultipole(idxRhs);
for (unsigned int m=0; m<nnodes; ++m)
for (unsigned int n=0; n<nnodes; ++n){
local->getLocal(idxRhs)[m]+=MatrixKernel->evaluate(X[m], Y[n]) * MultipoleExpansion[n];
}
}
}
void M2P(const CellClass* const pole, const int poleLevel, ContainerClass* const particles) override {
// Source cell: pole
const FReal poleCellWidth(KernelBaseClass::BoxWidth / FReal(FMath::pow(2.0, poleLevel)));
const FPoint poleCellCenter(KernelBaseClass::getCellCenter(pole->getCoordinate(),poleLevel));
// interpolation points of source (Y) cell
FPoint Y[nnodes];
FChebTensor<order>::setRoots(poleCellCenter, poleCellWidth, Y);
// read positions
const FReal*const positionsX = particles->getPositions()[0];
const FReal*const positionsY = particles->getPositions()[1];
const FReal*const positionsZ = particles->getPositions()[2];
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
const FReal *const MultipoleExpansion = pole->getMultipole(idxRhs);
// apply M2P
for (unsigned int idxPart=0; idxPart<particles->getNbParticles(); ++idxPart){
const FPoint x = FPoint(positionsX[idxPart],positionsY[idxPart],positionsZ[idxPart]);
FReal targetValue=0.;
{
for (unsigned int n=0; n<nnodes; ++n)
targetValue +=
MatrixKernel->evaluate(x, Y[n]) * MultipoleExpansion[/*idxLhs*nnodes+*/n];
}
// get potential
FReal*const potentials = particles->getPotentials(/*idxPot*/);
// add contribution to potential
potentials[idxPart] += (targetValue);
}// Particles
}// NVALS
}
void L2L(const CellClass* const local, const int localLevel, CellClass* const subCell, const int subCellLevel) override {
const FPoint subCellCenter(KernelBaseClass::getCellCenter(subCell->getCoordinate(),subCellLevel));
const FReal subCellWidth(KernelBaseClass::BoxWidth / FReal(FMath::pow(2.0,subCellLevel)));
const FPoint localCenter(KernelBaseClass::getCellCenter(local->getCoordinate(),localLevel));
const FReal localWidth(KernelBaseClass::BoxWidth / FReal(FMath::pow(2.0,localLevel)));
////////////////////////////////////////////////////////////////////////////
/// p^6 version
// allocate memory
FReal* subChildParentInterpolator = new FReal [nnodes * nnodes];
// set child info
FPoint ChildRoots[nnodes], localChildRoots[nnodes];
FChebTensor<ORDER>::setRoots(subCellCenter, subCellWidth, ChildRoots);
// map global position of roots to local position in parent cell
const map_glob_loc map(localCenter, localWidth);
for (unsigned int n=0; n<nnodes; ++n)
map(ChildRoots[n], localChildRoots[n]);
// assemble child - parent - interpolator
KernelBaseClass::Interpolator->assembleInterpolator(nnodes, localChildRoots, subChildParentInterpolator);
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 2) apply Sx
/// p^6 version
FBlas::gemva(nnodes, nnodes, FReal(1.),
subChildParentInterpolator,
const_cast<FReal*>(local->getLocal(idxRhs)), subCell->getLocal(idxRhs));
}// NVALS
}
void L2P(const CellClass* const local, const int cellLevel, ContainerClass* const particles) override {
const FPoint CellCenter(KernelBaseClass::getCellCenter(local->getCoordinate(),cellLevel));
const FReal BoxWidth = KernelBaseClass::BoxWidth / FMath::pow(2.0,cellLevel);
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 2.a) apply Sx
KernelBaseClass::Interpolator->applyL2P(CellCenter, BoxWidth,
local->getLocal(idxRhs), particles);
// 2.b) apply Px (grad Sx)
KernelBaseClass::Interpolator->applyL2PGradient(CellCenter, BoxWidth,
local->getLocal(idxRhs), particles);
}
}
void P2P(ContainerClass* target, const ContainerClass* sources) override {
// long long int*const particlesAttributes = target->getDataDown();
// for(int idxPart = 0 ; idxPart < target->getNbParticles() ; ++idxPart){
// particlesAttributes[idxPart] += sources->getNbParticles();
// }
}
bool preferP2M(const ContainerClass* const particles) override {
return particles->getNbParticles() < 10;
}
bool preferP2M(const int /*atLevel*/, const ContainerClass*const particles[], const int nbContainers) override {
int counterParticles = 0;
for(int idxContainer = 0 ; idxContainer < nbContainers ; ++idxContainer){
counterParticles += particles[idxContainer]->getNbParticles();
}
return counterParticles < 10;
}
};
//
//template < class CellClass, class ContainerClass, class MatrixKernelClass, int ORDER, int NVALS = 1>
//class FAdaptChebSymKernel
// : public FChebSymKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>
//{
// typedef FChebSymKernel<CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS> KernelBaseClass;
//
//#ifdef LOG_TIMINGS
// FTic time;
// FReal t_m2l_1, t_m2l_2, t_m2l_3;
//#endif
//
//public:
// /**
// * The constructor initializes all constant attributes and it reads the
// * precomputed and compressed M2L operators from a binary file (an
// * runtime_error is thrown if the required file is not valid).
// */
// FAdaptChebSymKernel(const int inTreeHeight,
// const FReal inBoxWidth,
// const FPoint& inBoxCenter)
//: KernelBaseClass(inTreeHeight, inBoxWidth, inBoxCenter)
//{
//
//#ifdef LOG_TIMINGS
// t_m2l_1 = FReal(0.);
// t_m2l_2 = FReal(0.);
// t_m2l_3 = FReal(0.);
//#endif
//}
//
//
// /** Copy constructor */
// FAdaptChebSymKernel(const FAdaptChebSymKernel& other)
// : KernelBaseClass(other)
// { }
//
//
//
// /** Destructor */
// ~FAdaptChebSymKernel()
// {
// this->~KernelBaseClass() ;
//#ifdef LOG_TIMINGS
// std::cout << "- Permutation took " << t_m2l_1 << "s"
// << "\n- GEMMT and GEMM took " << t_m2l_2 << "s"
// << "\n- Unpermutation took " << t_m2l_3 << "s"
// << std::endl;
//#endif
// }
//
//
// void P2MAdapt(CellClass* const ParentCell, const int &level)
// {
// const FPoint LeafCellCenter(KernelBaseClass::getLeafCellCenter(ParentCell->getCoordinate()));
// const FReal BoxWidth = KernelBaseClass::BoxWidthLeaf*FMath::pow(2.0,KernelBaseClass::TreeHeight-level);
// //
// for(int i = 0 ; i <ParentCell->getLeavesSize(); ++i ){
// //
// for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// KernelBaseClass::Interpolator->applyP2M(LeafCellCenter, BoxWidth,
// ParentCell->getMultipole(idxRhs), ParentCell->getLeaf(i)->getSrc());
// }
// }
// }
// void M2MAdapt(CellClass* const FRestrict ParentCell, const int &TreeLevel, const int &numberOfM2M,
// const int * FRestrict ChildLevel , const CellClass*const FRestrict *const FRestrict ChildCells)
// {
// for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// // // apply Sy
// for (unsigned int ChildIndex=0; ChildIndex < 8; ++ChildIndex){
// if (ChildCells[ChildIndex]){
// // KernelBaseClass::Interpolator->applyM2M(ChildIndex, ChildCells[ChildIndex]->getMultipole(idxRhs), ParentCell->getMultipole(idxRhs));
// }
// }
// }
// }
//
//
//
// void M2L(CellClass* const FRestrict TargetCell,
// const CellClass* SourceCells[343],
// const int /*NumSourceCells*/,
// const int TreeLevel)
// {
//
// }
//
//
// void L2L(const CellClass* const FRestrict ParentCell,
// CellClass* FRestrict *const FRestrict ChildCells,
// const int /*TreeLevel*/)
// {
// // for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// // // apply Sx
// // for (unsigned int ChildIndex=0; ChildIndex < 8; ++ChildIndex){
// // if (ChildCells[ChildIndex]){
// // AbstractBaseClass::Interpolator->applyL2L(ChildIndex, ParentCell->getLocal(idxRhs), ChildCells[ChildIndex]->getLocal(idxRhs));
// // }
// // }
// // }
// }
//
// void L2P(const CellClass* const LeafCell,
// ContainerClass* const TargetParticles)
// {
// KernelBaseClass::L2P(LeafCell,TargetParticles) ;
// }
//
// // void P2P(const FTreeCoordinate& /* LeafCellCoordinate */, // needed for periodic boundary conditions
// // ContainerClass* const FRestrict TargetParticles,
// // const ContainerClass* const FRestrict /*SourceParticles*/,
// // ContainerClass* const NeighborSourceParticles[27],
// // const int /* size */)
// // {
// // DirectInteractionComputer<MatrixKernelClass::Identifier, NVALS>::P2P(TargetParticles,NeighborSourceParticles);
// // }
// //
// //
// // void P2PRemote(const FTreeCoordinate& /*inPosition*/,
// // ContainerClass* const FRestrict inTargets, const ContainerClass* const FRestrict /*inSources*/,
// // ContainerClass* const inNeighbors[27], const int /*inSize*/){
// // DirectInteractionComputer<MatrixKernelClass::Identifier, NVALS>::P2PRemote(inTargets,inNeighbors,27);
// // }
//
//};
//
//
#endif //FADAPTCHEBSYMKERNELS_HPP
// [--END--]
#ifndef FADAPTUNIFKERNEL_HPP
#define FADAPTUNIFKERNEL_HPP
// ===================================================================================
// Copyright ScalFmm 2011 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,