Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
ScalFMM
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
5
Issues
5
List
Boards
Labels
Service Desk
Milestones
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
solverstack
ScalFMM
Commits
8067ae8b
Commit
8067ae8b
authored
Jun 12, 2018
by
COULAUD Olivier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove some errors+warning with gcc 8
parent
98cc61e5
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
271 additions
and
224 deletions
+271
-224
Contribs/json.hpp
Contribs/json.hpp
+2
-2
README.md
README.md
+6
-7
Src/Containers/FBufferReader.hpp
Src/Containers/FBufferReader.hpp
+2
-0
Src/Core/FFmmAlgorithmThreadProc.hpp
Src/Core/FFmmAlgorithmThreadProc.hpp
+87
-49
Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
Src/Core/FFmmAlgorithmThreadProcPeriodic.hpp
+167
-162
Src/Utils/FAlgorithmTimers.cpp
Src/Utils/FAlgorithmTimers.cpp
+1
-0
Src/Utils/FAlgorithmTimers.hpp
Src/Utils/FAlgorithmTimers.hpp
+3
-2
Src/Utils/FComplex.hpp
Src/Utils/FComplex.hpp
+3
-2
No files found.
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_type1
)
{
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/FBufferWrite
r.hpp"
#include "
../Containers/FBufferReader
.hpp"
#include "
../Containers/FVector
.hpp"
#include "
Containers/FVecto
r.hpp"
#include "
Containers/FBoolArray
.hpp"
#include "Containers/FOctree.hpp"
#include "
Containers/FLightOctree
.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
{
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
){