Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
solverstack
ScalFMM
Commits
8067ae8b
Commit
8067ae8b
authored
Jun 12, 2018
by
COULAUD Olivier
Browse files
Remove some errors+warning with gcc 8
parent
98cc61e5
Changes
8
Hide whitespace changes
Inline
Side-by-side
Contribs/json.hpp
View file @
8067ae8b
...
...
@@ -1913,8 +1913,8 @@ class basic_json
@since version 1.0.0
*/
basic_json
(
const
value_t
value_type
)
:
m_type
(
value_type
),
m_value
(
value_type
)
basic_json
(
const
value_t
value_type
1
)
:
m_type
(
value_type
1
),
m_value
(
value_type
1
)
{
assert_invariant
();
}
...
...
README.md
View file @
8067ae8b
...
...
@@ -28,15 +28,14 @@ The following are optional:
-
Custom BLAS, FFT implementations.
-
[
StarPU
](
http://starpu.gforge.inria.fr/
)
for the relevant FMM implementations.
### To get and Build ScalFMM
To obtain ScalFMM (develop branch) and its git submodules do
### Get and Build ScalFMM
To use last development states of ScalFMM, please clone the develop
branch. Note that ScalFMM contains a git submodule
`morse_cmake`
.
To get sources please use these commands:
```
bash
git clone
--recursive
git@gitlab.inria.fr:solverstack/ScalFMM.git
-b
develop
```
or
```
bash
git clone git@gitlab.inria.fr:solverstack/ScalFMM.git
cd
ScalFMM
...
...
@@ -55,9 +54,9 @@ The build may be configured after the first CMake invocation using, for instance
```
bash
# Still in the Build folder
ccmake
.
ccmake .
./
# Or
cmake-gui .
cmake-gui .
./
```
The binaries are then compiled calling
`make`
. They can be found in
`scalfmm/Build/Tests/{Release,Debug}/...`
...
...
Src/Containers/FBufferReader.hpp
View file @
8067ae8b
...
...
@@ -3,6 +3,7 @@
#define FBUFFERREADER_HPP
#include <memory>
#include <algorithm>
#include "FAbstractBuffer.hpp"
#include "FBufferWriter.hpp"
#include "Utils/FAssert.hpp"
...
...
@@ -213,6 +214,7 @@ public :
template
<
class
T
>
void
fillArray
(
T
*
const
inArray
,
const
FSize
count
){
FAssertLF
(
currentIndex
+
FSize
(
sizeof
(
T
))
*
count
<=
arrayCapacity
);
// std::copy(&(array[currentIndex]),&(array[currentIndex])+count, inArray);
memcpy
(
inArray
,
&
array
[
currentIndex
],
sizeof
(
T
)
*
count
);
currentIndex
+=
sizeof
(
T
)
*
count
;
}
...
...
Src/Core/FFmmAlgorithmThreadProc.hpp
View file @
8067ae8b
...
...
@@ -4,36 +4,39 @@
#define SCALFMM_DISTRIBUTED_ALGORITHM
#include <omp.h>
#include <algorithm>
#include <vector>
#include <memory>
//#include <sys/time.h>
//
#ifdef _OPENMP
#include <omp.h>
#endif
//
#include "Utils/FGlobal.hpp"
#include "Utils/FAssert.hpp"
#include "Utils/FLog.hpp"
#include "Utils/FTic.hpp"
#include "Utils/FAlgorithmTimers.hpp"
#include "Utils/FGlobal.hpp"
#include "../Containers/FBoolArray.hpp"
#include "../Containers/FOctree.hpp"
#include "../Containers/FLightOctree.hpp"
#include "Utils/FEnv.hpp"
#include "Utils/FMpi.hpp"
#include "
../
Containers/F
BufferWrite
r.hpp"
#include "
../
Containers/FB
ufferReader
.hpp"
#include "
../
Containers/F
Vector
.hpp"
#include "Containers/F
Vecto
r.hpp"
#include "Containers/FB
oolArray
.hpp"
#include "Containers/FOctree.hpp"
#include "Containers/F
LightOctree
.hpp"
#include "
Utils/FMpi
.hpp"
#include
<sys/time.h>
#include "
Containers/FBufferWriter
.hpp"
#include
"Containers/FBufferReader.hpp"
#include "FCoreCommon.hpp"
#include "FP2PExclusion.hpp"
#include
<memory>
#include <vector>
#include
"Utils/FAlgorithmTimers.hpp"
/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
...
...
@@ -66,21 +69,21 @@ private:
OctreeClass
*
const
tree
;
///< The octree to work on
KernelClass
**
kernels
;
///< The kernels
const
FMpi
::
FComm
comm
;
///<
MPI comm
FMpi
::
FComm
fcomCompute
;
const
int
OctreeHeight
;
///<
Tree height
/// Used to store pointers to cells/leafs to work with
typename
OctreeClass
::
Iterator
*
iterArray
;
/// Used to store pointers to cells/leafs to send/rcv
typename
OctreeClass
::
Iterator
*
iterArrayComm
;
typename
OctreeClass
::
Iterator
*
iterArray
;
///< Used to store pointers to cells/leafs to work with
typename
OctreeClass
::
Iterator
*
iterArrayComm
;
///< Used to store pointers to cells/leafs to send/rcv
const
FMpi
::
FComm
comm
;
///< MPI communicator
FMpi
::
FComm
fcomCompute
;
int
numberOfLeafs
;
///< To store the size at the previous level
const
int
MaxThreads
;
///< Max number of thread allowed by openmp
const
int
nbProcessOrig
;
///< Process count
const
int
idProcessOrig
;
///< Current process id
int
nbProcess
;
///< Process count
int
idProcess
;
///< Current process id
const
int
OctreeHeight
;
///< Tree height
int
nbProcess
;
///< Process count
int
idProcess
;
///< Current process id
const
int
nbProcessOrig
;
///< Process count
const
int
idProcessOrig
;
///< Current process id
const
int
userChunkSize
;
const
int
leafLevelSeparationCriteria
;
...
...
@@ -106,8 +109,6 @@ private:
const
Interval
&
getWorkingInterval
(
int
level
,
int
proc
)
const
{
return
workingIntervalsPerLevel
[
OctreeHeight
*
proc
+
level
];
}
/// Does \a procIdx have work at given \a idxLevel
/** i.e. does it hold cells and is responsible of them ? */
bool
procHasWorkAtLevel
(
const
int
idxLevel
,
const
int
idxProc
)
const
{
...
...
@@ -125,21 +126,23 @@ private:
}
public:
/// Get an interval from a process id and tree level
// Interval& getWorkingInterval( int level, int proc){
// return workingIntervalsPerLevel[OctreeHeight * proc + level];
// }
// /// Get an interval from a process id and tree level
// const Interval& getWorkingInterval( int level, int proc) const {
// return workingIntervalsPerLevel[OctreeHeight * proc + level];
// }
/// Get current process interval at given \a level
///
/// \brief getWorkingInterval
/// \param level level in th tree
/// \return the interval from current process at tree level
///
Interval
&
getWorkingInterval
(
int
level
){
return
getWorkingInterval
(
level
,
idProcess
);
}
/// Build and dill vector of the MortonIndex Distribution at Leaf level
/// p = mpi process id then
/// [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p+1] is the morton index shared by process p
/// Get the Morton index Distribution at the leaf level
///
/// Fill the vector mortonDistribution
///
/// p = mpi process id then
/// Processor p owns indexes between [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p]+1]
///
/// parameter[out] mortonLeafDistribution
///
void
getMortonLeafDistribution
(
std
::
vector
<
MortonIndex
>
&
mortonLeafDistribution
)
final
{
mortonLeafDistribution
.
resize
(
2
*
nbProcess
)
;
auto
level
=
OctreeHeight
-
1
;
...
...
@@ -148,14 +151,48 @@ public:
mortonLeafDistribution
[
2
*
p
]
=
inter
.
leftIndex
;
mortonLeafDistribution
[
2
*
p
+
1
]
=
inter
.
rightIndex
;
}
}
// /// Build and dill vector of the MortonIndex Distribution at Leaf level
// /// p = mpi process id then
// /// [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p+1] is the morton index shared by process p
// void getMortonLeafDistribution(std::vector<MortonIndex> & mortonLeafDistribution) final {
// mortonLeafDistribution.resize(2*nbProcess) ;
// auto level = OctreeHeight - 1;
// for (int p=0 ; p< nbProcess ; ++p ){
// auto inter = this->getWorkingInterval(level, p );
// mortonLeafDistribution[2*p] = inter.leftIndex;
// mortonLeafDistribution[2*p+1] = inter.rightIndex;
// }
// }
///
/// \brief setKernel
/// \param inKernels a pointer on the computational kernel used in the algorithm
///
/// @todo move it in private section
void
setKernel
(
KernelClass
*
const
inKernels
){
this
->
kernels
=
new
KernelClass
*
[
MaxThreads
]{};
#pragma omp parallel num_threads(MaxThreads)
{
#pragma omp critical (InitFFmmAlgorithmThreadProcPeriodic)
{
this
->
kernels
[
omp_get_thread_num
()]
=
new
KernelClass
(
*
inKernels
);
}
}
}
///
/// \brief getPtrOnMortonIndexAtLeaf
/// \return
///
const
MortonIndex
*
getPtrOnMortonIndexAtLeaf
()
{
return
&
workingIntervalsPerLevel
[
0
].
leftIndex
;
}
/// Does the current process has some work at this level ?
bool
hasWorkAtLevel
(
int
level
){
///
/// \brief hasWorkAtLevel - Does the current process have some work at this level ?
/// \param level
/// \return true if the current process have some work at this level
bool
hasWorkAtLevel
(
int
level
){
return
idProcess
==
0
||
(
getWorkingInterval
(
level
,
idProcess
-
1
).
rightIndex
)
<
(
getWorkingInterval
(
level
,
idProcess
).
rightIndex
);
}
...
...
@@ -171,17 +208,17 @@ public:
const
int
inLeafLevelSeperationCriteria
=
1
)
:
tree
(
inTree
),
kernels
(
nullptr
),
comm
(
inComm
),
fcomCompute
(
inComm
),
OctreeHeight
(
tree
->
getHeight
()),
iterArray
(
nullptr
),
iterArrayComm
(
nullptr
),
comm
(
inComm
),
fcomCompute
(
inComm
),
numberOfLeafs
(
0
),
MaxThreads
(
FEnv
::
GetValue
(
"SCALFMM_ALGO_NUM_THREADS"
,
omp_get_max_threads
())),
nbProcessOrig
(
inComm
.
processCount
()),
idProcessOrig
(
inComm
.
processId
()),
nbProcess
(
0
),
idProcess
(
0
),
OctreeHeight
(
tree
->
getHeight
()),
nbProcessOrig
(
inComm
.
processCount
()),
idProcessOrig
(
inComm
.
processId
()),
userChunkSize
(
inUserChunkSize
),
leafLevelSeparationCriteria
(
inLeafLevelSeperationCriteria
),
intervals
(
new
Interval
[
inComm
.
processCount
()]),
...
...
@@ -189,6 +226,7 @@ public:
FAssertLF
(
tree
,
"tree cannot be null"
);
FAssertLF
(
leafLevelSeparationCriteria
<
3
,
"Separation criteria should be < 3"
);
// this->setKernel(inKernels) ;
this
->
kernels
=
new
KernelClass
*
[
MaxThreads
];
#pragma omp parallel num_threads(MaxThreads)
{
...
...
@@ -1703,7 +1741,7 @@ protected:
}
}
// Wait the com
e
to finish (and the previous computation also)
// Wait the com
munications
to finish (and the previous computation also)
#pragma omp barrier
...
...
Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
View file @
8067ae8b
...
...
@@ -8,14 +8,19 @@
#include <array>
#include <vector>
#include <memory>
//
#ifdef _OPENMP
#include <omp.h>
#endif
//
#include "Utils/FGlobal.hpp"
#include "Utils/FAssert.hpp"
#include "Utils/FLog.hpp"
#include "Utils/FTic.hpp"
#include "Utils/FGlobal.hpp"
#include "Utils/FMemUtils.hpp"
#include "Utils/FEnv.hpp"
#include "Utils/FMpi.hpp"
#include "Containers/FVector.hpp"
#include "Containers/FBoolArray.hpp"
...
...
@@ -25,13 +30,6 @@
#include "Containers/FBufferWriter.hpp"
#include "Containers/FBufferReader.hpp"
#include "Utils/FEnv.hpp"
#include "Utils/FMpi.hpp"
#ifdef _OPENMP
#include <omp.h>
#endif
#include "FCoreCommon.hpp"
#include "FP2PExclusion.hpp"
...
...
@@ -61,9 +59,9 @@
template
<
class
FReal
,
class
OctreeClass
,
class
CellClass
,
class
ContainerClass
,
class
KernelClass
,
class
LeafClass
,
class
P2PExclusionClass
=
FP2PMiddleExclusion
>
class
FFmmAlgorithmThreadProcPeriodic
:
public
FAbstractAlgorithm
,
public
FAlgorithmTimers
{
using
multipole_t
=
typename
CellClass
::
multipole_t
;
using
multipole_t
=
typename
CellClass
::
multipole_t
;
using
local_expansion_t
=
typename
CellClass
::
local_expansion_t
;
using
symbolic_data_t
=
CellClass
;
using
symbolic_data_t
=
CellClass
;
OctreeClass
*
const
tree
;
///< The octree to work on
...
...
@@ -97,33 +95,10 @@ class FFmmAlgorithmThreadProcPeriodic : public FAbstractAlgorithm, public FAlgor
/// All processes intervals
Interval
*
const
workingIntervalsPerLevel
;
public:
/// Get the Morton index Distribution at the leaf level
///
/// Fill the vector mortonDistribution
///
/// p = mpi process id then
/// Processor p owns indexes between [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p]+1]
///
/// parameter[out] mortonLeafDistribution
///
void
getMortonLeafDistribution
(
std
::
vector
<
MortonIndex
>
&
mortonLeafDistribution
)
final
{
mortonLeafDistribution
.
resize
(
2
*
nbProcess
)
;
auto
level
=
OctreeHeight
-
1
;
for
(
int
p
=
0
;
p
<
nbProcess
;
++
p
){
auto
inter
=
this
->
getWorkingInterval
(
level
,
p
);
mortonLeafDistribution
[
2
*
p
]
=
inter
.
leftIndex
;
mortonLeafDistribution
[
2
*
p
+
1
]
=
inter
.
rightIndex
;
}
}
private:
/// Get an interval from a process id and tree level
Interval
&
getWorkingInterval
(
int
level
,
int
proc
){
return
workingIntervalsPerLevel
[
OctreeHeight
*
proc
+
level
];
}
/// Get an interval from a process id and tree level
const
Interval
&
getWorkingInterval
(
int
level
,
int
proc
)
const
{
return
workingIntervalsPerLevel
[
OctreeHeight
*
proc
+
level
];
...
...
@@ -145,9 +120,41 @@ private:
}
public:
///
/// \brief getWorkingInterval
/// \param level level in th tree
/// \return the interval from current process at tree level
///
Interval
&
getWorkingInterval
(
int
level
){
return
getWorkingInterval
(
level
,
idProcess
);
}
/// Get the Morton index Distribution at the leaf level
///
/// Fill the vector mortonDistribution
///
/// p = mpi process id then
/// Processor p owns indexes between [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p]+1]
///
/// parameter[out] mortonLeafDistribution
///
void
getMortonLeafDistribution
(
std
::
vector
<
MortonIndex
>
&
mortonLeafDistribution
)
final
{
mortonLeafDistribution
.
resize
(
2
*
nbProcess
)
;
auto
level
=
OctreeHeight
-
1
;
for
(
int
p
=
0
;
p
<
nbProcess
;
++
p
){
auto
inter
=
this
->
getWorkingInterval
(
level
,
p
);
mortonLeafDistribution
[
2
*
p
]
=
inter
.
leftIndex
;
mortonLeafDistribution
[
2
*
p
+
1
]
=
inter
.
rightIndex
;
}
}
///
/// \brief setKernel
/// \param inKernels a pointer on the computational kernel used in the algorithm
///
/// @todo move it in private section --> warning we need to extend the box
///
void
setKernel
(
KernelClass
*
const
inKernels
){
this
->
kernels
=
new
KernelClass
*
[
MaxThreads
];
this
->
kernels
=
new
KernelClass
*
[
MaxThreads
]
{}
;
#pragma omp parallel num_threads(MaxThreads)
{
#pragma omp critical (InitFFmmAlgorithmThreadProcPeriodic)
...
...
@@ -156,20 +163,18 @@ public:
}
}
}
// /// Build and dill vector of the MortonIndex Distribution at Leaf level
// /// p = mpi process id then
// /// [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p+1] is the morton index shared by process p
// virtual void getAndBuildMortonIndexAtLeaf(std::vector<MortonIndex> & mortonLeafDistribution) {
// mortonLeafDistribution.resize(2*nbProcess) ;
// } ;
Interval
&
getWorkingInterval
(
const
int
level
){
return
getWorkingInterval
(
level
,
idProcess
);
///
/// \brief getPtrOnMortonIndexAtLeaf
/// \return
///
const
MortonIndex
*
getPtrOnMortonIndexAtLeaf
()
{
return
&
workingIntervalsPerLevel
[
0
].
leftIndex
;
}
/// Does the current process have some work at this level ?
///
/// \brief hasWorkAtLevel - Does the current process have some work at this level ?
/// \param level
/// \return true if the current process have some work at this level
///
bool
hasWorkAtLevel
(
int
level
){
return
idProcess
==
0
||
(
getWorkingInterval
(
level
,
idProcess
-
1
).
rightIndex
)
<
(
getWorkingInterval
(
level
,
idProcess
).
rightIndex
);
}
...
...
@@ -222,120 +227,6 @@ public:
delete
[]
workingIntervalsPerLevel
;
}
long
long
int
theoricalRepetition
()
const
{
if
(
nbLevelsAboveRoot
==
-
1
){
// we know it is 3 (-1;+1)
return
3
;
}
// Else we find the repetition in one dir and double it
return
6
*
(
1
<<
(
nbLevelsAboveRoot
));
}
//
//
//
void
repetitionsIntervals
(
FTreeCoordinate
*
const
min
,
FTreeCoordinate
*
const
max
)
const
{
if
(
nbLevelsAboveRoot
==
-
1
){
// We know it is (-1;1)
min
->
setPosition
(
-
1
,
-
1
,
-
1
);
max
->
setPosition
(
1
,
1
,
1
);
}
else
{
const
int
halfRepeated
=
int
(
theoricalRepetition
()
/
2
);
min
->
setPosition
(
-
halfRepeated
,
-
halfRepeated
,
-
halfRepeated
);
// if we repeat the box 8 times, we go from [-4 to 3]
max
->
setPosition
(
halfRepeated
-
1
,
halfRepeated
-
1
,
halfRepeated
-
1
);
}
}
FReal
extendedBoxWidth
()
const
{
if
(
nbLevelsAboveRoot
==
-
1
){
return
tree
->
getBoxWidth
()
*
2
;
}
else
{
return
tree
->
getBoxWidth
()
*
FReal
(
4
<<
(
nbLevelsAboveRoot
));
}
}
FReal
extendedBoxWidthBoundary
()
const
{
if
(
nbLevelsAboveRoot
==
-
1
){
return
tree
->
getBoxWidth
()
*
4
;
}
else
{
return
tree
->
getBoxWidth
()
*
FReal
(
8
<<
(
nbLevelsAboveRoot
));
}
}
/** This function has to be used to init the kernel with correct args
* It returns the box center seen from a kernel point of view from the periodicity the user ask for
* this is computed using the originalBoxWidth and originalBoxCenter given in parameter
*
* @param originalBoxCenter the real system center
* @param originalBoxWidth the real system size
*
* @return the center the kernel should use
*/
FPoint
<
FReal
>
extendedBoxCenter
()
const
{
if
(
nbLevelsAboveRoot
==
-
1
){
const
FReal
originalBoxWidth
=
tree
->
getBoxWidth
();
const
FPoint
<
FReal
>
originalBoxCenter
=
tree
->
getBoxCenter
();
const
FReal
originalBoxWidthDiv2
=
originalBoxWidth
/
2.0
;
return
FPoint
<
FReal
>
(
originalBoxCenter
.
getX
()
+
originalBoxWidthDiv2
,
originalBoxCenter
.
getY
()
+
originalBoxWidthDiv2
,
originalBoxCenter
.
getZ
()
+
originalBoxWidthDiv2
);
}
else
{
const
FReal
originalBoxWidth
=
tree
->
getBoxWidth
();
const
FReal
originalBoxWidthDiv2
=
originalBoxWidth
/
2.0
;
const
FPoint
<
FReal
>
originalBoxCenter
=
tree
->
getBoxCenter
();
const
FReal
offset
=
extendedBoxWidth
()
/
FReal
(
2.0
);
return
FPoint
<
FReal
>
(
originalBoxCenter
.
getX
()
-
originalBoxWidthDiv2
+
offset
,
originalBoxCenter
.
getY
()
-
originalBoxWidthDiv2
+
offset
,
originalBoxCenter
.
getZ
()
-
originalBoxWidthDiv2
+
offset
);
}
}
FPoint
<
FReal
>
extendedBoxCenterBoundary
()
const
{
if
(
nbLevelsAboveRoot
==
-
1
){
const
FReal
originalBoxWidth
=
tree
->
getBoxWidth
();
const
FPoint
<
FReal
>
originalBoxCenter
=
tree
->
getBoxCenter
();
const
FReal
originalBoxWidthDiv2
=
originalBoxWidth
/
2.0
;
return
FPoint
<
FReal
>
(
originalBoxCenter
.
getX
()
+
originalBoxWidthDiv2
,
originalBoxCenter
.
getY
()
+
originalBoxWidthDiv2
,
originalBoxCenter
.
getZ
()
+
originalBoxWidthDiv2
);
}
else
{
const
FReal
originalBoxWidth
=
tree
->
getBoxWidth
();
const
FReal
originalBoxWidthDiv2
=
originalBoxWidth
/
2.0
;
const
FPoint
<
FReal
>
originalBoxCenter
=
tree
->
getBoxCenter
();
return
FPoint
<
FReal
>
(
originalBoxCenter
.
getX
()
+
originalBoxWidthDiv2
,
originalBoxCenter
.
getY
()
+
originalBoxWidthDiv2
,
originalBoxCenter
.
getZ
()
+
originalBoxWidthDiv2
);
}
}
/** This function has to be used to init the kernel with correct args
* it returns the tree height seen from a kernel point of view from the periodicity the user ask for
* this is computed using the originalTreeHeight given in parameter
*
* @param originalTreeHeight the real tree heigh
*
* @return the height the kernel should use
*/
int
extendedTreeHeight
()
const
{
// The real height
return
OctreeHeight
+
offsetRealTree
;
}
int
extendedTreeHeightBoundary
()
const
{
// The real height
return
OctreeHeight
+
offsetRealTree
+
1
;
}
protected:
/**
* To execute the fmm algorithm
...
...
@@ -2142,6 +2033,120 @@ protected:
}
public:
long
long
int
theoricalRepetition
()
const
{
if
(
nbLevelsAboveRoot
==
-
1
){
// we know it is 3 (-1;+1)
return
3
;
}
// Else we find the repetition in one dir and double it
return
6
*
(
1
<<
(
nbLevelsAboveRoot
));
}
//
//
//
void
repetitionsIntervals
(
FTreeCoordinate
*
const
min
,
FTreeCoordinate
*
const
max
)
const
{
if
(
nbLevelsAboveRoot
==
-
1
){
// We know it is (-1;1)
min
->
setPosition
(
-
1
,
-
1
,
-
1
);
max
->
setPosition
(
1
,
1
,
1
);
}
else
{
const
int
halfRepeated
=
int
(
theoricalRepetition
()
/
2
);
min
->
setPosition
(
-
halfRepeated
,
-
halfRepeated
,
-
halfRepeated
);
// if we repeat the box 8 times, we go from [-4 to 3]
max
->
setPosition
(
halfRepeated
-
1
,
halfRepeated
-
1
,
halfRepeated
-
1
);
}
}
FReal
extendedBoxWidth
()
const
{
if
(
nbLevelsAboveRoot
==
-
1
){
return
tree
->
getBoxWidth
()
*
2
;
}
else
{
return
tree
->
getBoxWidth
()
*
FReal
(
4
<<
(
nbLevelsAboveRoot
));
}
}
FReal
extendedBoxWidthBoundary
()
const
{
if
(
nbLevelsAboveRoot
==
-
1
){
return
tree
->
getBoxWidth
()
*
4
;
}
else
{
return
tree
->
getBoxWidth
()
*
FReal
(
8
<<
(
nbLevelsAboveRoot
));
}
}
/** This function has to be used to init the kernel with correct args
* It returns the box center seen from a kernel point of view from the periodicity the user ask for
* this is computed using the originalBoxWidth and originalBoxCenter given in parameter
*
* @param originalBoxCenter the real system center
* @param originalBoxWidth the real system size
*
* @return the center the kernel should use
*/
FPoint
<
FReal
>
extendedBoxCenter
()
const
{