Commit 97641e38 authored by Quentin Khan's avatar Quentin Khan
Browse files
parents 3723194a 32a8f61c
......@@ -45,7 +45,7 @@ class FAbstractChebKernel : public FAbstractKernels< CellClass, ContainerClass>
{
protected:
enum {nnodes = TensorTraits<ORDER>::nnodes};
typedef FChebInterpolator<ORDER,MatrixKernelClass> InterpolatorClass;
typedef FChebInterpolator<ORDER,MatrixKernelClass,NVALS> InterpolatorClass;
/// Needed for P2M, M2M, L2L and L2P operators
const FSmartPointer<InterpolatorClass,FSmartPointerMemory> Interpolator;
......
This diff is collapsed.
......@@ -77,19 +77,22 @@ public:
}
FChebKernel(const int inTreeHeight, const FReal inBoxWidth, const FPoint& inBoxCenter, const MatrixKernelClass *const inMatrixKernel)
: FChebKernel(inTreeHeight, inBoxWidth,inBoxCenter,inMatrixKernel,FMath::pow(10.0,static_cast<FReal>(-ORDER)))
: FChebKernel(inTreeHeight, inBoxWidth,inBoxCenter,inMatrixKernel,FReal(0.)/*FMath::pow(10.0,static_cast<FReal>(-ORDER))*/)
{
}
void P2M(CellClass* const LeafCell,
const ContainerClass* const SourceParticles)
{
const FPoint LeafCellCenter(AbstractBaseClass::getLeafCellCenter(LeafCell->getCoordinate()));
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 1) apply Sy
AbstractBaseClass::Interpolator->applyP2M(LeafCellCenter, AbstractBaseClass::BoxWidthLeaf,
LeafCell->getMultipole(idxRhs), SourceParticles);
LeafCell->getMultipole(0), SourceParticles);
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 2) apply B
M2LHandler->applyB(LeafCell->getMultipole(idxRhs), LeafCell->getMultipole(idxRhs) + AbstractBaseClass::nnodes);
}
......@@ -102,7 +105,6 @@ public:
{
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// 1) apply Sy
FBlas::scal(AbstractBaseClass::nnodes*2, FReal(0.), ParentCell->getMultipole(idxRhs));
for (unsigned int ChildIndex=0; ChildIndex < 8; ++ChildIndex){
if (ChildCells[ChildIndex]){
AbstractBaseClass::Interpolator->applyM2M(ChildIndex, ChildCells[ChildIndex]->getMultipole(idxRhs),
......@@ -192,22 +194,23 @@ public:
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,
// LeafCell->getLocal(),
// LeafCell->getLocal(0),
// TargetParticles);
//// 2.b) apply Px (grad Sx)
//AbstractBaseClass::Interpolator->applyL2PGradient(LeafCellCenter,
// AbstractBaseClass::BoxWidthLeaf,
// LeafCell->getLocal(),
// LeafCell->getLocal(0),
// TargetParticles);
// 2.c) apply Sx and Px (grad Sx)
AbstractBaseClass::Interpolator->applyL2PTotal(LeafCellCenter, AbstractBaseClass::BoxWidthLeaf,
LeafCell->getLocal(idxRhs), TargetParticles);
}
LeafCell->getLocal(0), TargetParticles);
}
void P2P(const FTreeCoordinate& /* LeafCellCoordinate */, // needed for periodic boundary conditions
......
......@@ -180,10 +180,8 @@ public:
{
// apply Sy
const FPoint LeafCellCenter(AbstractBaseClass::getLeafCellCenter(LeafCell->getCoordinate()));
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
AbstractBaseClass::Interpolator->applyP2M(LeafCellCenter, AbstractBaseClass::BoxWidthLeaf,
LeafCell->getMultipole(idxRhs), SourceParticles);
}
LeafCell->getMultipole(0), SourceParticles);
}
......@@ -445,7 +443,6 @@ public:
ContainerClass* const TargetParticles)
{
const FPoint LeafCellCenter(AbstractBaseClass::getLeafCellCenter(LeafCell->getCoordinate()));
for(int idxRhs = 0 ; idxRhs < NVALS ; ++idxRhs){
// // a) apply Sx
// AbstractBaseClass::Interpolator->applyL2P(LeafCellCenter,
// AbstractBaseClass::BoxWidthLeaf,
......@@ -459,8 +456,8 @@ public:
// c) apply Sx and Px (grad Sx)
AbstractBaseClass::Interpolator->applyL2PTotal(LeafCellCenter, AbstractBaseClass::BoxWidthLeaf,
LeafCell->getLocal(idxRhs), TargetParticles);
}
LeafCell->getLocal(0), TargetParticles);
}
void P2P(const FTreeCoordinate& /* LeafCellCoordinate */, // needed for periodic boundary conditions
......
......@@ -38,6 +38,7 @@
#include "Kernels/Chebyshev/FChebCell.hpp"
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "Kernels/Chebyshev/FChebSymKernel.hpp"
#include "Kernels/Chebyshev/FChebKernel.hpp"
#include "Kernels/Uniform/FUnifCell.hpp"
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
......@@ -102,35 +103,20 @@ class TestInterpolationKernel : public FUTester<TestInterpolationKernel> {
// Create octree
OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
// Insert particle in the tree
// For each particles we associate Nvals charge ( q,0,0,0)
for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
double q = particles[idxPart].getPhysicalValue();
if(NVals == 1){
tree.insert(particles[idxPart].getPosition() , idxPart, q);//,0.0,0.0,0.0);
}
else if(NVals == 2){
tree.insert(particles[idxPart].getPosition() , idxPart, q, q);//,0.0,0.0,0.0);
}
else if(NVals == 3){
tree.insert(particles[idxPart].getPosition() , idxPart, q, q,q);//,0.0,0.0,0.0);
} else{
FAssertLF(0, "NVALS should be <= 3");
for(int idxPart = 0 ; idxPart < nbParticles ; ++idxPart){
// Convert FReal[NVALS] to std::array<FReal,NVALS>
std::array<FReal, (1+4*1)*NVals> physicalState;
for(int idxVals = 0 ; idxVals < NVals ; ++idxVals){
physicalState[0*NVals+idxVals]= particles[idxPart].getPhysicalValue();
physicalState[1*NVals+idxVals]=0.0;
physicalState[2*NVals+idxVals]=0.0;
physicalState[3*NVals+idxVals]=0.0;
physicalState[4*NVals+idxVals]=0.0;
}
// put in tree
tree.insert(particles[idxPart].getPosition(), idxPart, physicalState);
}
// for(int idxPart = 0 ; idxPart < nbParticles ; ++idxPart){
// // Convert FReal[NVALS] to std::array<FReal,NVALS>
// std::array<FReal, (1+4*1)*NVals> physicalState;
// for(int idxVals = 0 ; idxVals < NVals ; ++idxVals){
// double q = particles[idxPart].getPhysicalValue();
// physicalState[0*NVals+idxVals]= q;
// physicalState[1*NVals+idxVals]=0.0;
// physicalState[2*NVals+idxVals]=0.0;
// physicalState[3*NVals+idxVals]=0.0;
// physicalState[4*NVals+idxVals]=0.0;
// }
// // put in tree
// tree.insert(particles[idxPart].getPosition(), idxPart, physicalState);
// }
// Run FMM
Print("Fmm...");
......@@ -307,7 +293,20 @@ class TestInterpolationKernel : public FUTester<TestInterpolationKernel> {
RunTest<CellClass,ContainerClass,KernelClass,MatrixKernelClass,LeafClass,OctreeClass,FmmClass, NVals>();
}
/** TestChebKernel */
void TestChebKernel(){
const int NVals = 3;
const unsigned int ORDER = 6;
typedef FP2PParticleContainerIndexed<1,1,NVals> ContainerClass;
typedef FSimpleLeaf<ContainerClass> LeafClass;
typedef FInterpMatrixKernelR MatrixKernelClass;
typedef FChebCell<ORDER, 1, 1, NVals> CellClass;
typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
typedef FChebKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER, NVals> KernelClass;
typedef FFmmAlgorithm<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
// run test
RunTest<CellClass,ContainerClass,KernelClass,MatrixKernelClass,LeafClass,OctreeClass,FmmClass, NVals>();
}
///////////////////////////////////////////////////////////
// Set the tests!
......@@ -318,6 +317,8 @@ class TestInterpolationKernel : public FUTester<TestInterpolationKernel> {
AddTest(&TestInterpolationKernel::TestUnifKernel,"Test Lagrange/Uniform grid FMM");
AddTest(&TestInterpolationKernel::TestChebSymKernel,"Test Symmetric Chebyshev Kernel with 16 small SVDs and symmetries");
AddTest(&TestInterpolationKernel::TestChebKernel,"Test Chebyshev Kernel with 1 large SVD");
}
};
......
......@@ -49,9 +49,10 @@ class TestRotationDirectPeriodic : public FUTester<TestRotationDirectPeriodic> {
const int NbLevels = 4;
const int SizeSubLevels = 2;
const int PeriodicDeep = 2;
const int NbParticles = 100;
const int nbParticles = 100;
FRandomLoader loader(NbParticles);
FRandomLoader loader(nbParticles);
//
OctreeClass tree(NbLevels, SizeSubLevels, loader.getBoxWidth(), loader.getCenterOfBox());
struct TestParticle{
FPoint position;
......@@ -59,13 +60,14 @@ class TestRotationDirectPeriodic : public FUTester<TestRotationDirectPeriodic> {
FReal physicalValue;
FReal potential;
};
FReal coeff = -1.0, value = 0.10, sum = 0.0;
FReal coeff = -1.0, value = 0.10, sum = 0.0, coerr =0.0, a=0.0;
TestParticle* const particles = new TestParticle[loader.getNumberOfParticles()];
for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
FPoint position;
loader.fillParticle(&position);
value *= coeff ;
sum += value ;
coerr += FMath::Abs(value);
// put in tree
tree.insert(position, idxPart, value);
// get copy
......@@ -75,7 +77,10 @@ class TestRotationDirectPeriodic : public FUTester<TestRotationDirectPeriodic> {
particles[idxPart].forces[0] = 0.0;
particles[idxPart].forces[1] = 0.0;
particles[idxPart].forces[2] = 0.0;
a = std::max(a,position.getX()*position.getX()+position.getY()*position.getY()+position.getZ()*position.getZ());
}
double CorErr = coerr/a;
if (FMath::Abs(sum)> 0.00001){
std::cerr << "Sum of charges is not equal zero!!! (sum=<<"<<sum<<" )"<<std::endl;
exit(-1);
......@@ -112,7 +117,7 @@ class TestRotationDirectPeriodic : public FUTester<TestRotationDirectPeriodic> {
loader.getBoxWidth() * FReal(idxY),
loader.getBoxWidth() * FReal(idxZ));
for(int idxSource = 0 ; idxSource < NbParticles ; ++idxSource){
for(int idxSource = 0 ; idxSource < nbParticles ; ++idxSource){
TestParticle source = particles[idxSource];
source.position += offset;
......@@ -186,29 +191,39 @@ class TestRotationDirectPeriodic : public FUTester<TestRotationDirectPeriodic> {
printf(" Energy DIRECT = %.12e\n",FMath::Abs(energyD));
// Assert
const FReal MaximumDiffPotential = FReal(9e-3);
const FReal MaximumDiffForces = FReal(9e-2);
double epsilon = 1.0/FMath::pow2(P);
const FReal MaximumDiffPotential = FReal(CorErr*epsilon);
const FReal MaximumDiffForces = FReal(10*CorErr*epsilon);
printf(" Criteria error - Epsilon %e \n",epsilon);
Print("Test1 - Error Relative L2 norm Potential ");
uassert(potentialDiff.getRelativeL2Norm() < MaximumDiffPotential); //1
Print("Test2 - Error RMS L2 norm Potential ");
uassert(potentialDiff.getRMSError() < MaximumDiffPotential); //2
FReal CoerrRMS = potentialDiff.getl2Dot()/FMath::Sqrt(static_cast<FReal>(nbParticles));
uassert(potentialDiff.getRMSError() < CoerrRMS*MaximumDiffPotential); //2
Print("Test3 - Error Relative L2 norm FX ");
uassert(fx.getRelativeL2Norm() < MaximumDiffForces); //3
uassert(fx.getRelativeL2Norm() < MaximumDiffForces);
CoerrRMS = fx.getl2Dot()/FMath::Sqrt(static_cast<FReal>(nbParticles));
//3
Print("Test4 - Error RMS L2 norm FX ");
uassert(fx.getRMSError() < MaximumDiffForces); //4
uassert(fx.getRMSError() < CoerrRMS*MaximumDiffForces); //4
Print("Test5 - Error Relative L2 norm FY ");
uassert(fy.getRelativeL2Norm() < MaximumDiffForces); //5
Print("Test6 - Error RMS L2 norm FY ");
uassert(fy.getRMSError() < MaximumDiffForces); //6
CoerrRMS = fy.getl2Dot()/FMath::Sqrt(static_cast<FReal>(nbParticles));
uassert(fy.getRMSError() < CoerrRMS*MaximumDiffForces); //6
Print("Test7 - Error Relative L2 norm FZ ");
uassert(fz.getRelativeL2Norm() < MaximumDiffForces); //8
Print("Test8 - Error RMS L2 norm FZ ");
uassert(fz.getRMSError() < MaximumDiffForces); //8
CoerrRMS = fz.getl2Dot()/FMath::Sqrt(static_cast<FReal>(nbParticles));
uassert(fz.getRMSError() < CoerrRMS*MaximumDiffForces); //8
Print("Test9 - Error Relative L2 norm F ");
uassert(L2error < MaximumDiffForces); //9 Total Force
Print("Test10 - Relative error Energy ");
uassert(FMath::Abs(energy-energyD) /energyD< MaximumDiffPotential); //10 Total Energy
uassert(FMath::Abs(energy-energyD)< coerr*MaximumDiffPotential); //10 Total Energy
delete[] particles;
}
......
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