Commit 86db3dab authored by Peter W. Draper's avatar Peter W. Draper
Browse files

Merge branch 'faster_rebuilds' into 'master'

Updated cell splitting strategy

See merge request !493
parents 2643736b 7cb536a4
...@@ -835,11 +835,15 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset, ...@@ -835,11 +835,15 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
memswap(&parts[j], &part, sizeof(struct part)); memswap(&parts[j], &part, sizeof(struct part));
memswap(&xparts[j], &xpart, sizeof(struct xpart)); memswap(&xparts[j], &xpart, sizeof(struct xpart));
memswap(&buff[j], &temp_buff, sizeof(struct cell_buff)); memswap(&buff[j], &temp_buff, sizeof(struct cell_buff));
if (parts[j].gpart)
parts[j].gpart->id_or_neg_offset = -(j + parts_offset);
bid = temp_buff.ind; bid = temp_buff.ind;
} }
parts[k] = part; parts[k] = part;
xparts[k] = xpart; xparts[k] = xpart;
buff[k] = temp_buff; buff[k] = temp_buff;
if (parts[k].gpart)
parts[k].gpart->id_or_neg_offset = -(k + parts_offset);
} }
bucket_count[bid]++; bucket_count[bid]++;
} }
...@@ -852,10 +856,6 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset, ...@@ -852,10 +856,6 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
c->progeny[k]->xparts = &c->xparts[bucket_offset[k]]; c->progeny[k]->xparts = &c->xparts[bucket_offset[k]];
} }
/* Re-link the gparts. */
if (count > 0 && gcount > 0)
part_relink_gparts_to_parts(parts, count, parts_offset);
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
/* Check that the buffs are OK. */ /* Check that the buffs are OK. */
for (int k = 1; k < count; k++) { for (int k = 1; k < count; k++) {
...@@ -952,10 +952,14 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset, ...@@ -952,10 +952,14 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
} }
memswap(&sparts[j], &spart, sizeof(struct spart)); memswap(&sparts[j], &spart, sizeof(struct spart));
memswap(&sbuff[j], &temp_buff, sizeof(struct cell_buff)); memswap(&sbuff[j], &temp_buff, sizeof(struct cell_buff));
if (sparts[j].gpart)
sparts[j].gpart->id_or_neg_offset = -(j + sparts_offset);
bid = temp_buff.ind; bid = temp_buff.ind;
} }
sparts[k] = spart; sparts[k] = spart;
sbuff[k] = temp_buff; sbuff[k] = temp_buff;
if (sparts[k].gpart)
sparts[k].gpart->id_or_neg_offset = -(k + sparts_offset);
} }
bucket_count[bid]++; bucket_count[bid]++;
} }
...@@ -967,10 +971,6 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset, ...@@ -967,10 +971,6 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
c->progeny[k]->sparts = &c->sparts[bucket_offset[k]]; c->progeny[k]->sparts = &c->sparts[bucket_offset[k]];
} }
/* Re-link the gparts. */
if (scount > 0 && gcount > 0)
part_relink_gparts_to_sparts(sparts, scount, sparts_offset);
/* Finally, do the same song and dance for the gparts. */ /* Finally, do the same song and dance for the gparts. */
for (int k = 0; k < 8; k++) bucket_count[k] = 0; for (int k = 0; k < 8; k++) bucket_count[k] = 0;
...@@ -1005,10 +1005,23 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset, ...@@ -1005,10 +1005,23 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
} }
memswap(&gparts[j], &gpart, sizeof(struct gpart)); memswap(&gparts[j], &gpart, sizeof(struct gpart));
memswap(&gbuff[j], &temp_buff, sizeof(struct cell_buff)); memswap(&gbuff[j], &temp_buff, sizeof(struct cell_buff));
if (gparts[j].type == swift_type_gas) {
parts[-gparts[j].id_or_neg_offset - parts_offset].gpart =
&gparts[j];
} else if (gparts[j].type == swift_type_star) {
sparts[-gparts[j].id_or_neg_offset - sparts_offset].gpart =
&gparts[j];
}
bid = temp_buff.ind; bid = temp_buff.ind;
} }
gparts[k] = gpart; gparts[k] = gpart;
gbuff[k] = temp_buff; gbuff[k] = temp_buff;
if (gparts[k].type == swift_type_gas) {
parts[-gparts[k].id_or_neg_offset - parts_offset].gpart = &gparts[k];
} else if (gparts[k].type == swift_type_star) {
sparts[-gparts[k].id_or_neg_offset - sparts_offset].gpart =
&gparts[k];
}
} }
bucket_count[bid]++; bucket_count[bid]++;
} }
...@@ -1019,14 +1032,6 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset, ...@@ -1019,14 +1032,6 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
c->progeny[k]->gcount = bucket_count[k]; c->progeny[k]->gcount = bucket_count[k];
c->progeny[k]->gparts = &c->gparts[bucket_offset[k]]; c->progeny[k]->gparts = &c->gparts[bucket_offset[k]];
} }
/* Re-link the parts. */
if (count > 0 && gcount > 0)
part_relink_parts_to_gparts(gparts, gcount, parts - parts_offset);
/* Re-link the sparts. */
if (scount > 0 && gcount > 0)
part_relink_sparts_to_gparts(gparts, gcount, sparts - sparts_offset);
} }
/** /**
......
...@@ -565,7 +565,8 @@ void engine_redistribute(struct engine *e) { ...@@ -565,7 +565,8 @@ void engine_redistribute(struct engine *e) {
/* Sort the particles according to their cell index. */ /* Sort the particles according to their cell index. */
if (s->nr_parts > 0) if (s->nr_parts > 0)
space_parts_sort(s, dest, s->nr_parts, 0, nr_nodes - 1, e->verbose); space_parts_sort(s->parts, s->xparts, dest, &counts[nodeID * nr_nodes],
nr_nodes, 0);
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
/* Verify that the part have been sorted correctly. */ /* Verify that the part have been sorted correctly. */
...@@ -656,7 +657,8 @@ void engine_redistribute(struct engine *e) { ...@@ -656,7 +657,8 @@ void engine_redistribute(struct engine *e) {
/* Sort the particles according to their cell index. */ /* Sort the particles according to their cell index. */
if (s->nr_sparts > 0) if (s->nr_sparts > 0)
space_sparts_sort(s, s_dest, s->nr_sparts, 0, nr_nodes - 1, e->verbose); space_sparts_sort(s->sparts, s_dest, &s_counts[nodeID * nr_nodes], nr_nodes,
0);
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
/* Verify that the spart have been sorted correctly. */ /* Verify that the spart have been sorted correctly. */
...@@ -748,7 +750,8 @@ void engine_redistribute(struct engine *e) { ...@@ -748,7 +750,8 @@ void engine_redistribute(struct engine *e) {
/* Sort the gparticles according to their cell index. */ /* Sort the gparticles according to their cell index. */
if (s->nr_gparts > 0) if (s->nr_gparts > 0)
space_gparts_sort(s, g_dest, s->nr_gparts, 0, nr_nodes - 1, e->verbose); space_gparts_sort(s->gparts, s->parts, s->sparts, g_dest,
&g_counts[nodeID * nr_nodes], nr_nodes);
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
/* Verify that the gpart have been sorted correctly. */ /* Verify that the gpart have been sorted correctly. */
...@@ -3678,6 +3681,11 @@ void engine_rebuild(struct engine *e, int clean_smoothing_length_values) { ...@@ -3678,6 +3681,11 @@ void engine_rebuild(struct engine *e, int clean_smoothing_length_values) {
/* Re-build the space. */ /* Re-build the space. */
space_rebuild(e->s, e->verbose); space_rebuild(e->s, e->verbose);
#ifdef SWIFT_DEBUG_CHECKS
part_verify_links(e->s->parts, e->s->gparts, e->s->sparts, e->s->nr_parts,
e->s->nr_gparts, e->s->nr_sparts, e->verbose);
#endif
/* Initial cleaning up session ? */ /* Initial cleaning up session ? */
if (clean_smoothing_length_values) space_sanitize(e->s); if (clean_smoothing_length_values) space_sanitize(e->s);
...@@ -4151,7 +4159,7 @@ void engine_first_init_particles(struct engine *e) { ...@@ -4151,7 +4159,7 @@ void engine_first_init_particles(struct engine *e) {
const ticks tic = getticks(); const ticks tic = getticks();
/* Set the particles in a state where they are ready for a run */ /* Set the particles in a state where they are ready for a run. */
space_first_init_parts(e->s, e->chemistry, e->cooling_func); space_first_init_parts(e->s, e->chemistry, e->cooling_func);
space_first_init_gparts(e->s, e->gravity_properties); space_first_init_gparts(e->s, e->gravity_properties);
space_first_init_sparts(e->s); space_first_init_sparts(e->s);
......
...@@ -94,6 +94,26 @@ void part_relink_sparts_to_gparts(struct gpart *gparts, size_t N, ...@@ -94,6 +94,26 @@ void part_relink_sparts_to_gparts(struct gpart *gparts, size_t N,
} }
} }
/**
* @brief Re-link both the #part%s and #spart%s associated with the list of
* #gpart%s.
*
* @param gparts The list of #gpart.
* @param N The number of particles to re-link;
* @param parts The global #part array in which to find the #gpart offsets.
* @param sparts The global #spart array in which to find the #gpart offsets.
*/
void part_relink_all_parts_to_gparts(struct gpart *gparts, size_t N,
struct part *parts, struct spart *sparts) {
for (size_t k = 0; k < N; k++) {
if (gparts[k].type == swift_type_gas) {
parts[-gparts[k].id_or_neg_offset].gpart = &gparts[k];
} else if (gparts[k].type == swift_type_star) {
sparts[-gparts[k].id_or_neg_offset].gpart = &gparts[k];
}
}
}
/** /**
* @brief Verifies that the #gpart, #part and #spart are correctly linked * @brief Verifies that the #gpart, #part and #spart are correctly linked
* together * together
...@@ -128,19 +148,19 @@ void part_verify_links(struct part *parts, struct gpart *gparts, ...@@ -128,19 +148,19 @@ void part_verify_links(struct part *parts, struct gpart *gparts,
/* Check that it is linked */ /* Check that it is linked */
if (gparts[k].id_or_neg_offset > 0) if (gparts[k].id_or_neg_offset > 0)
error("Gas gpart not linked to anything !"); error("Gas gpart not linked to anything!");
/* Find its link */ /* Find its link */
const struct part *part = &parts[-gparts[k].id_or_neg_offset]; const struct part *part = &parts[-gparts[k].id_or_neg_offset];
/* Check the reverse link */ /* Check the reverse link */
if (part->gpart != &gparts[k]) error("Linking problem !"); if (part->gpart != &gparts[k]) error("Linking problem!");
/* Check that the particles are at the same place */ /* Check that the particles are at the same place */
if (gparts[k].x[0] != part->x[0] || gparts[k].x[1] != part->x[1] || if (gparts[k].x[0] != part->x[0] || gparts[k].x[1] != part->x[1] ||
gparts[k].x[2] != part->x[2]) gparts[k].x[2] != part->x[2])
error( error(
"Linked particles are not at the same position !\n" "Linked particles are not at the same position!\n"
"gp->x=[%e %e %e] p->x=[%e %e %e] diff=[%e %e %e]", "gp->x=[%e %e %e] p->x=[%e %e %e] diff=[%e %e %e]",
gparts[k].x[0], gparts[k].x[1], gparts[k].x[2], part->x[0], gparts[k].x[0], gparts[k].x[1], gparts[k].x[2], part->x[0],
part->x[1], part->x[2], gparts[k].x[0] - part->x[0], part->x[1], part->x[2], gparts[k].x[0] - part->x[0],
......
...@@ -80,6 +80,8 @@ void part_relink_parts_to_gparts(struct gpart *gparts, size_t N, ...@@ -80,6 +80,8 @@ void part_relink_parts_to_gparts(struct gpart *gparts, size_t N,
struct part *parts); struct part *parts);
void part_relink_sparts_to_gparts(struct gpart *gparts, size_t N, void part_relink_sparts_to_gparts(struct gpart *gparts, size_t N,
struct spart *sparts); struct spart *sparts);
void part_relink_all_parts_to_gparts(struct gpart *gparts, size_t N,
struct part *parts, struct spart *sparts);
void part_verify_links(struct part *parts, struct gpart *gparts, void part_verify_links(struct part *parts, struct gpart *gparts,
struct spart *sparts, size_t nr_parts, size_t nr_gparts, struct spart *sparts, size_t nr_parts, size_t nr_gparts,
size_t nr_sparts, int verbose); size_t nr_sparts, int verbose);
......
...@@ -101,6 +101,7 @@ struct index_data { ...@@ -101,6 +101,7 @@ struct index_data {
struct space *s; struct space *s;
struct cell *cells; struct cell *cells;
int *ind; int *ind;
int *cell_counts;
}; };
/** /**
...@@ -580,26 +581,33 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -580,26 +581,33 @@ void space_rebuild(struct space *s, int verbose) {
an index that is larger than the number of particles to avoid an index that is larger than the number of particles to avoid
re-allocating after shuffling. */ re-allocating after shuffling. */
const size_t ind_size = s->size_parts + 100; const size_t ind_size = s->size_parts + 100;
int *ind; int *ind = (int *)malloc(sizeof(int) * ind_size);
if ((ind = (int *)malloc(sizeof(int) * ind_size)) == NULL) if (ind == NULL) error("Failed to allocate temporary particle indices.");
error("Failed to allocate temporary particle indices."); int *cell_part_counts = (int *)calloc(sizeof(int), s->nr_cells);
if (s->size_parts > 0) space_parts_get_cell_index(s, ind, cells_top, verbose); if (cell_part_counts == NULL)
error("Failed to allocate cell part count buffer.");
if (s->size_parts > 0)
space_parts_get_cell_index(s, ind, cell_part_counts, cells_top, verbose);
/* Run through the gravity particles and get their cell index. */ /* Run through the gravity particles and get their cell index. */
const size_t gind_size = s->size_gparts + 100; const size_t gind_size = s->size_gparts + 100;
int *gind; int *gind = (int *)malloc(sizeof(int) * gind_size);
if ((gind = (int *)malloc(sizeof(int) * gind_size)) == NULL) if (gind == NULL) error("Failed to allocate temporary g-particle indices.");
error("Failed to allocate temporary g-particle indices."); int *cell_gpart_counts = (int *)calloc(sizeof(int), s->nr_cells);
if (cell_gpart_counts == NULL)
error("Failed to allocate cell gpart count buffer.");
if (s->size_gparts > 0) if (s->size_gparts > 0)
space_gparts_get_cell_index(s, gind, cells_top, verbose); space_gparts_get_cell_index(s, gind, cell_gpart_counts, cells_top, verbose);
/* Run through the star particles and get their cell index. */ /* Run through the star particles and get their cell index. */
const size_t sind_size = s->size_sparts + 100; const size_t sind_size = s->size_sparts + 100;
int *sind; int *sind = (int *)malloc(sizeof(int) * sind_size);
if ((sind = (int *)malloc(sizeof(int) * sind_size)) == NULL) if (sind == NULL) error("Failed to allocate temporary s-particle indices.");
error("Failed to allocate temporary s-particle indices."); int *cell_spart_counts = (int *)calloc(sizeof(int), s->nr_cells);
if (cell_spart_counts == NULL)
error("Failed to allocate cell gpart count buffer.");
if (s->size_sparts > 0) if (s->size_sparts > 0)
space_sparts_get_cell_index(s, sind, cells_top, verbose); space_sparts_get_cell_index(s, sind, cell_spart_counts, cells_top, verbose);
#ifdef WITH_MPI #ifdef WITH_MPI
const int local_nodeID = s->e->nodeID; const int local_nodeID = s->e->nodeID;
...@@ -609,9 +617,7 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -609,9 +617,7 @@ void space_rebuild(struct space *s, int verbose) {
if (cells_top[ind[k]].nodeID != local_nodeID) { if (cells_top[ind[k]].nodeID != local_nodeID) {
nr_parts -= 1; nr_parts -= 1;
/* Swap the particle */ /* Swap the particle */
const struct part tp = s->parts[k]; memswap(&s->parts[k], &s->parts[nr_parts], sizeof(struct part));
s->parts[k] = s->parts[nr_parts];
s->parts[nr_parts] = tp;
/* Swap the link with the gpart */ /* Swap the link with the gpart */
if (s->parts[k].gpart != NULL) { if (s->parts[k].gpart != NULL) {
s->parts[k].gpart->id_or_neg_offset = -k; s->parts[k].gpart->id_or_neg_offset = -k;
...@@ -620,13 +626,9 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -620,13 +626,9 @@ void space_rebuild(struct space *s, int verbose) {
s->parts[nr_parts].gpart->id_or_neg_offset = -nr_parts; s->parts[nr_parts].gpart->id_or_neg_offset = -nr_parts;
} }
/* Swap the xpart */ /* Swap the xpart */
const struct xpart txp = s->xparts[k]; memswap(&s->xparts[k], &s->xparts[nr_parts], sizeof(struct xpart));
s->xparts[k] = s->xparts[nr_parts];
s->xparts[nr_parts] = txp;
/* Swap the index */ /* Swap the index */
const int t = ind[k]; memswap(&ind[k], &ind[nr_parts], sizeof(int));
ind[k] = ind[nr_parts];
ind[nr_parts] = t;
} else { } else {
/* Increment when not exchanging otherwise we need to retest "k".*/ /* Increment when not exchanging otherwise we need to retest "k".*/
k++; k++;
...@@ -652,9 +654,7 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -652,9 +654,7 @@ void space_rebuild(struct space *s, int verbose) {
if (cells_top[sind[k]].nodeID != local_nodeID) { if (cells_top[sind[k]].nodeID != local_nodeID) {
nr_sparts -= 1; nr_sparts -= 1;
/* Swap the particle */ /* Swap the particle */
const struct spart tp = s->sparts[k]; memswap(&s->sparts[k], &s->sparts[nr_sparts], sizeof(struct spart));
s->sparts[k] = s->sparts[nr_sparts];
s->sparts[nr_sparts] = tp;
/* Swap the link with the gpart */ /* Swap the link with the gpart */
if (s->sparts[k].gpart != NULL) { if (s->sparts[k].gpart != NULL) {
s->sparts[k].gpart->id_or_neg_offset = -k; s->sparts[k].gpart->id_or_neg_offset = -k;
...@@ -663,9 +663,7 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -663,9 +663,7 @@ void space_rebuild(struct space *s, int verbose) {
s->sparts[nr_sparts].gpart->id_or_neg_offset = -nr_sparts; s->sparts[nr_sparts].gpart->id_or_neg_offset = -nr_sparts;
} }
/* Swap the index */ /* Swap the index */
const int t = sind[k]; memswap(&sind[k], &sind[nr_sparts], sizeof(int));
sind[k] = sind[nr_sparts];
sind[nr_sparts] = t;
} else { } else {
/* Increment when not exchanging otherwise we need to retest "k".*/ /* Increment when not exchanging otherwise we need to retest "k".*/
k++; k++;
...@@ -691,9 +689,7 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -691,9 +689,7 @@ void space_rebuild(struct space *s, int verbose) {
if (cells_top[gind[k]].nodeID != local_nodeID) { if (cells_top[gind[k]].nodeID != local_nodeID) {
nr_gparts -= 1; nr_gparts -= 1;
/* Swap the particle */ /* Swap the particle */
const struct gpart tp = s->gparts[k]; memswap(&s->gparts[k], &s->gparts[nr_gparts], sizeof(struct gpart));
s->gparts[k] = s->gparts[nr_gparts];
s->gparts[nr_gparts] = tp;
/* Swap the link with part/spart */ /* Swap the link with part/spart */
if (s->gparts[k].type == swift_type_gas) { if (s->gparts[k].type == swift_type_gas) {
s->parts[-s->gparts[k].id_or_neg_offset].gpart = &s->gparts[k]; s->parts[-s->gparts[k].id_or_neg_offset].gpart = &s->gparts[k];
...@@ -708,9 +704,7 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -708,9 +704,7 @@ void space_rebuild(struct space *s, int verbose) {
&s->gparts[nr_gparts]; &s->gparts[nr_gparts];
} }
/* Swap the index */ /* Swap the index */
const int t = gind[k]; memswap(&gind[k], &gind[nr_gparts], sizeof(int));
gind[k] = gind[nr_gparts];
gind[nr_gparts] = t;
} else { } else {
/* Increment when not exchanging otherwise we need to retest "k".*/ /* Increment when not exchanging otherwise we need to retest "k".*/
k++; k++;
...@@ -745,6 +739,15 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -745,6 +739,15 @@ void space_rebuild(struct space *s, int verbose) {
s->nr_gparts = nr_gparts + nr_gparts_exchanged; s->nr_gparts = nr_gparts + nr_gparts_exchanged;
s->nr_sparts = nr_sparts + nr_sparts_exchanged; s->nr_sparts = nr_sparts + nr_sparts_exchanged;
/* Clear non-local cell counts. */
for (int k = 0; k < s->nr_cells; k++) {
if (s->cells_top[k].nodeID != local_nodeID) {
cell_part_counts[k] = 0;
cell_spart_counts[k] = 0;
cell_gpart_counts[k] = 0;
}
}
/* Re-allocate the index array for the parts if needed.. */ /* Re-allocate the index array for the parts if needed.. */
if (s->nr_parts + 1 > ind_size) { if (s->nr_parts + 1 > ind_size) {
int *ind_new; int *ind_new;
...@@ -773,6 +776,7 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -773,6 +776,7 @@ void space_rebuild(struct space *s, int verbose) {
const struct part *const p = &s->parts[k]; const struct part *const p = &s->parts[k];
ind[k] = ind[k] =
cell_getid(cdim, p->x[0] * ih[0], p->x[1] * ih[1], p->x[2] * ih[2]); cell_getid(cdim, p->x[0] * ih[0], p->x[1] * ih[1], p->x[2] * ih[2]);
cell_part_counts[ind[k]]++;
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
if (cells_top[ind[k]].nodeID != local_nodeID) if (cells_top[ind[k]].nodeID != local_nodeID)
error("Received part that does not belong to me (nodeID=%i).", error("Received part that does not belong to me (nodeID=%i).",
...@@ -786,6 +790,7 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -786,6 +790,7 @@ void space_rebuild(struct space *s, int verbose) {
const struct spart *const sp = &s->sparts[k]; const struct spart *const sp = &s->sparts[k];
sind[k] = sind[k] =
cell_getid(cdim, sp->x[0] * ih[0], sp->x[1] * ih[1], sp->x[2] * ih[2]); cell_getid(cdim, sp->x[0] * ih[0], sp->x[1] * ih[1], sp->x[2] * ih[2]);
cell_spart_counts[sind[k]]++;
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
if (cells_top[sind[k]].nodeID != local_nodeID) if (cells_top[sind[k]].nodeID != local_nodeID)
error("Received s-part that does not belong to me (nodeID=%i).", error("Received s-part that does not belong to me (nodeID=%i).",
...@@ -794,11 +799,12 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -794,11 +799,12 @@ void space_rebuild(struct space *s, int verbose) {
} }
nr_sparts = s->nr_sparts; nr_sparts = s->nr_sparts;
#endif /* WITH_MPI */ #endif // WITH_MPI
/* Sort the parts according to their cells. */ /* Sort the parts according to their cells. */
if (nr_parts > 0) if (nr_parts > 0)
space_parts_sort(s, ind, nr_parts, 0, s->nr_cells - 1, verbose); space_parts_sort(s->parts, s->xparts, ind, cell_part_counts, s->nr_cells,
0);
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
/* Verify that the part have been sorted correctly. */ /* Verify that the part have been sorted correctly. */
...@@ -825,7 +831,7 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -825,7 +831,7 @@ void space_rebuild(struct space *s, int verbose) {
/* Sort the sparts according to their cells. */ /* Sort the sparts according to their cells. */
if (nr_sparts > 0) if (nr_sparts > 0)
space_sparts_sort(s, sind, nr_sparts, 0, s->nr_cells - 1, verbose); space_sparts_sort(s->sparts, sind, cell_spart_counts, s->nr_cells, 0);
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
/* Verify that the spart have been sorted correctly. */ /* Verify that the spart have been sorted correctly. */
...@@ -850,12 +856,6 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -850,12 +856,6 @@ void space_rebuild(struct space *s, int verbose) {
} }
#endif #endif
/* Re-link the gparts to their (s-)particles. */
if (nr_parts > 0 && nr_gparts > 0)
part_relink_gparts_to_parts(s->parts, nr_parts, 0);
if (nr_sparts > 0 && nr_gparts > 0)
part_relink_gparts_to_sparts(s->sparts, nr_sparts, 0);
/* Extract the cell counts from the sorted indices. */ /* Extract the cell counts from the sorted indices. */
size_t last_index = 0; size_t last_index = 0;
ind[nr_parts] = s->nr_cells; // sentinel. ind[nr_parts] = s->nr_cells; // sentinel.
...@@ -878,7 +878,9 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -878,7 +878,9 @@ void space_rebuild(struct space *s, int verbose) {
/* We no longer need the indices as of here. */ /* We no longer need the indices as of here. */
free(ind); free(ind);
free(cell_part_counts);
free(sind); free(sind);
free(cell_spart_counts);
#ifdef WITH_MPI #ifdef WITH_MPI
...@@ -897,7 +899,7 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -897,7 +899,7 @@ void space_rebuild(struct space *s, int verbose) {
const struct gpart *const p = &s->gparts[k]; const struct gpart *const p = &s->gparts[k];
gind[k] = gind[k] =
cell_getid(cdim, p->x[0] * ih[0], p->x[1] * ih[1], p->x[2] * ih[2]); cell_getid(cdim, p->x[0] * ih[0], p->x[1] * ih[1], p->x[2] * ih[2]);
cell_gpart_counts[gind[k]]++;
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
if (cells_top[gind[k]].nodeID != s->e->nodeID) if (cells_top[gind[k]].nodeID != s->e->nodeID)
error("Received g-part that does not belong to me (nodeID=%i).", error("Received g-part that does not belong to me (nodeID=%i).",
...@@ -906,11 +908,12 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -906,11 +908,12 @@ void space_rebuild(struct space *s, int verbose) {
} }
nr_gparts = s->nr_gparts; nr_gparts = s->nr_gparts;
#endif /* WITH_MPI */ #endif // WITH_MPI
/* Sort the gparts according to their cells. */ /* Sort the gparts according to their cells. */
if (nr_gparts > 0) if (nr_gparts > 0)
space_gparts_sort(s, gind, nr_gparts, 0, s->nr_cells - 1, verbose); space_gparts_sort(s->gparts, s->parts, s->sparts, gind, cell_gpart_counts,
s->nr_cells);
#ifdef SWIFT_DEBUG_CHECKS #ifdef SWIFT_DEBUG_CHECKS
/* Verify that the gpart have been sorted correctly. */ /* Verify that the gpart have been sorted correctly. */
...@@ -935,14 +938,6 @@ void space_rebuild(struct space *s, int verbose) { ...@@ -935,14 +938,6 @@ void space_rebuild(struct space *s, int verbose) {
} }
#endif #endif
/* Re-link the parts. */
if (nr_parts > 0 && nr_gparts > 0)
part_relink_parts_to_gparts(s->gparts, nr_gparts, s->parts);
/* Re-link the sparts. */
if (nr_sparts > 0 && nr_gparts > 0)
part_relink_sparts_to_gparts(s->gparts, nr_gparts, s->sparts);
/* Extract the cell counts from the sorted indices. */ /* Extract the cell counts from the sorted indices. */
</