Commit a113ea91 authored by Pierre BLANCHARD's avatar Pierre BLANCHARD

Significant modif in Chebyshev FMM (may impact your library): Provide a...

Significant modif in Chebyshev FMM (may impact your library): Provide a variant of ChebM2L without compression (new name FCheb) and use prefix FChebCmp for the compressed variant (former FCheb); Now FChebTensorial does exactly the same thing as FCheb but for tensorial kernel matrices.
parent d36016e5
This diff is collapsed.
This diff is collapsed.
......@@ -25,6 +25,7 @@
#include "../../Utils/FSmartPointer.hpp"
#include "./FAbstractChebKernel.hpp"
#include "./FChebM2LHandler.hpp"
class FTreeCoordinate;
......@@ -82,9 +83,7 @@ public:
*/
FChebKernel(const int inTreeHeight, const FReal inBoxWidth, const FPoint<FReal>& inBoxCenter, const MatrixKernelClass *const inMatrixKernel,
const FReal Epsilon)
: FAbstractChebKernel< FReal, CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>(inTreeHeight,
inBoxWidth,
inBoxCenter),
: FAbstractChebKernel< FReal, CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>(inTreeHeight,inBoxWidth,inBoxCenter),
MatrixKernel(inMatrixKernel),
M2LHandler(new M2LHandlerClass(MatrixKernel,Epsilon))
{
......@@ -92,6 +91,8 @@ public:
//M2LHandler->ReadFromBinaryFileAndSet();
M2LHandler->ComputeAndCompressAndSet();
}
/**
* The constructor initializes all constant attributes and it reads the
* precomputed and compressed M2L operators from a binary file (an
......@@ -110,15 +111,8 @@ public:
const ContainerClass* const SourceParticles)
{
const FPoint<FReal> LeafCellCenter(AbstractBaseClass::getLeafCellCenter(LeafCell->getCoordinate()));
// 1) apply Sy
AbstractBaseClass::Interpolator->applyP2M(LeafCellCenter, AbstractBaseClass::BoxWidthLeaf,
LeafCell->getMultipole(0), SourceParticles);
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 2) apply B
M2LHandler->applyB(LeafCell->getMultipole(idxRhs), LeafCell->getMultipole(idxRhs) + AbstractBaseClass::nnodes);
}
}
......@@ -127,73 +121,34 @@ public:
const int /*TreeLevel*/)
{
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 1) apply Sy
for (unsigned int ChildIndex=0; ChildIndex < 8; ++ChildIndex){
if (ChildCells[ChildIndex]){
AbstractBaseClass::Interpolator->applyM2M(ChildIndex, ChildCells[ChildIndex]->getMultipole(idxRhs),
ParentCell->getMultipole(idxRhs));
}
}
// 2) apply B
M2LHandler->applyB(ParentCell->getMultipole(idxRhs), ParentCell->getMultipole(idxRhs) + AbstractBaseClass::nnodes);
}
}
// void M2L(CellClass* const FRestrict TargetCell,
// const CellClass* SourceCells[],
// const int NumSourceCells,
// const int TreeLevel) const
// {
// const FReal CellWidth(BoxWidth / FReal(FMath::pow(2, TreeLevel)));
// const FTreeCoordinate& cx = TargetCell->getCoordinate();
// for (int idx=0; idx<NumSourceCells; ++idx) {
// const FTreeCoordinate& cy = SourceCells[idx]->getCoordinate();
// const int transfer[3] = {cy.getX()-cx.getX(),
// cy.getY()-cx.getY(),
// cy.getZ()-cx.getZ()};
// M2LHandler->applyC(transfer, CellWidth,
// SourceCells[idx]->getMultipole() + AbstractBaseClass::nnodes,
// TargetCell->getLocal() + AbstractBaseClass::nnodes);
// }
// }
void M2L(CellClass* const FRestrict TargetCell, const CellClass* SourceCells[],
const int neighborPositions[], const int inSize, const int TreeLevel) override {
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
FReal *const CompressedLocalExpansion = TargetCell->getLocal(idxRhs) + AbstractBaseClass::nnodes;
FReal *const localExpansion = TargetCell->getLocal(idxRhs);
const FReal CellWidth(AbstractBaseClass::BoxWidth / FReal(FMath::pow(2, TreeLevel)));
for(int idxExistingNeigh = 0 ; idxExistingNeigh < inSize ; ++idxExistingNeigh){
const int idx = neighborPositions[idxExistingNeigh];
M2LHandler->applyC(idx, CellWidth, SourceCells[idxExistingNeigh]->getMultipole(idxRhs) + AbstractBaseClass::nnodes,
CompressedLocalExpansion);
M2LHandler->applyC(idx, CellWidth, SourceCells[idxExistingNeigh]->getMultipole(idxRhs),
localExpansion);
}
}
}
// void M2L(CellClass* const FRestrict TargetCell, const CellClass* SourceCells[],
// const int neighborPositions[], const int inSize, const int TreeLevel) override {
// const unsigned int rank = M2LHandler.getRank();
// FBlas::scal(343*rank, FReal(0.), MultipoleExpansion);
// const FReal CellWidth(BoxWidth / FReal(FMath::pow(2, TreeLevel)));
// for(int idxExistingNeigh = 0 ; idxExistingNeigh < inSize ; ++idxExistingNeigh){
// const int idx = neighborPositions[idxExistingNeigh];
// FBlas::copy(rank, const_cast<FReal *const>(SourceCells[idxExistingNeigh]->getMultipole())+AbstractBaseClass::nnodes,
// MultipoleExpansion+idx*rank);
//
// M2LHandler->applyC(CellWidth, MultipoleExpansion, TargetCell->getLocal() + AbstractBaseClass::nnodes);
// }
void L2L(const CellClass* const FRestrict ParentCell,
CellClass* FRestrict *const FRestrict ChildCells,
const int /*TreeLevel*/)
{
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 1) apply U
M2LHandler->applyU(ParentCell->getLocal(idxRhs) + AbstractBaseClass::nnodes,
const_cast<CellClass*>(ParentCell)->getLocal(idxRhs));
// 2) apply Sx
for (unsigned int ChildIndex=0; ChildIndex < 8; ++ChildIndex){
if (ChildCells[ChildIndex]){
AbstractBaseClass::Interpolator->applyL2L(ChildIndex, ParentCell->getLocal(idxRhs), ChildCells[ChildIndex]->getLocal(idxRhs));
......@@ -207,11 +162,6 @@ public:
{
const FPoint<FReal> LeafCellCenter(AbstractBaseClass::getLeafCellCenter(LeafCell->getCoordinate()));
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 1) apply U
M2LHandler->applyU(LeafCell->getLocal(idxRhs) + AbstractBaseClass::nnodes, const_cast<CellClass*>(LeafCell)->getLocal(idxRhs));
}
//// 2.a) apply Sx
//AbstractBaseClass::Interpolator->applyL2P(LeafCellCenter,
// AbstractBaseClass::BoxWidthLeaf,
......
This diff is collapsed.
......@@ -28,7 +28,8 @@
#include "FChebTensor.hpp"
#include "../Interpolation/FInterpSymmetries.hpp"
#include "FChebM2LHandler.hpp"
#include "FChebCmpM2LHandler.hpp"
#include "Utils/FAca.hpp"
......@@ -175,7 +176,7 @@ static void precompute(const MatrixKernelClass *const MatrixKernel, const FReal
stream << INFO;
throw std::runtime_error("SVD did not converge with " + stream.str());
}
rank = getRank(S, aca_rank, Epsilon);
rank = FSvd::getRank(S, aca_rank, Epsilon);
}
const unsigned int idx = (i+3)*7*7 + (j+3)*7 + (k+3);
......@@ -238,7 +239,7 @@ static void precompute(const MatrixKernelClass *const MatrixKernel, const FReal
stream << INFO;
throw std::runtime_error("SVD did not converge with " + stream.str());
}
const unsigned int rank = getRank<ORDER>(S, Epsilon);
const unsigned int rank = FSvd::getRank<ORDER>(S, Epsilon);
// store
const unsigned int idx = (i+3)*7*7 + (j+3)*7 + (k+3);
......
......@@ -25,7 +25,6 @@
#include "../../Utils/FSmartPointer.hpp"
#include "./FAbstractChebKernel.hpp"
//#include "./FChebM2LHandler.hpp"
#include "./FChebTensorialM2LHandler.hpp" //PB: temporary version
class FTreeCoordinate;
......@@ -79,15 +78,13 @@ public:
const FReal inBoxWidth,
const FPoint<FReal>& inBoxCenter,
const MatrixKernelClass *const inMatrixKernel,
const FReal inBoxWidthExtension,
const FReal Epsilon)
const FReal inBoxWidthExtension)
: FAbstractChebKernel< FReal, CellClass, ContainerClass, MatrixKernelClass, ORDER, NVALS>(inTreeHeight,inBoxWidth,inBoxCenter,inBoxWidthExtension),
MatrixKernel(inMatrixKernel),
M2LHandler(new M2LHandlerClass(MatrixKernel,
inTreeHeight,
inBoxWidth,
inBoxWidthExtension,
Epsilon))
inBoxWidthExtension))
{ }
......@@ -99,19 +96,9 @@ public:
+ AbstractBaseClass::BoxWidthExtension);
for(int idxV = 0 ; idxV < NVALS ; ++idxV){
// 1) apply Sy
// apply Sy
AbstractBaseClass::Interpolator->applyP2M(LeafCellCenter, ExtendedLeafCellWidth,
LeafCell->getMultipole(idxV*nRhs), SourceParticles);
for(int idxRhs = 0 ; idxRhs < nRhs ; ++idxRhs){
// update multipole index
int idxMul = idxV*nRhs + idxRhs;
// 2) apply B (PB: Tensorial version is just a basic copy)
M2LHandler->applyB(LeafCell->getMultipole(idxMul), LeafCell->getMultipole(idxMul) + AbstractBaseClass::nnodes);
}
}
}
......@@ -124,8 +111,6 @@ public:
for(int idxRhs = 0 ; idxRhs < nRhs ; ++idxRhs){
// update multipole index
int idxMul = idxV*nRhs + idxRhs;
// 1) apply Sy
FBlas::scal(AbstractBaseClass::nnodes*2, FReal(0.), ParentCell->getMultipole(idxMul));
for (unsigned int ChildIndex=0; ChildIndex < 8; ++ChildIndex){
if (ChildCells[ChildIndex]){
......@@ -136,9 +121,6 @@ public:
}
}
// 2) apply B (PB: Tensorial version is just a basic copy)
M2LHandler->applyB(ParentCell->getMultipole(idxMul), ParentCell->getMultipole(idxMul) + AbstractBaseClass::nnodes);
}
}
}
......@@ -155,7 +137,7 @@ public:
// update local index
const int idxLoc = idxV*nLhs + idxLhs;
FReal *const CompressedLocalExpansion = TargetCell->getLocal(idxLoc) + AbstractBaseClass::nnodes;
FReal *const localExpansion = TargetCell->getLocal(idxLoc);
// update idxRhs
const int idxRhs = idxLhs % nPv;
......@@ -168,8 +150,8 @@ public:
for(int idxExistingNeigh = 0 ; idxExistingNeigh < inSize ; ++idxExistingNeigh){
const int idx = neighborPositions[idxExistingNeigh];
M2LHandler->applyC(idx, TreeLevel, scale, d,
SourceCells[idxExistingNeigh]->getMultipole(idxMul) + AbstractBaseClass::nnodes,
CompressedLocalExpansion);
SourceCells[idxExistingNeigh]->getMultipole(idxMul),
localExpansion);
}
}// NLHS=NPOT*NPV
}// NVALS
......@@ -183,17 +165,12 @@ public:
for(int idxV = 0 ; idxV < NVALS ; ++idxV){
for(int idxLhs = 0 ; idxLhs < nLhs ; ++idxLhs){
int idxLoc = idxV*nLhs + idxLhs;
// 1) apply U (PB: Tensorial version is just a basic copy)
M2LHandler->applyU(ParentCell->getLocal(idxLoc) + AbstractBaseClass::nnodes,
const_cast<CellClass*>(ParentCell)->getLocal(idxLoc));
// 2) apply Sx
for (unsigned int ChildIndex=0; ChildIndex < 8; ++ChildIndex){
if (ChildCells[ChildIndex]){
AbstractBaseClass::Interpolator->applyL2L(ChildIndex,
ParentCell->getLocal(idxLoc),
ChildCells[ChildIndex]->getLocal(idxLoc),
TreeLevel/*Cell width extension specific*/);
AbstractBaseClass::Interpolator->applyL2L(ChildIndex,
ParentCell->getLocal(idxLoc),
ChildCells[ChildIndex]->getLocal(idxLoc),
TreeLevel/*Cell width extension specific*/);
}
}
}//NLHS
......@@ -209,15 +186,6 @@ public:
+ AbstractBaseClass::BoxWidthExtension);
for(int idxV = 0 ; idxV < NVALS ; ++idxV){
for(int idxLhs = 0 ; idxLhs < nLhs ; ++idxLhs){
int idxLoc = idxV*nLhs + idxLhs;
// 1) apply U (PB: Tensorial version is just a basic copy)
M2LHandler->applyU(LeafCell->getLocal(idxLoc) + AbstractBaseClass::nnodes, const_cast<CellClass*>(LeafCell)->getLocal(idxLoc));
}
// 2.c) apply Sx and Px (grad Sx)
AbstractBaseClass::Interpolator->applyL2PTotal(LeafCellCenter, ExtendedLeafCellWidth,
LeafCell->getLocal(idxV*nLhs), TargetParticles);
}
......
......@@ -39,7 +39,7 @@
#include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "Utils/FParameters.hpp"
#include "../../Src/Utils/FParameterNames.hpp"
#include "Utils/FParameterNames.hpp"
#include "Utils/FMemUtils.hpp"
#include "Containers/FOctree.hpp"
......@@ -160,7 +160,6 @@ int main(int argc, char* argv[])
// accuracy
const unsigned int ORDER = 5 ;
const FReal epsilon = FReal(1e-5);
// set box width extension
// ... either deduce from element size
const FReal LeafCellWidth = FReal(loader.getBoxWidth()) / FReal(FMath::pow(2.,TreeHeight-1));
......@@ -215,7 +214,7 @@ int main(int argc, char* argv[])
{ // -----------------------------------------------------
std::cout << "\nChebyshev FMM (ORDER="<< ORDER << ") ... " << std::endl;
time.tic();
KernelClass kernels(TreeHeight, loader.getBoxWidth(), loader.getCenterOfBox(), &MatrixKernel, BoxWidthExtension, epsilon);
KernelClass kernels(TreeHeight, loader.getBoxWidth(), loader.getCenterOfBox(), &MatrixKernel, BoxWidthExtension);
FmmClass algorithm(&tree, &kernels);
algorithm.execute();
time.tac();
......
......@@ -30,7 +30,7 @@
#include "../../Src/Utils/FTic.hpp"
#include "../../Src/Utils/FMath.hpp"
#include "../../Src/Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "../../Src/Kernels/Chebyshev/FChebM2LHandler.hpp"
#include "../../Src/Kernels/Chebyshev/FChebCmpM2LHandler.hpp"
#include "../../Src/Utils/FParameterNames.hpp"
......@@ -77,32 +77,32 @@ int main(int argc, char* argv[])
// order 2
time.tic();
FChebM2LHandler<FReal,2,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-1));
FChebM2LHandler<FReal,2,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-2));
FChebCmpM2LHandler<FReal,2,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-1));
FChebCmpM2LHandler<FReal,2,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-2));
// order 3
FChebM2LHandler<FReal,3,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-2));
FChebM2LHandler<FReal,3,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-3));
FChebCmpM2LHandler<FReal,3,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-2));
FChebCmpM2LHandler<FReal,3,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-3));
// order 4
FChebM2LHandler<FReal,4,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-3));
FChebM2LHandler<FReal,4,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-4));
FChebCmpM2LHandler<FReal,4,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-3));
FChebCmpM2LHandler<FReal,4,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-4));
// order 5
FChebM2LHandler<FReal,5,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-4));
FChebM2LHandler<FReal,5,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-5));
FChebCmpM2LHandler<FReal,5,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-4));
FChebCmpM2LHandler<FReal,5,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-5));
// order 6
FChebM2LHandler<FReal,6,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-5));
FChebM2LHandler<FReal,6,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-6));
FChebCmpM2LHandler<FReal,6,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-5));
FChebCmpM2LHandler<FReal,6,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-6));
// order 7
FChebM2LHandler<FReal,7,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-6));
FChebM2LHandler<FReal,7,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-7));
FChebCmpM2LHandler<FReal,7,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-6));
FChebCmpM2LHandler<FReal,7,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-7));
// order 8
FChebM2LHandler<FReal,8,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-7));
FChebM2LHandler<FReal,8,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-8));
FChebCmpM2LHandler<FReal,8,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-7));
FChebCmpM2LHandler<FReal,8,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-8));
// order 9
FChebM2LHandler<FReal,9,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-8));
FChebM2LHandler<FReal,9,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-9));
FChebCmpM2LHandler<FReal,9,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-8));
FChebCmpM2LHandler<FReal,9,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-9));
// order 10
FChebM2LHandler<FReal,10,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-9));
FChebM2LHandler<FReal,10,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-10));
FChebCmpM2LHandler<FReal,10,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-9));
FChebCmpM2LHandler<FReal,10,MatrixKernelClass>::ComputeAndCompressAndStoreInBinaryFile(&MatrixKernel,FReal(1e-10));
return 0;
......
......@@ -35,7 +35,7 @@
#include "../../Src/Kernels/Chebyshev/FChebTensor.hpp"
#include "../../Src/Kernels/Chebyshev/FChebM2LHandler.hpp"
#include "../../Src/Kernels/Chebyshev/FChebCmpM2LHandler.hpp"
#include "../../Src/Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "../../Src/Utils/FParameterNames.hpp"
......
......@@ -42,8 +42,8 @@
#include "Kernels/Chebyshev/FChebCell.hpp"
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "Kernels/Chebyshev/FChebSymKernel.hpp"
#include "Kernels/Chebyshev/FChebKernel.hpp"
#include "Kernels/Chebyshev/FChebSymKernel.hpp"
#include "Kernels/Uniform/FUnifCell.hpp"
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment