Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Q
QuickSched
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
SWIFT
QuickSched
Commits
625db4bd
Commit
625db4bd
authored
10 years ago
by
Matthieu Schaller
Browse files
Options
Downloads
Patches
Plain Diff
New version of the B-H code that uses quadrupoles for increased accuracy
parent
e319cf16
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
examples/test_bh_new.c
+186
-26
186 additions, 26 deletions
examples/test_bh_new.c
with
186 additions
and
26 deletions
examples/test_bh_new.c
+
186
−
26
View file @
625db4bd
...
...
@@ -37,16 +37,17 @@
/* Some local constants. */
#define cell_pool_grow 1000
#define cell_maxparts 1
00
#define task_limit 1
e8
#define cell_maxparts 1
28
#define task_limit 1
#define const_G 1 // 6.6738e-8
#define dist_min 0.5
/* Used for legacy walk only */
#define dist_cutoff_ratio 1.5
#define ICHECK -1
#define
NO_
SANITY_CHECKS
#define SANITY_CHECKS
#define NO_COM_AS_TASK
#define NO_COUNTERS
#define QUADRUPOLES
/** Data structure for the particles. */
struct
part
{
...
...
@@ -67,11 +68,21 @@ struct part_local {
}
__attribute__
((
aligned
(
32
)));
struct
multipole
{
#ifdef QUADRUPOLES
double
I
[
3
][
3
];
#endif
double
com
[
3
];
float
mass
;
};
struct
multipole_local
{
#ifdef QUADRUPOLES
float
I
[
3
][
3
];
#endif
float
com
[
3
];
float
mass
;
};
...
...
@@ -103,7 +114,7 @@ struct cell {
int
res
,
com_tid
;
struct
index
*
indices
;
}
__attribute__
((
aligned
(
128
)));
}
;
//
__attribute__((aligned(
256
)));
/** Task types. */
enum
task_type
{
...
...
@@ -173,6 +184,15 @@ void comp_com(struct cell *c) {
struct
part
*
parts
=
c
->
parts
;
double
com
[
3
]
=
{
0
.
0
,
0
.
0
,
0
.
0
},
mass
=
0
.
0
;
#ifdef QUADRUPOLES
double
I
[
3
][
3
]
=
{{
0
.
0
,
0
.
0
,
0
.
0
}
,
{
0
.
0
,
0
.
0
,
0
.
0
}
,
{
0
.
0
,
0
.
0
,
0
.
0
}
};
#endif
#ifdef SANITY_CHECKS
if
(
count
==
0
)
error
(
"CoM computed for an empty cell"
);
#endif
if
(
c
->
split
)
{
/* Loop over the projenitors and collect the multipole information. */
...
...
@@ -182,9 +202,29 @@ void comp_com(struct cell *c) {
com
[
1
]
+=
cp
->
new
.
com
[
1
]
*
cp_mass
;
com
[
2
]
+=
cp
->
new
.
com
[
2
]
*
cp_mass
;
mass
+=
cp_mass
;
#ifdef QUADRUPOLES
I
[
0
][
0
]
+=
cp
->
new
.
I
[
0
][
0
];
I
[
0
][
1
]
+=
cp
->
new
.
I
[
0
][
1
];
I
[
0
][
2
]
+=
cp
->
new
.
I
[
0
][
2
];
I
[
1
][
0
]
+=
cp
->
new
.
I
[
1
][
0
];
I
[
1
][
1
]
+=
cp
->
new
.
I
[
1
][
1
];
I
[
1
][
2
]
+=
cp
->
new
.
I
[
1
][
2
];
I
[
2
][
0
]
+=
cp
->
new
.
I
[
2
][
0
];
I
[
2
][
1
]
+=
cp
->
new
.
I
[
2
][
1
];
I
[
2
][
2
]
+=
cp
->
new
.
I
[
2
][
2
];
#endif
}
/* Otherwise, collect the multipole from the particles. */
/* Final operation for the COM */
float
imass
=
1
.
0
f
/
mass
;
com
[
0
]
*=
imass
;
com
[
1
]
*=
imass
;
com
[
2
]
*=
imass
;
/* Otherwise, collect the multipole from the particles. */
}
else
{
for
(
k
=
0
;
k
<
count
;
k
++
)
{
...
...
@@ -193,22 +233,47 @@ void comp_com(struct cell *c) {
com
[
1
]
+=
parts
[
k
].
x
[
1
]
*
p_mass
;
com
[
2
]
+=
parts
[
k
].
x
[
2
]
*
p_mass
;
mass
+=
p_mass
;
#ifdef QUADRUPOLES
I
[
0
][
0
]
+=
parts
[
k
].
x
[
0
]
*
parts
[
k
].
x
[
0
]
*
p_mass
;
I
[
0
][
1
]
+=
parts
[
k
].
x
[
0
]
*
parts
[
k
].
x
[
1
]
*
p_mass
;
I
[
0
][
2
]
+=
parts
[
k
].
x
[
0
]
*
parts
[
k
].
x
[
2
]
*
p_mass
;
I
[
1
][
0
]
+=
parts
[
k
].
x
[
1
]
*
parts
[
k
].
x
[
0
]
*
p_mass
;
I
[
1
][
1
]
+=
parts
[
k
].
x
[
1
]
*
parts
[
k
].
x
[
1
]
*
p_mass
;
I
[
1
][
2
]
+=
parts
[
k
].
x
[
1
]
*
parts
[
k
].
x
[
2
]
*
p_mass
;
I
[
2
][
0
]
+=
parts
[
k
].
x
[
2
]
*
parts
[
k
].
x
[
0
]
*
p_mass
;
I
[
2
][
1
]
+=
parts
[
k
].
x
[
2
]
*
parts
[
k
].
x
[
1
]
*
p_mass
;
I
[
2
][
2
]
+=
parts
[
k
].
x
[
2
]
*
parts
[
k
].
x
[
2
]
*
p_mass
;
#endif
}
}
/* Store the COM data, if any was collected. */
if
(
mass
>
0
.
0
)
{
/* Final operation for the COM */
float
imass
=
1
.
0
f
/
mass
;
c
->
new
.
com
[
0
]
=
com
[
0
]
*
imass
;
c
->
new
.
com
[
1
]
=
com
[
1
]
*
imass
;
c
->
new
.
com
[
2
]
=
com
[
2
]
*
imass
;
c
->
new
.
mass
=
mass
;
}
else
{
c
->
new
.
com
[
0
]
=
0
.
0
;
c
->
new
.
com
[
1
]
=
0
.
0
;
c
->
new
.
com
[
2
]
=
0
.
0
;
c
->
new
.
mass
=
0
.
0
;
com
[
0
]
*=
imass
;
com
[
1
]
*=
imass
;
com
[
2
]
*=
imass
;
}
/* Store the multipole data */
c
->
new
.
mass
=
mass
;
c
->
new
.
com
[
0
]
=
com
[
0
];
c
->
new
.
com
[
1
]
=
com
[
1
];
c
->
new
.
com
[
2
]
=
com
[
2
];
#ifdef QUADRUPOLES
c
->
new
.
I
[
0
][
0
]
=
I
[
0
][
0
];
c
->
new
.
I
[
0
][
1
]
=
I
[
0
][
1
];
c
->
new
.
I
[
0
][
2
]
=
I
[
0
][
2
];
c
->
new
.
I
[
1
][
0
]
=
I
[
1
][
0
];
c
->
new
.
I
[
1
][
1
]
=
I
[
1
][
1
];
c
->
new
.
I
[
1
][
2
]
=
I
[
1
][
2
];
c
->
new
.
I
[
2
][
0
]
=
I
[
2
][
0
];
c
->
new
.
I
[
2
][
1
]
=
I
[
2
][
1
];
c
->
new
.
I
[
2
][
2
]
=
I
[
2
][
2
];
#endif
}
/**
...
...
@@ -427,7 +492,7 @@ static inline void make_interact_pc(struct part_local *parts, int part_count,
struct
multipole_local
mults
[
8
],
int
mult_count
)
{
int
i
,
j
,
k
;
float
dx
[
3
]
=
{
0
.
0
,
0
.
0
,
0
.
0
},
r2
,
ir
,
w
;
float
dx
[
3
]
=
{
0
.
0
,
0
.
0
,
0
.
0
},
r2
,
ir
,
mrinv3
;
#ifdef SANITY_CHECKS
...
...
@@ -455,8 +520,37 @@ static inline void make_interact_pc(struct part_local *parts, int part_count,
/* Apply the gravitational acceleration. */
ir
=
1
.
0
f
/
sqrtf
(
r2
);
w
=
mults
[
j
].
mass
*
const_G
*
ir
*
ir
*
ir
;
for
(
k
=
0
;
k
<
3
;
k
++
)
parts
[
i
].
a
[
k
]
+=
w
*
dx
[
k
];
mrinv3
=
mults
[
j
].
mass
*
const_G
*
ir
*
ir
*
ir
;
#ifndef QUADRUPOLES
parts
[
i
].
a
[
0
]
+=
mrinv3
*
dx
[
0
];
parts
[
i
].
a
[
1
]
+=
mrinv3
*
dx
[
1
];
parts
[
i
].
a
[
2
]
+=
mrinv3
*
dx
[
2
];
#else
float
mrinv5
=
mrinv3
*
ir
*
ir
;
float
mrinv7
=
mrinv5
*
ir
*
ir
;
float
D1
=
-
mrinv3
;
float
D2
=
3
.
f
*
mrinv5
;
float
D3
=
-
15
.
f
*
mrinv7
;
float
q
=
mults
[
j
].
I
[
0
][
0
]
+
mults
[
j
].
I
[
1
][
1
]
+
mults
[
j
].
I
[
2
][
2
];
float
qRx
=
mults
[
j
].
I
[
0
][
0
]
*
dx
[
0
]
+
mults
[
j
].
I
[
0
][
1
]
*
dx
[
1
]
+
mults
[
j
].
I
[
0
][
2
]
*
dx
[
2
];
float
qRy
=
mults
[
j
].
I
[
1
][
0
]
*
dx
[
0
]
+
mults
[
j
].
I
[
1
][
1
]
*
dx
[
1
]
+
mults
[
j
].
I
[
1
][
2
]
*
dx
[
2
];
float
qRz
=
mults
[
j
].
I
[
2
][
0
]
*
dx
[
0
]
+
mults
[
j
].
I
[
2
][
1
]
*
dx
[
1
]
+
mults
[
j
].
I
[
2
][
2
]
*
dx
[
2
];
float
qRR
=
qRx
*
dx
[
0
]
+
qRy
*
dx
[
1
]
+
qRz
*
dx
[
2
];
float
C
=
D1
+
0
.
5
f
*
D2
*
q
+
0
.
5
f
*
D3
*
qRR
;
parts
[
i
].
a
[
0
]
-=
C
*
dx
[
0
]
+
D2
*
qRx
;
parts
[
i
].
a
[
1
]
-=
C
*
dx
[
1
]
+
D2
*
qRy
;
parts
[
i
].
a
[
2
]
-=
C
*
dx
[
2
]
+
D2
*
qRz
;
/* message(" %f %f %f", C * dx[0] + D2 * qRx, C * dx[1] + D2 * qRy, C * dx[2] + D2 * qRz); */
#endif
}
/* loop over every multipoles. */
}
/* loop over every particle. */
...
...
@@ -517,6 +611,21 @@ static inline void iact_pair_pc(struct cell *ci, struct cell *cj) {
mult_local
[
mult_count
].
com
[
2
]
=
cps
->
new
.
com
[
2
]
-
cp
->
loc
[
2
];
mult_local
[
mult_count
].
mass
=
cps
->
new
.
mass
;
#ifdef QUADRUPOLES
/* Final operation to get the quadrupoles */
double
imass
=
1
.
/
cps
->
new
.
mass
;
mult_local
[
mult_count
].
I
[
0
][
0
]
=
cps
->
new
.
I
[
0
][
0
]
*
imass
-
cps
->
new
.
com
[
0
]
*
cps
->
new
.
com
[
0
];
mult_local
[
mult_count
].
I
[
0
][
1
]
=
cps
->
new
.
I
[
0
][
1
]
*
imass
-
cps
->
new
.
com
[
0
]
*
cps
->
new
.
com
[
1
];
mult_local
[
mult_count
].
I
[
0
][
2
]
=
cps
->
new
.
I
[
0
][
2
]
*
imass
-
cps
->
new
.
com
[
0
]
*
cps
->
new
.
com
[
2
];
mult_local
[
mult_count
].
I
[
1
][
0
]
=
cps
->
new
.
I
[
1
][
0
]
*
imass
-
cps
->
new
.
com
[
1
]
*
cps
->
new
.
com
[
0
];
mult_local
[
mult_count
].
I
[
1
][
1
]
=
cps
->
new
.
I
[
1
][
1
]
*
imass
-
cps
->
new
.
com
[
1
]
*
cps
->
new
.
com
[
1
];
mult_local
[
mult_count
].
I
[
1
][
2
]
=
cps
->
new
.
I
[
1
][
2
]
*
imass
-
cps
->
new
.
com
[
1
]
*
cps
->
new
.
com
[
2
];
mult_local
[
mult_count
].
I
[
2
][
0
]
=
cps
->
new
.
I
[
2
][
0
]
*
imass
-
cps
->
new
.
com
[
2
]
*
cps
->
new
.
com
[
0
];
mult_local
[
mult_count
].
I
[
2
][
1
]
=
cps
->
new
.
I
[
2
][
1
]
*
imass
-
cps
->
new
.
com
[
2
]
*
cps
->
new
.
com
[
1
];
mult_local
[
mult_count
].
I
[
2
][
2
]
=
cps
->
new
.
I
[
2
][
2
]
*
imass
-
cps
->
new
.
com
[
2
]
*
cps
->
new
.
com
[
2
];
#endif
mult_count
++
;
}
}
...
...
@@ -1172,13 +1281,14 @@ void interact_exact(int N, struct part *parts, int monitor) {
*/
void
test_bh
(
int
N
,
int
nr_threads
,
int
runs
,
char
*
fileName
)
{
int
i
,
k
;
int
i
,
j
,
k
;
struct
cell
*
root
;
struct
part
*
parts
;
FILE
*
file
;
struct
qsched
s
;
ticks
tic
,
toc_run
,
tot_setup
=
0
,
tot_run
=
0
;
int
countMultipoles
=
0
,
countPairs
=
0
,
countCoMs
=
0
;
// double I[3][3] = {{0., 0., 0.},{0., 0., 0.},{0., 0., 0.}};
/* Runner function. */
void
runner
(
int
type
,
void
*
data
)
{
...
...
@@ -1231,6 +1341,23 @@ void test_bh(int N, int nr_threads, int runs, char *fileName) {
parts
[
k
].
a_legacy
[
1
]
=
0
.
0
;
parts
[
k
].
a_legacy
[
2
]
=
0
.
0
;
}
j
++
;
/* for (i = 0; i < 4; i++) { */
/* for (j = 0; j < 4; j++) { */
/* for (k = 0; k < 4; k++) { */
/* int l = 16*i + 4*j + k; */
/* parts[l].id = l; */
/* parts[l].x[0] = 0.125 + 0.25 * i; */
/* parts[l].x[1] = 0.125 + 0.25 * j; */
/* parts[l].x[2] = 0.125 + 0.25 * k; */
/* parts[l].mass = 1.; */
/* parts[l].a_legacy[0] = 0.0; */
/* parts[l].a_legacy[1] = 0.0; */
/* parts[l].a_legacy[2] = 0.0; */
/* } */
/* } */
/* } */
/* Otherwise, read them from a file. */
}
else
{
...
...
@@ -1274,7 +1401,7 @@ void test_bh(int N, int nr_threads, int runs, char *fileName) {
}
message
(
"Average number of parts per leaf is %f."
,
((
double
)
N
)
/
nr_leaves
);
#if ICHECK > 0
#if
1 //
ICHECK > 0
printf
(
"----------------------------------------------------------
\n
"
);
/* Do a N^2 interactions calculation */
...
...
@@ -1355,10 +1482,43 @@ void test_bh(int N, int nr_threads, int runs, char *fileName) {
tot_run
+=
toc_run
-
tic
;
}
message
(
"[check] root mass= %f %f"
,
root
->
legacy
.
mass
,
root
->
new
.
mass
);
message
(
"[check] root CoMx= %f %f"
,
root
->
legacy
.
com
[
0
],
root
->
new
.
com
[
0
]);
message
(
"[check] root CoMy= %f %f"
,
root
->
legacy
.
com
[
1
],
root
->
new
.
com
[
1
]);
message
(
"[check] root CoMz= %f %f"
,
root
->
legacy
.
com
[
2
],
root
->
new
.
com
[
2
]);
/* for (k = 0; k < N; ++k) { */
/* I[0][0] += parts[k].mass * parts[k].x[0] * parts[k].x[0]; */
/* I[0][1] += parts[k].mass * parts[k].x[0] * parts[k].x[1]; */
/* I[0][2] += parts[k].mass * parts[k].x[0] * parts[k].x[2]; */
/* I[1][0] += parts[k].mass * parts[k].x[1] * parts[k].x[0]; */
/* I[1][1] += parts[k].mass * parts[k].x[1] * parts[k].x[1]; */
/* I[1][2] += parts[k].mass * parts[k].x[1] * parts[k].x[2]; */
/* I[2][0] += parts[k].mass * parts[k].x[2] * parts[k].x[0]; */
/* I[2][1] += parts[k].mass * parts[k].x[2] * parts[k].x[1]; */
/* I[2][2] += parts[k].mass * parts[k].x[2] * parts[k].x[2]; */
/* } */
/* for (k = 0; k < N; ++k) { */
/* I[0][0] = I[0][0] / root->new.mass - root->new.com[0]*root->new.com[0]; */
/* I[0][1] = I[0][1] / root->new.mass - root->new.com[0]*root->new.com[1]; */
/* I[0][2] = I[0][2] / root->new.mass - root->new.com[0]*root->new.com[2]; */
/* I[1][0] = I[1][0] / root->new.mass - root->new.com[1]*root->new.com[0]; */
/* I[1][1] = I[1][1] / root->new.mass - root->new.com[1]*root->new.com[1]; */
/* I[1][2] = I[1][2] / root->new.mass - root->new.com[1]*root->new.com[2]; */
/* I[2][0] = I[2][0] / root->new.mass - root->new.com[2]*root->new.com[0]; */
/* I[2][1] = I[2][1] / root->new.mass - root->new.com[2]*root->new.com[1]; */
/* I[2][2] = I[2][2] / root->new.mass - root->new.com[2]*root->new.com[2]; */
/* } */
/* message("[check] root mass= %f %f", root->legacy.mass, root->new.mass); */
/* message("[check] root CoMx= %f %f", root->legacy.com[0], root->new.com[0]); */
/* message("[check] root CoMy= %f %f", root->legacy.com[1], root->new.com[1]); */
/* message("[check] root CoMz= %f %f", root->legacy.com[2], root->new.com[2]); */
/* message(" | %f %f %f |", root->new.I[0][0], root->new.I[0][1], root->new.I[0][2]); */
/* message("In=| %f %f %f |", root->new.I[1][0], root->new.I[1][1], root->new.I[1][2]); */
/* message(" | %f %f %f |", root->new.I[2][0], root->new.I[2][1], root->new.I[2][2]); */
/* message("------------------------------------------------") */
/* message(" | %f %f %f |", I[0][0], I[0][1], I[0][2]); */
/* message("I =| %f %f %f |", I[1][0], I[1][1], I[1][2]); */
/* message(" | %f %f %f |", I[2][0], I[2][1], I[2][2]); */
#if ICHECK >= 0
for
(
i
=
0
;
i
<
N
;
++
i
)
if
(
root
->
parts
[
i
].
id
==
ICHECK
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
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!
Save comment
Cancel
Please
register
or
sign in
to comment