Commit 00014c51 authored by berenger-bramas's avatar berenger-bramas

Add and use a smart pointer for M2L precomputed array.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@381 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 2832bb57
......@@ -81,7 +81,7 @@ public:
directPass();
}
private:
/////////////////////////////////////////////////////////////////////////////
// P2M
/////////////////////////////////////////////////////////////////////////////
......
......@@ -16,6 +16,7 @@
#include "../Utils/FGlobal.hpp"
#include "../Utils/FTrace.hpp"
#include "../Utils/FMemUtils.hpp"
#include "../Utils/FSmartPointer.hpp"
#include "../Containers/FTreeCoordinate.hpp"
......@@ -41,16 +42,16 @@ protected:
FHarmonic harmonic; //< The harmonic computation class
// For normal computation
FComplexe** preL2LTransitions; //< The pre-computation for the L2L based on the level
FComplexe** preM2MTransitions; //< The pre-computation for the M2M based on the level
FSmartPointer<FComplexe*> preL2LTransitions; //< The pre-computation for the L2L based on the level
FSmartPointer<FComplexe*> preM2MTransitions; //< The pre-computation for the M2M based on the level
/** Alloc and init pre-vectors*/
void allocAndInit(){
preL2LTransitions = new FComplexe*[treeHeight + periodicLevels];
memset(preL2LTransitions, 0, (treeHeight + periodicLevels) * sizeof(FComplexe*));
memset(preL2LTransitions.getPtr(), 0, (treeHeight + periodicLevels) * sizeof(FComplexe*));
preM2MTransitions = new FComplexe*[treeHeight + periodicLevels];
memset(preM2MTransitions, 0, (treeHeight + periodicLevels) * sizeof(FComplexe*));
memset(preM2MTransitions.getPtr(), 0, (treeHeight + periodicLevels) * sizeof(FComplexe*));
FReal treeWidthAtLevel = (boxWidth * FReal(1 << periodicLevels))/2;
for(int idxLevel = -periodicLevels ; idxLevel < treeHeight - 1 ; ++idxLevel ){
......@@ -107,7 +108,7 @@ public:
harmonic(inDevP),
preL2LTransitions(0),
preM2MTransitions(0) {
std::cout << "widthAtLeafLevel " << widthAtLeafLevel << "\n";
allocAndInit();
}
......@@ -121,17 +122,19 @@ public:
widthAtLeafLevelDiv2(other.widthAtLeafLevelDiv2),
boxCorner(other.boxCorner),
harmonic(other.devP),
preL2LTransitions(0), preM2MTransitions(0) {
preL2LTransitions(other.preL2LTransitions),
preM2MTransitions(other.preM2MTransitions) {
allocAndInit();
}
/** Default destructor */
virtual ~FAbstractSphericalKernel(){
FMemUtils::DeleteAll(preL2LTransitions, treeHeight + periodicLevels);
delete[] preL2LTransitions;
FMemUtils::DeleteAll(preM2MTransitions, treeHeight + periodicLevels);
delete[] preM2MTransitions;
if(preL2LTransitions.isLast()){
FMemUtils::DeleteAll(preL2LTransitions.getPtr(), treeHeight + periodicLevels);
}
if(preM2MTransitions.isLast()){
FMemUtils::DeleteAll(preM2MTransitions.getPtr(), treeHeight + periodicLevels);
}
}
/** P2M with a cell and all its particles */
......@@ -201,11 +204,17 @@ public:
ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
ContainerClass* const directNeighborsParticles[27], const int size){
if( targets == sources ){
P2PNoTsm(inLeafPosition, targets, directNeighborsParticles, size);
if( periodicLevels == 0 && targets == sources ){
P2PNoTsm(targets, directNeighborsParticles);
}
else{
P2PTsm(inLeafPosition, targets, sources, directNeighborsParticles, size);
else if(periodicLevels == 0 /* && targets != sources */) {
P2PTsm(targets, sources, directNeighborsParticles);
}
else if( targets == sources /* && periodicLevels != 0 */){
P2PNoTsmPeriodic(inLeafPosition, targets, directNeighborsParticles);
}
else { // if(periodicLevels != 0 && periodicLevels != 0 ) {
P2PTsmPeriodic(inLeafPosition, targets, sources, directNeighborsParticles);
}
}
......@@ -223,9 +232,8 @@ private:
* then it computes the sources/targets inteactions between this leaf and the
* neighbors.
*/
void P2PTsm(const FTreeCoordinate& inLeafPosition,
ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
ContainerClass* const directNeighborsParticles[27], const int ){
void P2PTsm(ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
ContainerClass* const directNeighborsParticles[27]){
{ // Compute interaction in this leaf
typename ContainerClass::BasicIterator iterTarget(*targets);
......@@ -275,9 +283,8 @@ private:
* then it computes the inteactions between this leaf and the
* neighbors.
*/
void P2PNoTsm(const FTreeCoordinate& inLeafPosition,
ContainerClass* const FRestrict targets,
ContainerClass* const directNeighborsParticles[27], const int ){
void P2PNoTsm(ContainerClass* const FRestrict targets,
ContainerClass* const directNeighborsParticles[27] ){
{ // Compute interaction in this leaf
typename ContainerClass::BasicIterator iterTarget(*targets);
while( iterTarget.hasNotFinished() ){
......@@ -308,6 +315,7 @@ private:
typename ContainerClass::BasicIterator iterSource(*directNeighborsParticles[idxDirectNeighbors]);
while( iterSource.hasNotFinished() ){
directInteractionMutual(&target, &iterSource.data());
iterSource.gotoNext();
}
// Set data and progress
......@@ -320,6 +328,200 @@ private:
}
/** This P2P has to be used when target != sources
* It will proceed an direct interation no mutual
*
* It takes all the target particles from the current leaf,
* then it computes the sources/targets interaction in this leaf,
* then it computes the sources/targets inteactions between this leaf and the
* neighbors.
*/
void P2PTsmPeriodic(const FTreeCoordinate& inLeafPosition,
ContainerClass* const FRestrict targets, const ContainerClass* const FRestrict sources,
ContainerClass* const directNeighborsParticles[27]){
const int limite = FMath::pow2(treeHeight-1) - 1;
if( inLeafPosition.getX() == 0 || inLeafPosition.getX() == limite ||
inLeafPosition.getY() == 0 || inLeafPosition.getY() == limite ||
inLeafPosition.getZ() == 0 || inLeafPosition.getZ() == limite){
{ // Compute interaction in this leaf
typename ContainerClass::BasicIterator iterTarget(*targets);
while( iterTarget.hasNotFinished() ){
// We copy the target particle to work with a particle in the heap
ParticleClass target( iterTarget.data() );
// For all the source particles in the same leaf
typename ContainerClass::ConstBasicIterator iterSameBox(*sources);
while( iterSameBox.hasNotFinished() ){
directInteraction(&target, iterSameBox.data());
iterSameBox.gotoNext();
}
// Set data and progress
iterTarget.setData(target);
iterTarget.gotoNext();
}
}
{ // Compute interactions with other leaves
// For all the neigbors leaves
for(int idxDirectNeighbors = 0 ; idxDirectNeighbors < 27 ; ++idxDirectNeighbors){
if( directNeighborsParticles[idxDirectNeighbors] ){
const int zrelatif = (idxDirectNeighbors%3) - 1;
const int yrelatif = ((idxDirectNeighbors%(3*3))/3)-1;
const int xrelatif = (idxDirectNeighbors / (3*3))-1;
FReal xoffset = 0;
FReal yoffset = 0;
FReal zoffset = 0;
if( inLeafPosition.getX() == 0 && xrelatif == -1){
xoffset = -boxWidth;
}
else if (inLeafPosition.getX() == limite && xrelatif == 1){
xoffset = boxWidth;
}
if( inLeafPosition.getY() == 0 && yrelatif == -1){
yoffset = -boxWidth;
}
else if (inLeafPosition.getY() == limite && yrelatif == 1){
yoffset = boxWidth;
}
if( inLeafPosition.getZ() == 0 && zrelatif == -1){
zoffset = -boxWidth;
}
else if (inLeafPosition.getZ() == limite && zrelatif == 1){
zoffset = boxWidth;
}
// For all particles in current leaf
typename ContainerClass::BasicIterator iterTarget(*targets);
while( iterTarget.hasNotFinished() ){
ParticleClass target( iterTarget.data() );
// For all the particles in the other leaf
typename ContainerClass::ConstBasicIterator iterSource(*directNeighborsParticles[idxDirectNeighbors]);
while( iterSource.hasNotFinished() ){
ParticleClass sourcePart( iterSource.data() );
sourcePart.setPosition(
sourcePart.getPosition().getX() + xoffset,
sourcePart.getPosition().getY() + yoffset,
sourcePart.getPosition().getZ() + zoffset
);
directInteraction(&target, sourcePart);
iterSource.gotoNext();
}
// Set data and progress
iterTarget.setData(target);
iterTarget.gotoNext();
}
}
}
}
}
else{
P2PTsm(targets, sources, directNeighborsParticles);
}
}
/** This P2P has to be used when target == sources
* It will proceed a direct interation >> mutual
*
* It takes all the particles from the current leaf,
* then it computes the interactions in this leaf,
* then it computes the inteactions between this leaf and the
* neighbors.
*/
void P2PNoTsmPeriodic(const FTreeCoordinate& inLeafPosition,
ContainerClass* const FRestrict targets,
ContainerClass* const directNeighborsParticles[27]){
const int limite = FMath::pow2(treeHeight-1) - 1;
if( inLeafPosition.getX() == 0 || inLeafPosition.getX() == limite ||
inLeafPosition.getY() == 0 || inLeafPosition.getY() == limite ||
inLeafPosition.getZ() == 0 || inLeafPosition.getZ() == limite){
{ // Compute interaction in this leaf
typename ContainerClass::BasicIterator iterTarget(*targets);
while( iterTarget.hasNotFinished() ){
// We copy the target particle to work with a particle in the heap
ParticleClass target( iterTarget.data() );
// For all particles after the current one
typename ContainerClass::BasicIterator iterSameBox = iterTarget;
iterSameBox.gotoNext();
while( iterSameBox.hasNotFinished() ){
directInteractionMutual(&target, &iterSameBox.data());
iterSameBox.gotoNext();
}
// Set data and progress
iterTarget.setData(target);
iterTarget.gotoNext();
}
}
{ // Compute interactions with other leaves
// For all the neigbors leaves
for(int idxDirectNeighbors = 0 ; idxDirectNeighbors <= 13 ; ++idxDirectNeighbors){
if( directNeighborsParticles[idxDirectNeighbors] ){
const int zrelatif = (idxDirectNeighbors%3) - 1;
const int yrelatif = ((idxDirectNeighbors%(3*3))/3)-1;
const int xrelatif = (idxDirectNeighbors / (3*3))-1;
FReal xoffset = 0;
FReal yoffset = 0;
FReal zoffset = 0;
if( inLeafPosition.getX() == 0 && xrelatif == -1){
xoffset = -boxWidth;
}
else if (inLeafPosition.getX() == limite && xrelatif == 1){
xoffset = boxWidth;
}
if( inLeafPosition.getY() == 0 && yrelatif == -1){
yoffset = -boxWidth;
}
else if (inLeafPosition.getY() == limite && yrelatif == 1){
yoffset = boxWidth;
}
if( inLeafPosition.getZ() == 0 && zrelatif == -1){
zoffset = -boxWidth;
}
else if (inLeafPosition.getZ() == limite && zrelatif == 1){
zoffset = boxWidth;
}
// For all particles in current leaf
typename ContainerClass::BasicIterator iterTarget(*targets);
while( iterTarget.hasNotFinished() ){
ParticleClass target( iterTarget.data() );
// For all the particles in the other leaf
typename ContainerClass::BasicIterator iterSource(*directNeighborsParticles[idxDirectNeighbors]);
while( iterSource.hasNotFinished() ){
iterSource.data().setPosition(
iterSource.data().getPosition().getX() + xoffset,
iterSource.data().getPosition().getY() + yoffset,
iterSource.data().getPosition().getZ() + zoffset
);
directInteractionMutual(&target, &iterSource.data());
iterSource.data().setPosition(
iterSource.data().getPosition().getX() - xoffset,
iterSource.data().getPosition().getY() - yoffset,
iterSource.data().getPosition().getZ() - zoffset
);
iterSource.gotoNext();
}
// Set data and progress
iterTarget.setData(target);
iterTarget.gotoNext();
}
}
}
}
}
else {
P2PNoTsm(targets, directNeighborsParticles);
}
}
///////////////////////////////////////////////////////////////////////////////
// Computation
///////////////////////////////////////////////////////////////////////////////
......@@ -714,7 +916,8 @@ public:
* F = q * q' / r²
*/
void directInteractionMutual(ParticleClass*const FRestrict target, ParticleClass*const FRestrict source){
//TODO std::cout << "P2P Mutual between " << target->getPosition() << " and " << source->getPosition() << std::endl;//TODO delete
//TODO std::cout << target << " / " << source << std::endl;
FReal dx = -(target->getPosition().getX() - source->getPosition().getX());
FReal dy = -(target->getPosition().getY() - source->getPosition().getY());
FReal dz = -(target->getPosition().getZ() - source->getPosition().getZ());
......@@ -740,7 +943,8 @@ public:
* F = q * q' / r²
*/
void directInteraction(ParticleClass*const FRestrict target, const ParticleClass& source){
//TODO std::cout << "P2P between " << target->getPosition() << " and " << source.getPosition() << std::endl;//TODO delete
//TODO std::cout << target << " / " << &source << std::endl;
FReal dx = -(target->getPosition().getX() - source.getPosition().getX());
FReal dy = -(target->getPosition().getY() - source.getPosition().getY());
FReal dz = -(target->getPosition().getZ() - source.getPosition().getZ());
......@@ -759,28 +963,6 @@ public:
target->incPotential( inv_distance * source.getPhysicalValue() );
}
/** P2P NO mutual interaction with an offset
* F = q * q' / r²
*/
void directInteractionOffset(ParticleClass*const FRestrict target, const ParticleClass& source, const FTreeCoordinate& offset){
FReal dx = -(target->getPosition().getX() - source.getPosition().getX()) + FReal(offset.getX()) * boxWidth;
FReal dy = -(target->getPosition().getY() - source.getPosition().getY()) + FReal(offset.getY()) * boxWidth;
FReal dz = -(target->getPosition().getZ() - source.getPosition().getZ()) + FReal(offset.getZ()) * boxWidth;
FReal inv_square_distance = FReal(1.0) / (dx*dx + dy*dy + dz*dz);
FReal inv_distance = FMath::Sqrt(inv_square_distance);
inv_square_distance *= inv_distance;
inv_square_distance *= target->getPhysicalValue() * source.getPhysicalValue();
dx *= inv_square_distance;
dy *= inv_square_distance;
dz *= inv_square_distance;
target->incForces( dx, dy, dz);
target->incPotential( inv_distance * source.getPhysicalValue() );
}
/** Update a velocity of a particle
*
......
......@@ -29,8 +29,8 @@ protected:
const int FF_MATRIX_COLUMN_DIM; //< The blas matrix number of columns
const int FF_MATRIX_SIZE; //< The blas matrix size
FComplexe* temporaryMultiSource; //< To perform the M2L without allocating at each call
FComplexe** preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
FComplexe* temporaryMultiSource; //< To perform the M2L without allocating at each call
FSmartPointer<FComplexe*> preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
/** To access te precomputed M2L transfer matrixes */
int indexM2LTransition(const int idxX,const int idxY,const int idxZ) const {
......@@ -39,15 +39,13 @@ protected:
/** Alloc and init pre-vectors*/
void allocAndInit(){
temporaryMultiSource = new FComplexe[FF_MATRIX_COLUMN_DIM];
FHarmonic blasHarmonic(Parent::devP * 2);
// M2L transfer, there is a maximum of 3 neighbors in each direction,
// so 6 in each dimension
FReal treeWidthAtLevel = Parent::boxWidth * FReal( 1 << Parent::periodicLevels);
preM2LTransitions = new FComplexe*[Parent::treeHeight + Parent::periodicLevels];
memset(preM2LTransitions, 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
memset(preM2LTransitions.getPtr(), 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
preM2LTransitions[idxLevel + Parent::periodicLevels] = new FComplexe[(7 * 7 * 7) * FF_MATRIX_SIZE];
......@@ -99,7 +97,9 @@ public:
: Parent(inDevP, inTreeHeight, inBoxWidth, inBoxCenter, inPeriodicLevel),
FF_MATRIX_ROW_DIM(Parent::harmonic.getExpSize()), FF_MATRIX_COLUMN_DIM(Parent::harmonic.getNExpSize()),
FF_MATRIX_SIZE(FF_MATRIX_ROW_DIM * FF_MATRIX_COLUMN_DIM),
temporaryMultiSource(0), preM2LTransitions(0){
temporaryMultiSource(new FComplexe[FF_MATRIX_COLUMN_DIM]),
preM2LTransitions(0){
allocAndInit();
}
......@@ -108,15 +108,16 @@ public:
: Parent(other),
FF_MATRIX_ROW_DIM(other.FF_MATRIX_ROW_DIM), FF_MATRIX_COLUMN_DIM(other.FF_MATRIX_COLUMN_DIM),
FF_MATRIX_SIZE(other.FF_MATRIX_SIZE),
temporaryMultiSource(0), preM2LTransitions(0) {
allocAndInit();
temporaryMultiSource(new FComplexe[FF_MATRIX_COLUMN_DIM]),
preM2LTransitions(other.preM2LTransitions) {
}
/** Destructor */
~FSphericalBlasKernel(){
delete[] temporaryMultiSource;
FMemUtils::DeleteAll(preM2LTransitions, Parent::treeHeight + Parent::periodicLevels);
delete[] preM2LTransitions;
if(preM2LTransitions.isLast()){
FMemUtils::DeleteAll(preM2LTransitions.getPtr(), Parent::treeHeight + Parent::periodicLevels);
}
}
/** M2L with a cell and all the existing neighbors */
......
......@@ -29,8 +29,8 @@ protected:
const int FF_MATRIX_COLUMN_DIM; //< The blas matrix number of columns
const int FF_MATRIX_SIZE; //< The blas matrix size
FComplexe* temporaryMultiSource; //< To perform the M2L without allocating at each call
FComplexe** preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
FComplexe* temporaryMultiSource; //< To perform the M2L without allocating at each call
FSmartPointer<FComplexe*> preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
/** To access te precomputed M2L transfer matrixes */
int indexM2LTransition(const int idxX,const int idxY,const int idxZ) const {
......@@ -39,7 +39,6 @@ protected:
/** Alloc and init pre-vectors*/
void allocAndInit(){
temporaryMultiSource = new FComplexe[FF_MATRIX_COLUMN_DIM];
FHarmonic blasHarmonic(Parent::devP * 2);
......@@ -47,7 +46,7 @@ protected:
// so 6 in each dimension
FReal treeWidthAtLevel = Parent::boxWidth * FReal( 1 << Parent::periodicLevels);
preM2LTransitions = new FComplexe*[Parent::treeHeight + Parent::periodicLevels];
memset(preM2LTransitions, 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
memset(preM2LTransitions.getPtr(), 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
preM2LTransitions[idxLevel + Parent::periodicLevels] = new FComplexe[(7 * 7 * 7) * FF_MATRIX_SIZE];
......@@ -99,7 +98,8 @@ public:
: Parent(inDevP, inTreeHeight, inBoxWidth, inBoxCenter, inPeriodicLevel),
FF_MATRIX_ROW_DIM(Parent::harmonic.getExpSize()), FF_MATRIX_COLUMN_DIM(Parent::harmonic.getNExpSize()),
FF_MATRIX_SIZE(FF_MATRIX_ROW_DIM * FF_MATRIX_COLUMN_DIM),
temporaryMultiSource(0), preM2LTransitions(0){
temporaryMultiSource(new FComplexe[FF_MATRIX_COLUMN_DIM]),
preM2LTransitions(0){
allocAndInit();
}
......@@ -108,15 +108,17 @@ public:
: Parent(other),
FF_MATRIX_ROW_DIM(other.FF_MATRIX_ROW_DIM), FF_MATRIX_COLUMN_DIM(other.FF_MATRIX_COLUMN_DIM),
FF_MATRIX_SIZE(other.FF_MATRIX_SIZE),
temporaryMultiSource(0), preM2LTransitions(0) {
allocAndInit();
temporaryMultiSource(new FComplexe[FF_MATRIX_COLUMN_DIM]),
preM2LTransitions(other.preM2LTransitions) {
}
/** Destructor */
~FSphericalBlockBlasKernel(){
delete[] temporaryMultiSource;
FMemUtils::DeleteAll(preM2LTransitions, Parent::treeHeight + Parent::periodicLevels);
delete[] preM2LTransitions;
if(preM2LTransitions.isLast()){
FMemUtils::DeleteAll(preM2LTransitions.getPtr(), Parent::treeHeight + Parent::periodicLevels);
}
}
/** M2L with a cell and all the existing neighbors */
......
......@@ -25,7 +25,7 @@ protected:
const int devM2lP; //< A secondary P
FComplexe** preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
FSmartPointer<FComplexe*> preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
/** To access te pre computed M2L transfer vector */
int indexM2LTransition(const int idxX,const int idxY,const int idxZ) const {
......@@ -37,7 +37,7 @@ protected:
// M2L transfer, there is a maximum of 3 neighbors in each direction,
// so 6 in each dimension
preM2LTransitions = new FComplexe*[Parent::treeHeight + Parent::periodicLevels];
memset(preM2LTransitions, 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
memset(preM2LTransitions.getPtr(), 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
// We start from the higher level
FReal treeWidthAtLevel = Parent::boxWidth * FReal(1 << Parent::periodicLevels);
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
......@@ -70,20 +70,23 @@ public:
*/
FSphericalKernel(const int inDevP, const int inTreeHeight, const FReal inBoxWidth, const F3DPosition& inBoxCenter, const int inPeriodicLevel = 0)
: Parent(inDevP, inTreeHeight, inBoxWidth, inBoxCenter, inPeriodicLevel),
devM2lP(int(((inDevP*2)+1) * ((inDevP*2)+2) * 0.5)), preM2LTransitions(0) {
devM2lP(int(((inDevP*2)+1) * ((inDevP*2)+2) * 0.5)),
preM2LTransitions(0) {
allocAndInit();
}
/** Copy constructor */
FSphericalKernel(const FSphericalKernel& other)
: Parent(other), devM2lP(other.devM2lP), preM2LTransitions(0) {
allocAndInit();
: Parent(other), devM2lP(other.devM2lP),
preM2LTransitions(other.preM2LTransitions) {
}
/** Destructor */
~FSphericalKernel(){
FMemUtils::DeleteAll(preM2LTransitions, Parent::treeHeight + Parent::periodicLevels);
delete[] preM2LTransitions;
if( preM2LTransitions.isLast() ){
FMemUtils::DeleteAll(preM2LTransitions.getPtr(), Parent::treeHeight + Parent::periodicLevels);
}
}
/** M2L with a cell and all the existing neighbors */
......
......@@ -340,7 +340,7 @@ protected:
const int devM2lP; //< A secondary P
RotationM2LTransfer** preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
FSmartPointer<RotationM2LTransfer*> preM2LTransitions; //< The pre-computation for the M2L based on the level and the 189 possibilities
RotationInfo rotation_Info;
/** To access te pre computed M2L transfer vector */
......@@ -353,7 +353,7 @@ protected:
// M2L transfer, there is a maximum of 3 neighbors in each direction,
// so 6 in each dimension
preM2LTransitions = new RotationM2LTransfer*[Parent::treeHeight + Parent::periodicLevels];
memset(preM2LTransitions, 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
memset(preM2LTransitions.getPtr(), 0, sizeof(FComplexe*) * (Parent::treeHeight + Parent::periodicLevels));
// We start from the higher level
FReal treeWidthAtLevel = Parent::boxWidth * FReal(1 << Parent::periodicLevels);
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
......@@ -387,25 +387,30 @@ public:
*/
FSphericalRotationKernel(const int inDevP, const int inTreeHeight, const FReal inBoxWidth, const F3DPosition& inBoxCenter, const int inPeriodicLevel = 0)
: Parent(inDevP, inTreeHeight, inBoxWidth, inBoxCenter, inPeriodicLevel),
devM2lP(int(((inDevP*2)+1) * ((inDevP*2)+2) * 0.5)), preM2LTransitions(0), rotation_Info(inDevP) {
devM2lP(int(((inDevP*2)+1) * ((inDevP*2)+2) * 0.5)),
preM2LTransitions(0),
rotation_Info(inDevP) {
allocAndInit();
}
/** Copy constructor */
FSphericalRotationKernel(const FSphericalRotationKernel& other)
: Parent(other), devM2lP(other.devM2lP), preM2LTransitions(0), rotation_Info(other.devP) {
allocAndInit();
: Parent(other), devM2lP(other.devM2lP),
preM2LTransitions(other.preM2LTransitions),
rotation_Info(other.devP) {
}
/** Destructor */
~FSphericalRotationKernel(){
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
for(int idx = 0 ; idx < 7*7*7 ; ++idx ){
preM2LTransitions[idxLevel + Parent::periodicLevels][idx].~RotationM2LTransfer();
if( preM2LTransitions.isLast() ){
for(int idxLevel = -Parent::periodicLevels ; idxLevel < Parent::treeHeight ; ++idxLevel ){
for(int idx = 0 ; idx < 7*7*7 ; ++idx ){
preM2LTransitions[idxLevel + Parent::periodicLevels][idx].~RotationM2LTransfer();
}
delete[] reinterpret_cast<char*>(preM2LTransitions[idxLevel + Parent::periodicLevels]);
}
delete[] reinterpret_cast<char*>(preM2LTransitions[idxLevel + Parent::periodicLevels]);
}
delete[] preM2LTransitions;
}