Skip to content
Snippets Groups Projects
Commit 55a02e1e authored by James Willis's avatar James Willis
Browse files

Perform FOF tree search recursively.

parent 89e75783
Branches
Tags
1 merge request!543Fof
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* Local headers. */ /* Local headers. */
//#include "active.h" //#include "active.h"
__attribute__((always_inline)) INLINE int fof_find(const int i, const int *pid) { __attribute__((always_inline)) INLINE static int fof_find(const int i, const int *pid) {
int root = i; int root = i;
while(root != pid[root]) while(root != pid[root])
...@@ -43,6 +43,91 @@ __attribute__((always_inline)) INLINE int fof_find(const int i, const int *pid) ...@@ -43,6 +43,91 @@ __attribute__((always_inline)) INLINE int fof_find(const int i, const int *pid)
return root; return root;
} }
static void rec_fof_search_sub(struct cell *ci, struct cell *cj, struct space *s, int *pid, int *num_in_groups, int *num_groups, const double *dim, const double search_r2) {
/* Recurse on cj. */
if (cj->split)
for (int k = 0; k < 8; k++)
if (cj->progeny[k] != NULL)
rec_fof_search_sub(ci, cj->progeny[k], s, pid, num_in_groups, num_groups, dim, search_r2);
/* No progeny? */
if (!cj->split) {
const double cix = ci->loc[0];
const double ciy = ci->loc[1];
const double ciz = ci->loc[2];
const double cjx = cj->loc[0];
const double cjy = cj->loc[1];
const double cjz = cj->loc[2];
/* Find the shortest distance between cells, remembering to account for boundary conditions. */
float dx[3], r2 = 0.0f;
dx[0] = min3(abs(nearest(cix - cjx, dim[0])), abs(nearest(cix - (cjx + cj->width[0]), dim[0])), abs(nearest((cix + ci->width[0]) - cjx, dim[0])));
dx[0] = min(dx[0], abs(nearest((cix + ci->width[0]) - (cjx + cj->width[0]), dim[0])));
dx[1] = min3(abs(nearest(ciy - cjy, dim[1])), abs(nearest(ciy - (cjy + cj->width[1]), dim[1])), abs(nearest((ciy + ci->width[1]) - cjy, dim[1])));
dx[1] = min(dx[1], abs(nearest((ciy + ci->width[1]) - (cjy + cj->width[1]), dim[1])));
dx[2] = min3(abs(nearest(ciz - cjz, dim[2])), abs(nearest(ciz - (cjz + cj->width[2]), dim[2])), abs(nearest((ciz + ci->width[2]) - cjz, dim[2])));
dx[2] = min(dx[2], abs(nearest((ciz + ci->width[2]) - (cjz + cj->width[2]), dim[2])));
for (int k = 0; k < 3; k++) {
r2 += dx[k] * dx[k];
}
/* Perform FOF search between pairs of cells that are within the linking length and not the same cell. */
if (r2 < search_r2 && ci != cj) {
fof_search_pair_cells(s, ci, cj, pid, num_in_groups, num_groups);
}
}
}
static void rec_fof_search(struct cell *ci, const int cid, struct space *s, int *pid, int *num_in_groups, int *num_groups, const double *dim, const double search_r2) {
/* Recurse on ci. */
if (ci->split)
for (int k = 0; k < 8; k++)
if (ci->progeny[k] != NULL)
rec_fof_search(ci->progeny[k], cid, s, pid, num_in_groups, num_groups, dim, search_r2);
/* No progeny? */
if (!ci->split) {
const double cix = ci->loc[0];
const double ciy = ci->loc[1];
const double ciz = ci->loc[2];
/* Loop over all other top-level cells. */
for(int cjd=cid + 1; cjd<s->nr_cells; cjd++) {
struct cell *restrict cj = &s->cells_top[cjd];
const double cjx = cj->loc[0];
const double cjy = cj->loc[1];
const double cjz = cj->loc[2];
/* Find the shortest distance between cells, remembering to account for boundary conditions. */
float dx[3], r2 = 0.0f;
dx[0] = min3(abs(nearest(cix - cjx, dim[0])), abs(nearest(cix - (cjx + cj->width[0]), dim[0])), abs(nearest((cix + ci->width[0]) - cjx, dim[0])));
dx[0] = min(dx[0], abs(nearest((cix + ci->width[0]) - (cjx + cj->width[0]), dim[0])));
dx[1] = min3(abs(nearest(ciy - cjy, dim[1])), abs(nearest(ciy - (cjy + cj->width[1]), dim[1])), abs(nearest((ciy + ci->width[1]) - cjy, dim[1])));
dx[1] = min(dx[1], abs(nearest((ciy + ci->width[1]) - (cjy + cj->width[1]), dim[1])));
dx[2] = min3(abs(nearest(ciz - cjz, dim[2])), abs(nearest(ciz - (cjz + cj->width[2]), dim[2])), abs(nearest((ciz + ci->width[2]) - cjz, dim[2])));
dx[2] = min(dx[2], abs(nearest((ciz + ci->width[2]) - (cjz + cj->width[2]), dim[2])));
for (int k = 0; k < 3; k++) r2 += dx[k] * dx[k];
/* If the leaf cell of ci is within the linking length of the top-level cell cj recurse on cj. Otherwise skip over cj as all of its leaf cells will also be out of range. */
if (r2 > search_r2) continue;
else if(cj->split) rec_fof_search_sub(ci, cj, s, pid, num_in_groups, num_groups, dim, search_r2);
/* Perform FOF search between pairs of cells that are within the linking length and not the same cell. */
else if(ci != cj) fof_search_pair_cells(s, ci, cj, pid, num_in_groups, num_groups);
}
}
}
void fof_search_naive(struct space *s) { void fof_search_naive(struct space *s) {
const size_t nr_gparts = s->nr_gparts; const size_t nr_gparts = s->nr_gparts;
...@@ -404,41 +489,17 @@ void fof_search_tree_serial(struct space *s) { ...@@ -404,41 +489,17 @@ void fof_search_tree_serial(struct space *s) {
/* Loop over cells and find which cells are in range of each other to perform the FOF search. */ /* Loop over cells and find which cells are in range of each other to perform the FOF search. */
for(int cid=0; cid<nr_cells; cid++) { for(int cid=0; cid<nr_cells; cid++) {
struct cell *restrict ci = &s->cells_top[cid]; struct cell *restrict c = &s->cells_top[cid];
const double cix = ci->loc[0];
const double ciy = ci->loc[1];
const double ciz = ci->loc[2];
/* Perform FOF search on local particles within the cell. */ message("Searching top-level cell: %d.", cid);
fof_search_cell(s, ci, pid, num_in_groups, &num_groups); fflush(stdout);
for(int cjd=cid + 1; cjd<nr_cells; cjd++) {
struct cell *restrict cj = &s->cells_top[cjd];
const double cjx = cj->loc[0];
const double cjy = cj->loc[1];
const double cjz = cj->loc[2];
/* Find the shortest distance between cells, remembering to account for boundary conditions. */ /* Perform FOF search on local particles within the cell. */
float dx[3], r2 = 0.0f; fof_search_cell(s, c, pid, num_in_groups, &num_groups);
dx[0] = min3(abs(nearest(cix - cjx, dim[0])), abs(nearest(cix - (cjx + cj->width[0]), dim[0])), abs(nearest((cix + ci->width[0]) - cjx, dim[0])));
dx[0] = min(dx[0], abs(nearest((cix + ci->width[0]) - (cjx + cj->width[0]), dim[0])));
dx[1] = min3(abs(nearest(ciy - cjy, dim[1])), abs(nearest(ciy - (cjy + cj->width[1]), dim[1])), abs(nearest((ciy + ci->width[1]) - cjy, dim[1])));
dx[1] = min(dx[1], abs(nearest((ciy + ci->width[1]) - (cjy + cj->width[1]), dim[1])));
dx[2] = min3(abs(nearest(ciz - cjz, dim[2])), abs(nearest(ciz - (cjz + cj->width[2]), dim[2])), abs(nearest((ciz + ci->width[2]) - cjz, dim[2])));
dx[2] = min(dx[2], abs(nearest((ciz + ci->width[2]) - (cjz + cj->width[2]), dim[2])));
for (int k = 0; k < 3; k++) { /* Recursively perform FOF search on all other cells in top-level grid. */
r2 += dx[k] * dx[k]; rec_fof_search(c, cid, s, pid, num_in_groups, &num_groups, dim, search_r2);
}
/* Perform FOF search between pairs of cells that are within the linking length. */
if (r2 < search_r2) {
fof_search_pair_cells(s, ci, cj, pid, num_in_groups, &num_groups);
}
}
} }
fof_dump_group_data("fof_output_tree_serial.dat", nr_gparts, pid, num_in_groups); fof_dump_group_data("fof_output_tree_serial.dat", nr_gparts, pid, num_in_groups);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment