From 4878243489a884ecea4ce61b5de3025e97bdc057 Mon Sep 17 00:00:00 2001
From: "Peter W. Draper"
Date: Mon, 17 Jul 2017 14:01:19 +0100
Subject: [PATCH 1/3] Add checks for particles that are at same position, this
isn't allowed, and update the cell h_max to that of the particles after the
initial ghost tasks have ran. This is needed before regridding if the h
values of the particles in the IC are set to be smaller than reality (ends up
looking like rebuilding failed as the particles are too far outside their
cells).
---
src/engine.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/src/engine.c b/src/engine.c
index 2680080ee..2b6f0f2f4 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -3359,6 +3359,38 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs,
/* Recover the (integer) end of the next time-step */
engine_collect_timestep_and_rebuild(e, 1);
+ /* Check if any particles have the same position and see if we need to
+ * correct the cell h_max to match possible particle updates in the ghost
+ * tasks. */
+ if (s->cells_top != NULL) {
+
+ /* Sorting should put the same positions next to each other... */
+ int failed = 0;
+ double *prev_x = s->parts[0].x;
+ for (size_t k = 1; k < s->nr_parts; k++) {
+ if (prev_x[0] == s->parts[k].x[0] &&
+ prev_x[1] == s->parts[k].x[1] &&
+ prev_x[2] == s->parts[k].x[2]) {
+ message("Two particles occupy location: %f %f %f",
+ prev_x[0], prev_x[1], prev_x[2]);
+ failed = 1;
+ }
+ prev_x = s->parts[k].x;
+ }
+ if (failed)
+ error("Cannot have particles with the same positions");
+
+ for (int i = 0; i < s->nr_cells; i++) {
+ struct cell *c = &s->cells_top[i];
+ if (c->nodeID == engine_rank) {
+ float part_h_max = c->parts[0].h;
+ for (int k = 1; k < c->count; k++) {
+ if (c->parts[k].h > part_h_max) part_h_max = c->parts[k].h;
+ }
+ c->h_max = max(part_h_max, c->h_max);
+ }
+ }
+ }
clocks_gettime(&time2);
#ifdef SWIFT_DEBUG_CHECKS
--
GitLab
From cfd96b505503a284338c22d98738d47109b4700d Mon Sep 17 00:00:00 2001
From: "Peter W. Draper"
Date: Mon, 17 Jul 2017 17:08:31 +0100
Subject: [PATCH 2/3] Clarify some comments on this fix
---
src/engine.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/engine.c b/src/engine.c
index 2b6f0f2f4..351f398ae 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -3360,9 +3360,10 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs,
engine_collect_timestep_and_rebuild(e, 1);
/* Check if any particles have the same position and see if we need to
- * correct the cell h_max to match possible particle updates in the ghost
- * tasks. */
- if (s->cells_top != NULL) {
+ * correct the top-level cell h_max to match possible particle updates in
+ * the ghost tasks. Note this must be followed by a rebuild as sub-cells
+ * will not be updated until that is done. */
+ if (s->cells_top != NULL && s->nr_parts > 0) {
/* Sorting should put the same positions next to each other... */
int failed = 0;
@@ -3378,7 +3379,7 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs,
prev_x = s->parts[k].x;
}
if (failed)
- error("Cannot have particles with the same positions");
+ error("Cannot have particles with the same locations");
for (int i = 0; i < s->nr_cells; i++) {
struct cell *c = &s->cells_top[i];
--
GitLab
From eef6e5de546eb71a395199fd7cdddde4d4d100e1 Mon Sep 17 00:00:00 2001
From: "Peter W. Draper"
Date: Tue, 18 Jul 2017 16:51:57 +0100
Subject: [PATCH 3/3] Check gparts for the same locations as well as parts.
We allow gparts to share locations as that will work, unlike parts (but these may as well be merged, unless they are stars)
Also reduce the verbosity of the reports
---
src/engine.c | 48 ++++++++++++++++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 10 deletions(-)
diff --git a/src/engine.c b/src/engine.c
index 030a724be..993c6fe49 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -3360,11 +3360,9 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs,
/* Recover the (integer) end of the next time-step */
engine_collect_timestep_and_rebuild(e, 1);
- /* Check if any particles have the same position and see if we need to
- * correct the top-level cell h_max to match possible particle updates in
- * the ghost tasks. Note this must be followed by a rebuild as sub-cells
- * will not be updated until that is done. */
- if (s->cells_top != NULL && s->nr_parts > 0) {
+ /* Check if any particles have the same position. This is not
+ * allowed (/0) so we abort.*/
+ if (s->nr_parts > 0) {
/* Sorting should put the same positions next to each other... */
int failed = 0;
@@ -3373,15 +3371,44 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs,
if (prev_x[0] == s->parts[k].x[0] &&
prev_x[1] == s->parts[k].x[1] &&
prev_x[2] == s->parts[k].x[2]) {
- message("Two particles occupy location: %f %f %f",
- prev_x[0], prev_x[1], prev_x[2]);
- failed = 1;
+ if (e->verbose)
+ message("Two particles occupy location: %f %f %f",
+ prev_x[0], prev_x[1], prev_x[2]);
+ failed++;
}
prev_x = s->parts[k].x;
}
- if (failed)
- error("Cannot have particles with the same locations");
+ if (failed > 0)
+ error("Have %d particle pairs with the same locations.\n"
+ "Cannot continue", failed);
+ }
+
+ /* Also check any gparts. This is not supposed to be fatal so only warn. */
+ if (s->nr_gparts > 0) {
+ int failed = 0;
+ double *prev_x = s->gparts[0].x;
+ for (size_t k = 1; k < s->nr_gparts; k++) {
+ if (prev_x[0] == s->gparts[k].x[0] &&
+ prev_x[1] == s->gparts[k].x[1] &&
+ prev_x[2] == s->gparts[k].x[2]) {
+ if (e->verbose)
+ message("Two gparts occupy location: %f %f %f / %f %f %f",
+ prev_x[0], prev_x[1], prev_x[2],
+ s->gparts[k].x[0], s->gparts[k].x[1], s->gparts[k].x[2] );
+ failed++;
+ }
+ prev_x = s->gparts[k].x;
+ }
+ if (failed > 0)
+ message("WARNING: found %d gpart pairs at the same location. "
+ "That is not optimal", failed);
+ }
+ /* Check the top-level cell h_max matches the particles as these can be
+ * updated in the the ghost tasks (only a problem if the ICs estimates for h
+ * are too small). Note this must be followed by a rebuild as sub-cells will
+ * not be updated until that is done. */
+ if (s->cells_top != NULL && s->nr_parts > 0) {
for (int i = 0; i < s->nr_cells; i++) {
struct cell *c = &s->cells_top[i];
if (c->nodeID == engine_rank) {
@@ -3393,6 +3420,7 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs,
}
}
}
+
clocks_gettime(&time2);
#ifdef SWIFT_DEBUG_CHECKS
--
GitLab