Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
solverstack
ScalFMM
Commits
c503873f
Commit
c503873f
authored
Dec 11, 2014
by
PIACIBELLO Cyrille
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Both version (user defined kernel and interpolation kernel) provides same features
parent
e14f2180
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
317 additions
and
85 deletions
+317
-85
Addons/CKernelApi/Src/CScalfmmApi.h
Addons/CKernelApi/Src/CScalfmmApi.h
+52
-28
Addons/CKernelApi/Src/FInterEngine.hpp
Addons/CKernelApi/Src/FInterEngine.hpp
+6
-3
Addons/CKernelApi/Src/FScalFMMEngine.hpp
Addons/CKernelApi/Src/FScalFMMEngine.hpp
+8
-21
Addons/CKernelApi/Src/FScalfmmApiInit.cpp
Addons/CKernelApi/Src/FScalfmmApiInit.cpp
+4
-5
Addons/CKernelApi/Src/FUserKernelEngine.hpp
Addons/CKernelApi/Src/FUserKernelEngine.hpp
+204
-17
Addons/CKernelApi/Tests/testUseNewApi.c
Addons/CKernelApi/Tests/testUseNewApi.c
+7
-2
Addons/CKernelApi/Tests/testUserDefinedKernelApi.c
Addons/CKernelApi/Tests/testUserDefinedKernelApi.c
+36
-9
No files found.
Addons/CKernelApi/Src/CScalfmmApi.h
View file @
c503873f
...
...
@@ -101,9 +101,6 @@ typedef void* scalfmm_handle;
/**
* @brief This function initialize scalfmm datas.
* @param TreeHeight Height of the octree.
* @param BoxWidth Width of the entire simulation box.
* @param BoxCenter Coordinate of the center of the box (ie array)
* @param KernelType kernel to be used
* @return scalfmm_handle (ie void *). This handle will be given to
* every other scalfmm functions.
...
...
@@ -111,15 +108,58 @@ typedef void* scalfmm_handle;
* Every data will be stored in order to crete later through a builder
* what is needed for the simulation
*/
scalfmm_handle
scalfmm_init
(
int
TreeHeight
,
double
BoxWidth
,
double
*
BoxCenter
,
scalfmm_kernel_type
KernelType
);
scalfmm_handle
scalfmm_init
(
scalfmm_kernel_type
KernelType
);
/////////////////////////////////////////////////////////////////////
////////////////// Tree Part //////////////
/////////////////////////////////////////////////////////////////////
//In order to initate the tree for user defined cell and kernel, we
//define here the call_backs to deal with cells
/**
* @brief Function to init the cells (should be given by the user when
* calling Scalfmm_init_cell)
* @param level level of the cell.
* @param morton_index morton index of the cell to be allocated.
* @param tree_position int[3] position inside the tree (number of boxes in
* each direction)
* @param spatial_position double[3] center of the cell
*/
typedef
void
*
(
*
Callback_init_cell
)(
int
level
,
long
long
morton_index
,
int
*
tree_position
,
double
*
spatial_position
);
/**
* Function to destroy what have bee initialized by the user (should
* be give in Scalfmm_dealloc_handle)
*/
typedef
void
(
*
Callback_free_cell
)(
void
*
);
/**
* @brief Structure containing user's call_backs in order to
* initialize/free the cell's user data.
*/
typedef
struct
User_Scalfmm_Cell_Descriptor
{
Callback_free_cell
user_free_cell
;
Callback_init_cell
user_init_cell
;
}
Scalfmm_Cell_Descriptor
;
/**
* @brief This function build the tree. If scalfmm_init has been
* called with a user defined kernel, then user_cell_descriptor need
* to be provided
*
* @param TreeHeight Height of the octree.
* @param BoxWidth Width of the entire simulation box.
* @param BoxCenter Coordinate of the center of the box (ie array)
*/
void
scalfmm_build_tree
(
scalfmm_handle
handle
,
int
TreeHeight
,
double
BoxWidth
,
double
*
BoxCenter
,
Scalfmm_Cell_Descriptor
user_cell_descriptor
);
/**
* @brief This function insert an array of position into the octree
* @param Handle scalfmm_handle provided by scalfmm_init.
...
...
@@ -414,30 +454,14 @@ void scalfmm_user_kernel_config(scalfmm_handle Handle, Scalfmm_Kernel_Descriptor
//To fill gestion des cellules utilisateurs
/**
* @brief Function to init the cells (should be given by the user when
* calling Scalfmm_init_cell)
* @param level level of the cell.
* @param morton_index morton index of the cell to be allocated.
* @param tree_position int[3] position inside the tree (number of boxes in
* each direction)
* @param spatial_position double[3] center of the cell
*/
typedef
void
*
(
*
Callback_init_cell
)(
int
level
,
long
long
morton_index
,
int
*
tree_position
,
double
*
spatial_position
);
/**
* Function to destroy what have bee initialized by the user (should
* be give in Scalfmm_dealloc_handle)
*/
typedef
void
(
*
Callback_free_cell
)(
void
*
);
void
scalfmm_init_cell
(
scalfmm_handle
Handle
,
Callback_init_cell
user_cell_initializer
);
void
scalfmm_free_cell
(
scalfmm_handle
Handle
,
Callback_free_cell
user_cell_deallocator
);
/* void scalfmm_init_cell(scalfmm_handle Handle, Callback_init_cell user_cell_initializer); */
/* void scalfmm_free_cell(scalfmm_handle Handle, Callback_free_cell user_cell_deallocator); */
/* /\** */
/* *@param Struct defining how scalfmm will handle user's cell data. */
/* *\/ */
/* void scalfmm_user_cell_config(scalfmm_handle Handle, Scalfmm_Cell_Descriptor user_cell_descriptor); */
///////////////// Common kernel part : /////////////////
...
...
Addons/CKernelApi/Src/FInterEngine.hpp
View file @
c503873f
...
...
@@ -70,15 +70,18 @@ public:
* @param BoxCenter double[3] coordinate of the center of the
* simulation box
*/
FInterEngine
(
int
TreeHeight
,
double
BoxWidth
,
double
*
BoxCenter
,
scalfmm_kernel_type
KernelType
)
:
FInterEngine
(
scalfmm_kernel_type
KernelType
)
:
kernel
(
nullptr
),
matrix
(
nullptr
),
octree
(
nullptr
),
arranger
(
nullptr
){
kernelType
=
KernelType
;
}
void
build_tree
(
int
TreeHeight
,
double
BoxWidth
,
double
*
BoxCenter
,
User_Scalfmm_Cell_Descriptor
notUsedHere
){
octree
=
new
OctreeClass
(
TreeHeight
,
FMath
::
Min
(
3
,
TreeHeight
-
1
),
BoxWidth
,
FPoint
(
BoxCenter
));
this
->
matrix
=
new
MatrixKernelClass
();
this
->
kernel
=
new
InterKernel
(
TreeHeight
,
BoxWidth
,
FPoint
(
BoxCenter
),
matrix
);
kernelType
=
KernelType
;
arranger
=
nullptr
;
}
//TODO free kernel too
~
FInterEngine
(){
delete
matrix
;
...
...
Addons/CKernelApi/Src/FScalFMMEngine.hpp
View file @
c503873f
...
...
@@ -80,6 +80,10 @@ public:
//by specific Engine
//Function about the tree
virtual
void
build_tree
(
int
TreeHeight
,
double
BoxWidth
,
double
*
BoxCenter
,
Scalfmm_Cell_Descriptor
user_cell_descriptor
){
FAssertLF
(
0
,
"Nothing has been done yet, exiting"
);
}
virtual
void
tree_insert_particles
(
int
NbPositions
,
double
*
arrayX
,
double
*
arrayY
,
double
*
arrayZ
){
FAssertLF
(
0
,
"No tree instancied, exiting ...
\n
"
);
}
...
...
@@ -201,15 +205,7 @@ public:
FAssertLF
(
0
,
"No user kernel defined, exiting ...
\n
"
);
}
virtual
void
init_cell
(
Callback_init_cell
user_cell_initializer
){
FAssertLF
(
0
,
"No user kernel defined, exiting ...
\n
"
);
}
virtual
void
free_cell
(
Callback_free_cell
user_cell_initializer
){
FAssertLF
(
0
,
"No user kernel defined, exiting ...
\n
"
);
}
virtual
void
execute_fmm
(){
virtual
void
execute_fmm
(){
FAssertLF
(
0
,
"No kernel set, cannot execute anything, exiting ...
\n
"
);
}
...
...
@@ -234,7 +230,9 @@ struct ScalFmmCoreHandle {
extern
"C"
void
scalfmm_build_tree
(
scalfmm_handle
Handle
,
int
TreeHeight
,
double
BoxWidth
,
double
*
BoxCenter
,
Scalfmm_Cell_Descriptor
user_cell_descriptor
){
((
ScalFmmCoreHandle
*
)
Handle
)
->
engine
->
build_tree
(
TreeHeight
,
BoxWidth
,
BoxCenter
,
user_cell_descriptor
);
}
extern
"C"
void
scalfmm_tree_insert_particles
(
scalfmm_handle
Handle
,
int
NbPositions
,
double
*
arrayX
,
double
*
arrayY
,
double
*
arrayZ
){
((
ScalFmmCoreHandle
*
)
Handle
)
->
engine
->
tree_insert_particles
(
NbPositions
,
arrayX
,
arrayY
,
arrayZ
);
...
...
@@ -391,16 +389,5 @@ extern "C" void scalfmm_user_kernel_config(scalfmm_handle Handle, Scalfmm_Kernel
((
ScalFmmCoreHandle
*
)
Handle
)
->
engine
->
user_kernel_config
(
userKernel
,
userDatas
);
}
extern
"C"
void
scalfmm_init_cell
(
scalfmm_handle
Handle
,
Callback_init_cell
user_cell_initializer
){
((
ScalFmmCoreHandle
*
)
Handle
)
->
engine
->
init_cell
(
user_cell_initializer
);
}
extern
"C"
void
scalfmm_free_cell
(
scalfmm_handle
Handle
,
Callback_free_cell
user_cell_deallocator
){
((
ScalFmmCoreHandle
*
)
Handle
)
->
engine
->
free_cell
(
user_cell_deallocator
);
}
// extern "C" void scalfmm_intern_dealloc_handle(scalfmm_handle Handle,Callback_free_cell userDeallocator){
// ((ScalFmmCoreHandle * ) Handle)->engine->intern_dealloc_handle(userDeallocator);
// }
#endif
Addons/CKernelApi/Src/FScalfmmApiInit.cpp
View file @
c503873f
...
...
@@ -6,13 +6,12 @@ extern "C" {
#include "FInterEngine.hpp"
#include "FUserKernelEngine.hpp"
extern
"C"
scalfmm_handle
scalfmm_init
(
int
TreeHeight
,
double
BoxWidth
,
double
*
BoxCenter
,
scalfmm_kernel_type
KernelType
){
extern
"C"
scalfmm_handle
scalfmm_init
(
/*
int TreeHeight,double BoxWidth,double* BoxCenter,
*/
scalfmm_kernel_type
KernelType
){
ScalFmmCoreHandle
*
handle
=
new
ScalFmmCoreHandle
();
switch
(
KernelType
){
case
0
:
handle
->
engine
=
new
FUserKernelEngine
(
TreeHeight
,
BoxWidth
,
BoxCenter
,
KernelType
);
std
::
cout
<<
"User Kernel type unsupported yet"
<<
std
::
endl
;
handle
->
engine
=
new
FUserKernelEngine
(
/*TreeHeight, BoxWidth, BoxCenter, */
KernelType
);
break
;
case
1
:
...
...
@@ -23,7 +22,7 @@ extern "C" scalfmm_handle scalfmm_init(int TreeHeight,double BoxWidth,double* Bo
typedef
FInterpMatrixKernelR
MatrixKernelClass
;
typedef
FChebSymKernel
<
ChebCell
,
ContainerClass
,
MatrixKernelClass
,
7
>
ChebKernel
;
handle
->
engine
=
new
FInterEngine
<
ChebCell
,
ChebKernel
>
(
TreeHeight
,
BoxWidth
,
BoxCenter
,
KernelType
);
handle
->
engine
=
new
FInterEngine
<
ChebCell
,
ChebKernel
>
(
/*
TreeHeight,BoxWidth,BoxCenter,
*/
KernelType
);
break
;
case
2
:
//TODO typedefs
...
...
@@ -33,7 +32,7 @@ extern "C" scalfmm_handle scalfmm_init(int TreeHeight,double BoxWidth,double* Bo
typedef
FInterpMatrixKernelR
MatrixKernelClass
;
typedef
FUnifKernel
<
UnifCell
,
ContainerClass
,
MatrixKernelClass
,
7
>
UnifKernel
;
handle
->
engine
=
new
FInterEngine
<
UnifCell
,
UnifKernel
>
(
TreeHeight
,
BoxWidth
,
BoxCenter
,
KernelType
);
handle
->
engine
=
new
FInterEngine
<
UnifCell
,
UnifKernel
>
(
/*
TreeHeight,BoxWidth,BoxCenter,
*/
KernelType
);
break
;
default:
...
...
Addons/CKernelApi/Src/FUserKernelEngine.hpp
View file @
c503873f
...
...
@@ -31,12 +31,32 @@ class CoreCell : public FBasicCell {
// Mutable in order to work with the API
mutable
void
*
userData
;
//Static members to be initialised before octree creation
static
Scalfmm_Cell_Descriptor
user_cell_descriptor
;
public:
static
void
Init
(
Scalfmm_Cell_Descriptor
cell_descriptor
){
user_cell_descriptor
=
cell_descriptor
;
}
static
Callback_init_cell
GetInit
(){
return
user_cell_descriptor
.
user_init_cell
;
}
static
Callback_free_cell
GetFree
(){
return
user_cell_descriptor
.
user_free_cell
;
}
CoreCell
()
:
userData
(
nullptr
)
{
}
//We free the cells here
~
CoreCell
(){
if
(
userData
){
this
->
user_cell_descriptor
.
user_free_cell
(
userData
);
}
}
/**
* @brief setContainer store the ptr to the user data inside our
* struct
...
...
@@ -54,6 +74,10 @@ public:
}
};
/**
* Define here static member
*/
Scalfmm_Cell_Descriptor
CoreCell
::
user_cell_descriptor
;
/**
* This class simply call the function pointers from Scalfmm_Kernel_Descriptor.
...
...
@@ -142,8 +166,6 @@ public:
};
class
FUserKernelEngine
:
public
FScalFMMEngine
{
private:
...
...
@@ -165,15 +187,17 @@ private:
CoreKernelClass
*
kernel
;
ArrangerClass
*
arranger
;
public:
FUserKernelEngine
(
int
TreeHeight
,
double
BoxWidth
,
double
*
BoxCenter
,
scalfmm_kernel_type
KernelType
)
:
FUserKernelEngine
(
/*
int TreeHeight, double BoxWidth , double * BoxCenter,
*/
scalfmm_kernel_type
KernelType
)
:
octree
(
nullptr
),
kernel
(
nullptr
),
arranger
(
nullptr
){
octree
=
new
OctreeClass
(
TreeHeight
,
FMath
::
Min
(
3
,
TreeHeight
-
1
),
BoxWidth
,
FPoint
(
BoxCenter
));
//
octree = new OctreeClass(TreeHeight,FMath::Min(3,TreeHeight-1),BoxWidth,FPoint(BoxCenter));
kernelType
=
KernelType
;
//Kernel is not set now because the user must provide a
//Scalfmm_Kernel_descriptor
}
~
FUserKernelEngine
(){
delete
octree
;
...
...
@@ -191,12 +215,17 @@ public:
}
}
void
build_tree
(
int
TreeHeight
,
double
BoxWidth
,
double
*
BoxCenter
,
Scalfmm_Cell_Descriptor
user_cell_descriptor
){
CoreCell
::
Init
(
user_cell_descriptor
);
this
->
octree
=
new
OctreeClass
(
TreeHeight
,
FMath
::
Min
(
3
,
TreeHeight
-
1
),
BoxWidth
,
FPoint
(
BoxCenter
));
}
void
tree_insert_particles
(
int
NbPositions
,
double
*
arrayX
,
double
*
arrayY
,
double
*
arrayZ
){
for
(
int
idPart
=
0
;
idPart
<
NbPositions
;
++
idPart
){
octree
->
insert
(
FPoint
(
arrayX
[
idPart
],
arrayY
[
idPart
],
arrayZ
[
idPart
]),
idPart
);
}
nbPart
+=
NbPositions
;
this
->
init_cell
();
}
void
tree_insert_particles_xyz
(
int
NbPositions
,
double
*
XYZ
){
...
...
@@ -206,19 +235,176 @@ public:
nbPart
+=
NbPositions
;
}
/**
* To retrieve the positions, in order to move the parts
*/
void
get_positions_xyz
(
int
NbPositions
,
double
*
positionsToFill
){
octree
->
forEachLeaf
([
&
](
LeafClass
*
leaf
){
ContainerClass
*
sources
=
leaf
->
getSrc
();
const
FVector
<
int
>&
indexes
=
sources
->
getIndexes
();
int
nbPartThere
=
sources
->
getNbParticles
();
for
(
int
idxPart
=
0
;
idxPart
<
nbPartThere
;
++
idxPart
){
positionsToFill
[
indexes
[
idxPart
]
*
3
+
0
]
=
sources
->
getPositions
()[
0
][
idxPart
];
positionsToFill
[
indexes
[
idxPart
]
*
3
+
1
]
=
sources
->
getPositions
()[
1
][
idxPart
];
positionsToFill
[
indexes
[
idxPart
]
*
3
+
2
]
=
sources
->
getPositions
()[
2
][
idxPart
];
}
});
}
void
get_positions_xyz_npart
(
int
NbPositions
,
int
*
idxOfParticles
,
double
*
positionsToFill
){
octree
->
forEachLeaf
([
&
](
LeafClass
*
leaf
){
ContainerClass
*
sources
=
leaf
->
getSrc
();
const
FVector
<
int
>&
indexes
=
sources
->
getIndexes
();
int
nbPartThere
=
sources
->
getNbParticles
();
for
(
int
idxPart
=
0
;
idxPart
<
nbPartThere
;
++
idxPart
){
int
iterPart
=
0
;
bool
notFoundYet
=
true
;
while
(
iterPart
<
NbPositions
&&
notFoundYet
){
if
(
indexes
[
idxPart
]
==
idxOfParticles
[
iterPart
]){
positionsToFill
[
indexes
[
idxPart
]
*
3
+
0
]
=
sources
->
getPositions
()[
0
][
idxPart
];
positionsToFill
[
indexes
[
idxPart
]
*
3
+
1
]
=
sources
->
getPositions
()[
1
][
idxPart
];
positionsToFill
[
indexes
[
idxPart
]
*
3
+
2
]
=
sources
->
getPositions
()[
2
][
idxPart
];
notFoundYet
=
false
;
}
else
{
++
iterPart
;
}
}
}
});
}
void
get_positions
(
int
NbPositions
,
double
*
X
,
double
*
Y
,
double
*
Z
){
octree
->
forEachLeaf
([
&
](
LeafClass
*
leaf
){
ContainerClass
*
sources
=
leaf
->
getSrc
();
const
FVector
<
int
>&
indexes
=
sources
->
getIndexes
();
int
nbPartThere
=
sources
->
getNbParticles
();
for
(
int
idxPart
=
0
;
idxPart
<
nbPartThere
;
++
idxPart
){
X
[
indexes
[
idxPart
]]
=
sources
->
getPositions
()[
0
][
idxPart
];
Y
[
indexes
[
idxPart
]]
=
sources
->
getPositions
()[
1
][
idxPart
];
Z
[
indexes
[
idxPart
]]
=
sources
->
getPositions
()[
2
][
idxPart
];
}
});
}
void
get_positions_npart
(
int
NbPositions
,
int
*
idxOfParticles
,
double
*
X
,
double
*
Y
,
double
*
Z
){
octree
->
forEachLeaf
([
&
](
LeafClass
*
leaf
){
ContainerClass
*
sources
=
leaf
->
getSrc
();
const
FVector
<
int
>&
indexes
=
sources
->
getIndexes
();
int
nbPartThere
=
sources
->
getNbParticles
();
for
(
int
idxPart
=
0
;
idxPart
<
nbPartThere
;
++
idxPart
){
int
iterPart
=
0
;
bool
notFoundYet
=
true
;
while
(
iterPart
<
NbPositions
&&
notFoundYet
){
if
(
indexes
[
idxPart
]
==
idxOfParticles
[
iterPart
]){
X
[
indexes
[
idxPart
]]
=
sources
->
getPositions
()[
0
][
idxPart
];
Y
[
indexes
[
idxPart
]]
=
sources
->
getPositions
()[
1
][
idxPart
];
Z
[
indexes
[
idxPart
]]
=
sources
->
getPositions
()[
2
][
idxPart
];
notFoundYet
=
false
;
}
else
{
++
iterPart
;
}
}
}
});
}
//Arranger parts : following function provide a way to move parts
//inside the tree
void
add_to_positions_xyz
(
int
NbPositions
,
double
*
updatedXYZ
){
octree
->
forEachLeaf
([
&
](
LeafClass
*
leaf
){
ContainerClass
*
sources
=
leaf
->
getSrc
();
const
FVector
<
int
>&
indexes
=
sources
->
getIndexes
();
int
nbPartThere
=
sources
->
getNbParticles
();
for
(
int
idxPart
=
0
;
idxPart
<
nbPartThere
;
++
idxPart
){
sources
->
getWPositions
()[
0
][
idxPart
]
+=
updatedXYZ
[
indexes
[
idxPart
]
*
3
+
0
];
sources
->
getWPositions
()[
1
][
idxPart
]
+=
updatedXYZ
[
indexes
[
idxPart
]
*
3
+
1
];
sources
->
getWPositions
()[
2
][
idxPart
]
+=
updatedXYZ
[
indexes
[
idxPart
]
*
3
+
2
];
}
});
}
void
add_to_positions
(
int
NbPositions
,
double
*
X
,
double
*
Y
,
double
*
Z
){
octree
->
forEachLeaf
([
&
](
LeafClass
*
leaf
){
ContainerClass
*
sources
=
leaf
->
getSrc
();
const
FVector
<
int
>&
indexes
=
sources
->
getIndexes
();
int
nbPartThere
=
sources
->
getNbParticles
();
for
(
int
idxPart
=
0
;
idxPart
<
nbPartThere
;
++
idxPart
){
sources
->
getWPositions
()[
0
][
idxPart
]
+=
X
[
indexes
[
idxPart
]];
sources
->
getWPositions
()[
1
][
idxPart
]
+=
Y
[
indexes
[
idxPart
]];
sources
->
getWPositions
()[
2
][
idxPart
]
+=
Z
[
indexes
[
idxPart
]];
}
});
}
void
set_positions_xyz
(
int
NbPositions
,
double
*
updatedXYZ
){
octree
->
forEachLeaf
([
&
](
LeafClass
*
leaf
){
ContainerClass
*
sources
=
leaf
->
getSrc
();
const
FVector
<
int
>&
indexes
=
sources
->
getIndexes
();
int
nbPartThere
=
sources
->
getNbParticles
();
for
(
int
idxPart
=
0
;
idxPart
<
nbPartThere
;
++
idxPart
){
sources
->
getWPositions
()[
0
][
idxPart
]
=
updatedXYZ
[
indexes
[
idxPart
]
*
3
+
0
];
sources
->
getWPositions
()[
1
][
idxPart
]
=
updatedXYZ
[
indexes
[
idxPart
]
*
3
+
1
];
sources
->
getWPositions
()[
2
][
idxPart
]
=
updatedXYZ
[
indexes
[
idxPart
]
*
3
+
2
];
}
});
}
void
set_positions
(
int
NbPositions
,
double
*
X
,
double
*
Y
,
double
*
Z
){
octree
->
forEachLeaf
([
&
](
LeafClass
*
leaf
){
ContainerClass
*
sources
=
leaf
->
getSrc
();
const
FVector
<
int
>&
indexes
=
sources
->
getIndexes
();
int
nbPartThere
=
sources
->
getNbParticles
();
for
(
int
idxPart
=
0
;
idxPart
<
nbPartThere
;
++
idxPart
){
sources
->
getWPositions
()[
0
][
idxPart
]
=
X
[
indexes
[
idxPart
]];
sources
->
getWPositions
()[
1
][
idxPart
]
=
Y
[
indexes
[
idxPart
]];
sources
->
getWPositions
()[
2
][
idxPart
]
=
Z
[
indexes
[
idxPart
]];
}
});
}
void
update_tree
(){
if
(
arranger
){
arranger
->
rearrange
();
//then, we need to re-allocate cells user data for the
//cells created during the process and free user datas for
//the cells removed during the process
init_cell
();
}
else
{
if
(
Algorithm
==
2
){
//case in wich the periodic algorithm is used
arranger
=
new
ArrangerClassPeriodic
(
octree
);
arranger
->
rearrange
();
}
else
{
arranger
=
new
ArrangerClass
(
octree
);
arranger
->
rearrange
();
init_cell
();
}
}
}
/*
* Call the user allocator on userDatas member field of each cell
*/
void
init_cell
(
Callback_init_cell
user_cell_initializer
){
if
(
user_cell_initializer
){
double
boxwidth
=
octree
->
getBoxWidth
();
FPoint
BoxCenter
=
octree
->
getBoxCenter
();
double
boxCorner
[
3
];
boxCorner
[
0
]
=
BoxCenter
.
getX
()
-
boxwidth
/
2.0
;
boxCorner
[
1
]
=
BoxCenter
.
getY
()
-
boxwidth
/
2.0
;
boxCorner
[
2
]
=
BoxCenter
.
getZ
()
-
boxwidth
/
2.0
;
//apply user function on each cell
octree
->
forEachCellWithLevel
([
&
](
CoreCell
*
currCell
,
const
int
currLevel
){
void
init_cell
(){
double
boxwidth
=
octree
->
getBoxWidth
();
FPoint
BoxCenter
=
octree
->
getBoxCenter
();
double
boxCorner
[
3
];
boxCorner
[
0
]
=
BoxCenter
.
getX
()
-
boxwidth
/
2.0
;
boxCorner
[
1
]
=
BoxCenter
.
getY
()
-
boxwidth
/
2.0
;
boxCorner
[
2
]
=
BoxCenter
.
getZ
()
-
boxwidth
/
2.0
;
//apply user function on each cell
octree
->
forEachCellWithLevel
([
&
](
CoreCell
*
currCell
,
const
int
currLevel
){
if
(
!
(
currCell
->
getContainer
())){
FTreeCoordinate
currCoord
=
currCell
->
getCoordinate
();
int
arrayCoord
[
3
]
=
{
currCoord
.
getX
(),
currCoord
.
getY
(),
currCoord
.
getZ
()};
MortonIndex
currMorton
=
currCoord
.
getMortonIndex
(
currLevel
);
...
...
@@ -226,11 +412,12 @@ public:
position
[
0
]
=
boxCorner
[
0
]
+
currCoord
.
getX
()
*
boxwidth
/
double
(
1
<<
currLevel
);
position
[
1
]
=
boxCorner
[
1
]
+
currCoord
.
getY
()
*
boxwidth
/
double
(
1
<<
currLevel
);
position
[
2
]
=
boxCorner
[
2
]
+
currCoord
.
getZ
()
*
boxwidth
/
double
(
1
<<
currLevel
);
currCell
->
setContainer
(
user_cell_initializer
(
currLevel
,
currMorton
,
arrayCoord
,
position
));
}
);
}
currCell
->
setContainer
(
CoreCell
::
GetInit
()
(
currLevel
,
currMorton
,
arrayCoord
,
position
));
}
});
}
void
free_cell
(
Callback_free_cell
user_cell_deallocator
){
octree
->
forEachCell
([
&
](
CoreCell
*
currCell
){
if
(
currCell
->
getContainer
()){
...
...
Addons/CKernelApi/Tests/testUseNewApi.c
View file @
c503873f
...
...
@@ -28,7 +28,12 @@ int main(int argc, char ** av){
double
boxCenter
[
3
]
=
{
0
.
0
,
0
.
0
,
0
.
0
};
//Init our lib
scalfmm_handle
handle
=
scalfmm_init
(
TreeHeight
,
boxWidth
,
boxCenter
,
myChoice
);
//The tree is built
scalfmm_handle
handle
=
scalfmm_init
(
/* TreeHeight,boxWidth,boxCenter, */
myChoice
);
//The tree is built
struct
User_Scalfmm_Cell_Descriptor
user_descr
;
user_descr
.
user_init_cell
=
NULL
;
user_descr
.
user_free_cell
=
NULL
;
scalfmm_build_tree
(
handle
,
TreeHeight
,
boxWidth
,
boxCenter
,
user_descr
);
scalfmm_algorithm_config
(
handle
,
periodic
);
//Creation of an array of particles
int
nb_of_parts
=
2
;
...
...
@@ -56,7 +61,7 @@ int main(int argc, char ** av){
//Computation Part
int
nb_iteration
=
10
;
//atoi(av[1]);
int
nb_iteration
=
3
;
//atoi(av[1]);
int
curr_iteration
=
0
;
//Array to store the output
...
...
Addons/CKernelApi/Tests/testUserDefinedKernelApi.c
View file @
c503873f
...
...
@@ -25,7 +25,7 @@
#include "../Src/CScalfmmApi.h"
// Uncomment the next line to avoid the print in the kernel and verbosity
//
#define NOT_TOO_MUCH_VERBOSE
#define NOT_TOO_MUCH_VERBOSE
#ifdef NOT_TOO_MUCH_VERBOSE
#define VerbosePrint(X...)
#else
...
...
@@ -233,13 +233,19 @@ int main(int argc, char ** argv){
}
// Init the handle
scalfmm_handle
handle
=
scalfmm_init
(
treeHeight
,
boxWidth
,
boxCenter
,
user_defined_kernel
);
scalfmm_handle
handle
=
scalfmm_init
(
user_defined_kernel
);
//Build our own call backs
struct
User_Scalfmm_Cell_Descriptor
cellDescriptor
;
cellDescriptor
.
user_init_cell
=
my_Callback_init_cell
;
cellDescriptor
.
user_free_cell
=
my_Callback_free_cell
;
// Init tree and cell
printf
(
"Building the tree and Initizalizing the cells:
\n
"
);
scalfmm_build_tree
(
handle
,
treeHeight
,
boxWidth
,
boxCenter
,
cellDescriptor
);
// Insert particles
printf
(
"Inserting particles...
\n
"
);
scalfmm_tree_insert_particles_xyz
(
handle
,
nbParticles
,
particleXYZ
);
// Init cell
printf
(
"Initizalizing the cells:
\n
"
);
scalfmm_init_cell
(
handle
,
my_Callback_init_cell
);
// Init our callback struct
struct
User_Scalfmm_Kernel_Descriptor
kernel
;
...
...
@@ -258,8 +264,31 @@ int main(int argc, char ** argv){
//Set my datas before calling fmm (this will set as well the kernel)
scalfmm_user_kernel_config
(
handle
,
kernel
,
&
my_data
);
// Execute the FMM
scalfmm_execute_fmm
(
handle
/*, kernel, &my_data*/
);
//loop to multiples runs of the fmm
int
nb_ite
=
1
;
int
curr_ite
=
0
;
//array to store positions
double
new_positions
[
nbParticles
*
3
];
memset
(
new_positions
,
0
,
3
*
nbParticles
*
sizeof
(
double
));
while
(
curr_ite
<
nb_ite
){
// Execute the FMM
scalfmm_execute_fmm
(
handle
/*, kernel, &my_data*/
);
scalfmm_get_positions_xyz
(
handle
,
nbParticles
,
new_positions
);
//Computation on those positions
//Here it's a random
int
id
;
for
(
id
=
0
;
id
<
nbParticles
;
++
id
){
new_positions
[
id
*
3
]
=
(
random
()
/
(
double
)(
RAND_MAX
))
*
boxWidth
-
boxWidth
/
2
+
boxCenter
[
0
];
new_positions
[
id
*
3
+
1
]
=
(
random
()
/
(
double
)(
RAND_MAX
))
*
boxWidth
-
boxWidth
/
2
+
boxCenter
[
1
];
new_positions
[
id
*
3
+
2
]
=
(
random
()
/
(
double
)(
RAND_MAX
))
*
boxWidth
-
boxWidth
/
2
+
boxCenter
[
2
];
}
printf
(
"Positions changed
\n
"
);
scalfmm_set_positions_xyz
(
handle
,
nbParticles
,
new_positions
);
scalfmm_update_tree
(
handle
);
curr_ite
++
;
}