Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
SWIFT
SWIFTsim
Commits
4e72575f
Commit
4e72575f
authored
May 09, 2017
by
Matthieu Schaller
Browse files
Added a test of the FFT task#
parent
106624ab
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/runner.h
View file @
4e72575f
...
...
@@ -70,6 +70,7 @@ void runner_do_end_force(struct runner *r, struct cell *c, int timer);
void
runner_do_init
(
struct
runner
*
r
,
struct
cell
*
c
,
int
timer
);
void
runner_do_cooling
(
struct
runner
*
r
,
struct
cell
*
c
,
int
timer
);
void
runner_do_grav_external
(
struct
runner
*
r
,
struct
cell
*
c
,
int
timer
);
void
runner_do_grav_fft
(
struct
runner
*
r
,
int
timer
);
void
*
runner_main
(
void
*
data
);
void
runner_do_unskip_mapper
(
void
*
map_data
,
int
num_elements
,
void
*
extra_data
);
...
...
src/space.c
View file @
4e72575f
...
...
@@ -895,8 +895,9 @@ void space_rebuild(struct space *s, int verbose) {
#ifdef SWIFT_DEBUG_CHECKS
/* Verify that the links are correct */
part_verify_links
(
s
->
parts
,
s
->
gparts
,
s
->
sparts
,
nr_parts
,
nr_gparts
,
nr_sparts
,
verbose
);
if
((
nr_gparts
>
0
&&
nr_parts
>
0
)
||
(
nr_gparts
>
0
&&
nr_sparts
>
0
))
part_verify_links
(
s
->
parts
,
s
->
gparts
,
s
->
sparts
,
nr_parts
,
nr_gparts
,
nr_sparts
,
verbose
);
#endif
/* Hook the cells up to the parts. */
...
...
@@ -2952,47 +2953,3 @@ void space_clean(struct space *s) {
free
(
s
->
gparts
);
free
(
s
->
sparts
);
}
void
space_dump_multipoles
(
struct
space
*
s
)
{
hid_t
h_file
=
H5Fcreate
(
"multipoles.hdf5"
,
H5F_ACC_TRUNC
,
H5P_DEFAULT
,
H5P_DEFAULT
);
hid_t
h_grp
=
H5Gcreate
(
h_file
,
"/Multipoles"
,
H5P_DEFAULT
,
H5P_DEFAULT
,
H5P_DEFAULT
);
const
hid_t
h_space
=
H5Screate
(
H5S_SIMPLE
);
const
hid_t
h_space2
=
H5Screate
(
H5S_SIMPLE
);
hsize_t
shape
[
2
]
=
{
s
->
nr_cells
,
3
};
hsize_t
shape2
[
1
]
=
{
s
->
nr_cells
};
H5Sset_extent_simple
(
h_space
,
2
,
shape
,
NULL
);
H5Sset_extent_simple
(
h_space2
,
1
,
shape2
,
NULL
);
const
hid_t
h_data
=
H5Dcreate
(
h_grp
,
"Coordinates"
,
H5T_NATIVE_DOUBLE
,
h_space
,
H5P_DEFAULT
,
H5P_DEFAULT
,
H5P_DEFAULT
);
const
hid_t
h_data2
=
H5Dcreate
(
h_grp
,
"Potential"
,
H5T_NATIVE_DOUBLE
,
h_space2
,
H5P_DEFAULT
,
H5P_DEFAULT
,
H5P_DEFAULT
);
double
*
temp
=
malloc
(
s
->
nr_cells
*
3
*
sizeof
(
double
));
double
*
temp2
=
malloc
(
s
->
nr_cells
*
1
*
sizeof
(
double
));
for
(
int
i
=
0
;
i
<
s
->
nr_cells
;
++
i
)
{
temp
[
i
*
3
+
0
]
=
s
->
multipoles_top
[
i
].
CoM
[
0
];
temp
[
i
*
3
+
1
]
=
s
->
multipoles_top
[
i
].
CoM
[
1
];
temp
[
i
*
3
+
2
]
=
s
->
multipoles_top
[
i
].
CoM
[
2
];
temp2
[
i
]
=
s
->
multipoles_top
[
i
].
pot
.
F_000
;
}
H5Dwrite
(
h_data
,
H5T_NATIVE_DOUBLE
,
h_space
,
H5S_ALL
,
H5P_DEFAULT
,
temp
);
H5Dwrite
(
h_data2
,
H5T_NATIVE_DOUBLE
,
h_space2
,
H5S_ALL
,
H5P_DEFAULT
,
temp2
);
free
(
temp
);
free
(
temp2
);
H5Dclose
(
h_data
);
H5Dclose
(
h_data2
);
H5Sclose
(
h_space
);
H5Sclose
(
h_space2
);
H5Gclose
(
h_grp
);
H5Fclose
(
h_file
);
}
src/space.h
View file @
4e72575f
...
...
@@ -224,6 +224,5 @@ void space_check_timesteps(struct space *s);
void
space_replicate
(
struct
space
*
s
,
int
replicate
,
int
verbose
);
void
space_reset_task_counters
(
struct
space
*
s
);
void
space_clean
(
struct
space
*
s
);
void
space_dump_multipoles
(
struct
space
*
s
);
#endif
/* SWIFT_SPACE_H */
tests/Makefile.am
View file @
4e72575f
...
...
@@ -94,4 +94,5 @@ EXTRA_DIST = testReading.sh makeInput.py testPair.sh testPairPerturbed.sh \
test27cells.sh test27cellsPerturbed.sh testParser.sh
\
test125cells.sh testParserInput.yaml difffloat.py
\
tolerance_125.dat tolerance_27_normal.dat tolerance_27_perturbed.dat
\
tolerance_pair_normal.dat tolerance_pair_perturbed.dat
tolerance_pair_normal.dat tolerance_pair_perturbed.dat
\
fft_params.yml
tests/fft_params.yml
0 → 100644
View file @
4e72575f
Scheduler
:
max_top_level_cells
:
64
# Parameters for the self-gravity scheme
Gravity
:
eta
:
0.025
# Constant dimensionless multiplier for time integration.
theta
:
0.7
# Opening angle (Multipole acceptance criterion)
epsilon
:
0.00001
# Softening length (in internal units).
a_smooth
:
0.
r_cut
:
0.
tests/testFFT.c
View file @
4e72575f
...
...
@@ -18,8 +18,8 @@
******************************************************************************/
/* Some standard headers. */
#include
<stdlib.h>
#include
<strin
g.h
>
#include
"../confi
g.h
"
#ifndef HAVE_FFTW
...
...
@@ -27,19 +27,15 @@ int main() { return 0; }
#else
#include
<fftw3.h>
/* Some standard headers. */
#include
<fenv.h>
#include
<stdlib.h>
#include
<string.h>
/* Includes. */
#include
"swift.h"
const
double
G
=
1
.;
const
size_t
N
=
16
;
const
size_t
PMGRID
=
8
;
// const double asmth = 2. * M_PI * const_gravity_a_smooth / boxSize;
// const double asmth2 = asmth * asmth;
// const double fact = G / (M_PI * boxSize) * (1. / (2. * boxSize / PMGRID));
#define NEAREST(x) (((x) > 0.5) ? ((x)-1.) : (((x) < -0.5) ? ((x) + 1.) : (x)))
int
main
()
{
...
...
@@ -47,149 +43,77 @@ int main() {
unsigned
long
long
cpufreq
=
0
;
clocks_set_cpufreq
(
cpufreq
);
/* Simulation properties */
const
size_t
count
=
N
*
N
*
N
;
const
double
boxSize
=
1
.;
/* Create some particles */
struct
gpart
*
gparts
=
malloc
(
count
*
sizeof
(
struct
gpart
));
bzero
(
gparts
,
count
*
sizeof
(
struct
gpart
));
for
(
size_t
i
=
0
;
i
<
N
;
++
i
)
{
for
(
size_t
j
=
0
;
j
<
N
;
++
j
)
{
for
(
size_t
k
=
0
;
k
<
N
;
++
k
)
{
struct
gpart
*
gp
=
&
gparts
[
i
*
N
*
N
+
j
*
N
+
k
];
gp
->
x
[
0
]
=
i
*
boxSize
/
N
+
boxSize
/
(
2
*
N
);
gp
->
x
[
1
]
=
j
*
boxSize
/
N
+
boxSize
/
(
2
*
N
);
gp
->
x
[
2
]
=
k
*
boxSize
/
N
+
boxSize
/
(
2
*
N
);
gp
->
mass
=
1
.
/
count
;
gp
->
id_or_neg_offset
=
i
*
N
*
N
+
j
*
N
+
k
;
}
}
}
/* Properties of the mesh */
const
size_t
meshmin
[
3
]
=
{
0
,
0
,
0
};
const
size_t
meshmax
[
3
]
=
{
PMGRID
-
1
,
PMGRID
-
1
,
PMGRID
-
1
};
const
size_t
dimx
=
meshmax
[
0
]
-
meshmin
[
0
]
+
2
;
const
size_t
dimy
=
meshmax
[
1
]
-
meshmin
[
1
]
+
2
;
const
size_t
dimz
=
meshmax
[
2
]
-
meshmin
[
2
]
+
2
;
const
double
fac
=
PMGRID
/
boxSize
;
const
size_t
PMGRID2
=
2
*
(
PMGRID
/
2
+
1
);
/* message("dimx=%zd dimy=%zd dimz=%zd", dimx, dimy, dimz); */
/* Allocate and empty the workspace mesh */
const
size_t
workspace_size
=
(
dimx
+
4
)
*
(
dimy
+
4
)
*
(
dimz
+
4
);
double
*
workspace
=
fftw_malloc
(
workspace_size
*
sizeof
(
double
));
bzero
(
workspace
,
workspace_size
*
sizeof
(
double
));
/* Do CIC with the particles */
for
(
size_t
pid
=
0
;
pid
<
count
;
++
pid
)
{
const
struct
gpart
*
const
gp
=
&
gparts
[
pid
];
const
size_t
slab_x
=
(
fac
*
gp
->
x
[
0
]
>=
PMGRID
)
?
PMGRID
-
1
:
fac
*
gp
->
x
[
0
];
const
size_t
slab_y
=
(
fac
*
gp
->
x
[
1
]
>=
PMGRID
)
?
PMGRID
-
1
:
fac
*
gp
->
x
[
1
];
const
size_t
slab_z
=
(
fac
*
gp
->
x
[
2
]
>=
PMGRID
)
?
PMGRID
-
1
:
fac
*
gp
->
x
[
2
];
const
double
dx
=
fac
*
gp
->
x
[
0
]
-
(
double
)
slab_x
;
const
double
dy
=
fac
*
gp
->
x
[
1
]
-
(
double
)
slab_y
;
const
double
dz
=
fac
*
gp
->
x
[
2
]
-
(
double
)
slab_z
;
const
size_t
slab_xx
=
slab_x
+
1
;
const
size_t
slab_yy
=
slab_y
+
1
;
const
size_t
slab_zz
=
slab_z
+
1
;
workspace
[(
slab_x
*
dimy
+
slab_y
)
*
dimz
+
slab_z
]
+=
gp
->
mass
*
(
1
.
0
-
dx
)
*
(
1
.
0
-
dy
)
*
(
1
.
0
-
dz
);
workspace
[(
slab_x
*
dimy
+
slab_yy
)
*
dimz
+
slab_z
]
+=
gp
->
mass
*
(
1
.
0
-
dx
)
*
dy
*
(
1
.
0
-
dz
);
workspace
[(
slab_x
*
dimy
+
slab_y
)
*
dimz
+
slab_zz
]
+=
gp
->
mass
*
(
1
.
0
-
dx
)
*
(
1
.
0
-
dy
)
*
dz
;
workspace
[(
slab_x
*
dimy
+
slab_yy
)
*
dimz
+
slab_zz
]
+=
gp
->
mass
*
(
1
.
0
-
dx
)
*
dy
*
dz
;
workspace
[(
slab_xx
*
dimy
+
slab_y
)
*
dimz
+
slab_z
]
+=
gp
->
mass
*
(
dx
)
*
(
1
.
0
-
dy
)
*
(
1
.
0
-
dz
);
workspace
[(
slab_xx
*
dimy
+
slab_yy
)
*
dimz
+
slab_z
]
+=
gp
->
mass
*
(
dx
)
*
dy
*
(
1
.
0
-
dz
);
workspace
[(
slab_xx
*
dimy
+
slab_y
)
*
dimz
+
slab_zz
]
+=
gp
->
mass
*
(
dx
)
*
(
1
.
0
-
dy
)
*
dz
;
workspace
[(
slab_xx
*
dimy
+
slab_yy
)
*
dimz
+
slab_zz
]
+=
gp
->
mass
*
(
dx
)
*
dy
*
dz
;
}
/* for(size_t i = 0 ; i < dimx*dimy*dimz; ++i) */
/* message("workspace[%zd] = %f", i, workspace[i]); */
/* Prepare the force grid */
const
size_t
fft_size
=
workspace_size
;
double
*
forcegrid
=
fftw_malloc
(
fft_size
*
sizeof
(
double
));
bzero
(
forcegrid
,
fft_size
*
sizeof
(
double
));
const
size_t
sendmin
=
0
,
recvmin
=
0
;
const
size_t
sendmax
=
PMGRID
,
recvmax
=
PMGRID
;
memcpy
(
forcegrid
,
workspace
+
(
sendmin
-
meshmin
[
0
])
*
dimy
*
dimz
,
(
sendmax
-
sendmin
+
1
)
*
dimy
*
dimz
*
sizeof
(
double
));
/* for (size_t i = 0; i < fft_size; ++i) */
/* if (forcegrid[i] != workspace[i]) error("wrong"); */
/* Prepare the density grid */
double
*
rhogrid
=
fftw_malloc
(
fft_size
*
sizeof
(
double
));
bzero
(
rhogrid
,
fft_size
*
sizeof
(
double
));
/* Now get the density */
for
(
size_t
slab_x
=
recvmin
;
slab_x
<=
recvmax
;
slab_x
++
)
{
const
size_t
slab_xx
=
slab_x
%
PMGRID
;
for
(
size_t
slab_y
=
recvmin
;
slab_y
<=
recvmax
;
slab_y
++
)
{
const
size_t
slab_yy
=
slab_y
%
PMGRID
;
for
(
size_t
slab_z
=
recvmin
;
slab_z
<=
recvmax
;
slab_z
++
)
{
const
size_t
slab_zz
=
slab_z
%
PMGRID
;
rhogrid
[
PMGRID
*
PMGRID2
*
slab_xx
+
PMGRID2
*
slab_yy
+
slab_zz
]
+=
forcegrid
[((
slab_x
-
recvmin
)
*
dimy
+
(
slab_y
-
recvmin
))
*
dimz
+
(
slab_z
-
recvmin
)];
}
}
}
/* for (size_t i = 0; i < 640; i++) { */
/* if (rhogrid[i] != workspace[i]) { */
/* message("rhogrid[%zd]= %f workspace[%zd]= %f forcegrid[%zd]= %f", i, */
/* rhogrid[i], i, workspace[i], i, forcegrid[i]); */
/* } */
/* } */
/* FFT of the density field */
fftw_complex
*
fftgrid
=
fftw_malloc
(
fft_size
*
sizeof
(
fftw_complex
));
fftw_plan
plan_forward
=
fftw_plan_dft_r2c_3d
(
PMGRID
,
PMGRID
,
PMGRID
,
rhogrid
,
fftgrid
,
FFTW_ESTIMATE
);
fftw_execute
(
plan_forward
);
for
(
size_t
i
=
0
;
i
<
640
;
i
++
)
{
message
(
"workspace[%zd]= %f"
,
i
,
fftgrid
[
i
][
0
]);
/* Choke on FP-exceptions */
feenableexcept
(
FE_DIVBYZERO
|
FE_INVALID
|
FE_OVERFLOW
);
/* Make one particle */
int
nr_gparts
=
1
;
struct
gpart
*
gparts
=
NULL
;
posix_memalign
((
void
**
)
&
gparts
,
64
,
nr_gparts
*
sizeof
(
struct
gpart
));
bzero
(
gparts
,
nr_gparts
*
sizeof
(
struct
gpart
));
gparts
[
0
].
x
[
0
]
=
0
.
3
;
gparts
[
0
].
x
[
1
]
=
0
.
8
;
gparts
[
0
].
x
[
2
]
=
0
.
2
;
gparts
[
0
].
mass
=
1
.
f
;
/* Read the parameter file */
struct
swift_params
*
params
=
malloc
(
sizeof
(
struct
swift_params
));
parser_read_file
(
"fft_params.yml"
,
params
);
/* Initialise the gravity properties */
struct
gravity_props
gravity_properties
;
gravity_props_init
(
&
gravity_properties
,
params
);
/* Build the infrastructure */
struct
space
space
;
double
dim
[
3
]
=
{
1
.,
1
.,
1
.};
space_init
(
&
space
,
params
,
dim
,
NULL
,
gparts
,
NULL
,
0
,
nr_gparts
,
0
,
1
,
1
,
1
,
0
,
0
);
struct
engine
engine
;
engine
.
s
=
&
space
;
space
.
e
=
&
engine
;
engine
.
time
=
0
.
1
f
;
engine
.
ti_current
=
8
;
engine
.
max_active_bin
=
num_time_bins
;
engine
.
gravity_properties
=
&
gravity_properties
;
engine
.
nr_threads
=
1
;
struct
runner
runner
;
runner
.
e
=
&
engine
;
/* Initialize the threadpool. */
threadpool_init
(
&
engine
.
threadpool
,
engine
.
nr_threads
);
space_rebuild
(
&
space
,
0
);
/* Run the FFT task */
runner_do_grav_fft
(
&
runner
,
1
);
/* Now check that we got the right answer */
int
nr_cells
=
space
.
nr_cells
;
double
*
r
=
malloc
(
nr_cells
*
sizeof
(
double
));
double
*
pot
=
malloc
(
nr_cells
*
sizeof
(
double
));
double
*
pot_exact
=
malloc
(
nr_cells
*
sizeof
(
double
));
FILE
*
file
=
fopen
(
"potential.dat"
,
"w"
);
for
(
int
i
=
0
;
i
<
nr_cells
;
++
i
)
{
pot
[
i
]
=
space
.
multipoles_top
[
i
].
pot
.
F_000
;
double
dx
=
NEAREST
(
space
.
multipoles_top
[
i
].
CoM
[
0
]
-
gparts
[
0
].
x
[
0
]);
double
dy
=
NEAREST
(
space
.
multipoles_top
[
i
].
CoM
[
1
]
-
gparts
[
0
].
x
[
1
]);
double
dz
=
NEAREST
(
space
.
multipoles_top
[
i
].
CoM
[
2
]
-
gparts
[
0
].
x
[
2
]);
r
[
i
]
=
sqrt
(
dx
*
dx
+
dy
*
dy
+
dz
*
dz
);
if
(
r
[
i
]
>
0
)
pot_exact
[
i
]
=
-
1
.
/
r
[
i
];
fprintf
(
file
,
"%e %e %e
\n
"
,
r
[
i
],
pot
[
i
],
pot_exact
[
i
]);
}
fclose
(
file
);
/* Clean
-
up */
f
ftw_destroy_plan
(
plan_forward
);
f
ftw_free
(
forcegrid
);
f
ftw_free
(
rhogrid
);
f
ftw_free
(
workspace
);
/* Clean
up */
f
ree
(
r
);
f
ree
(
pot
);
f
ree
(
pot_exact
);
f
ree
(
params
);
free
(
gparts
);
return
0
;
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment