space.c 208 KB
Newer Older
1
/*******************************************************************************
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 * This file is part of SWIFT.
 * Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
 *                    Matthieu Schaller (matthieu.schaller@durham.ac.uk)
 *               2015 Peter W. Draper (p.w.draper@durham.ac.uk)
 *               2016 John A. Regan (john.a.regan@durham.ac.uk)
 *                    Tom Theuns (tom.theuns@durham.ac.uk)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/
Pedro Gonnet's avatar
Pedro Gonnet committed
23
24
25
26
27
28
29
30

/* Config parameters. */
#include "../config.h"

/* Some standard headers. */
#include <float.h>
#include <limits.h>
#include <math.h>
31
#include <stdlib.h>
32
#include <string.h>
Pedro Gonnet's avatar
Pedro Gonnet committed
33

34
35
/* MPI headers. */
#ifdef WITH_MPI
36
#include <mpi.h>
37
38
#endif

39
40
41
/* This object's header. */
#include "space.h"

Pedro Gonnet's avatar
Pedro Gonnet committed
42
/* Local headers. */
43
#include "atomic.h"
44
#include "black_holes.h"
45
#include "chemistry.h"
46
#include "const.h"
47
#include "cooling.h"
48
#include "debug.h"
49
#include "engine.h"
50
#include "error.h"
51
52
#include "gravity.h"
#include "hydro.h"
53
#include "kernel_hydro.h"
54
#include "lock.h"
55
#include "memswap.h"
56
#include "memuse.h"
57
#include "minmax.h"
58
#include "multipole.h"
59
#include "pressure_floor.h"
60
#include "proxy.h"
61
#include "restart.h"
62
#include "sort_part.h"
Loic Hausammann's avatar
Loic Hausammann committed
63
#include "space_unique_id.h"
64
#include "star_formation.h"
65
#include "star_formation_logger.h"
Loic Hausammann's avatar
Format    
Loic Hausammann committed
66
#include "stars.h"
67
#include "threadpool.h"
68
#include "tools.h"
69
#include "tracers.h"
Pedro Gonnet's avatar
Pedro Gonnet committed
70
71
72

/* Split size. */
int space_splitsize = space_splitsize_default;
73
74
int space_subsize_pair_hydro = space_subsize_pair_hydro_default;
int space_subsize_self_hydro = space_subsize_self_hydro_default;
75
76
int space_subsize_pair_stars = space_subsize_pair_stars_default;
int space_subsize_self_stars = space_subsize_self_stars_default;
77
int space_subsize_pair_grav = space_subsize_pair_grav_default;
78
int space_subsize_self_grav = space_subsize_self_grav_default;
79
int space_subdepth_diff_grav = space_subdepth_diff_grav_default;
80
int space_maxsize = space_maxsize_default;
81

82
83
84
/*! Number of extra #part we allocate memory for per top-level cell */
int space_extra_parts = space_extra_parts_default;

85
86
87
/*! Number of extra #spart we allocate memory for per top-level cell */
int space_extra_sparts = space_extra_sparts_default;

88
89
90
/*! Number of extra #bpart we allocate memory for per top-level cell */
int space_extra_bparts = space_extra_bparts_default;

91
92
93
/*! Number of extra #gpart we allocate memory for per top-level cell */
int space_extra_gparts = space_extra_gparts_default;

94
95
96
97
/*! Maximum number of particles per ghost */
int engine_max_parts_per_ghost = engine_max_parts_per_ghost_default;
int engine_max_sparts_per_ghost = engine_max_sparts_per_ghost_default;

98
/*! Maximal depth at which the stars resort task can be pushed */
99
int engine_star_resort_task_depth = engine_star_resort_task_depth_default;
100

101
102
/*! Expected maximal number of strays received at a rebuild */
int space_expected_max_nr_strays = space_expected_max_nr_strays_default;
Loic Hausammann's avatar
Loic Hausammann committed
103
#if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH)
104
105
int last_cell_id;
#endif
Pedro Gonnet's avatar
Pedro Gonnet committed
106

107
108
109
110
111
112
113
114
115
/**
 * @brief Interval stack necessary for parallel particle sorting.
 */
struct qstack {
  volatile ptrdiff_t i, j;
  volatile int min, max;
  volatile int ready;
};

116
117
118
119
120
121
/**
 * @brief Information required to compute the particle cell indices.
 */
struct index_data {
  struct space *s;
  int *ind;
122
  int *cell_counts;
123
124
125
  size_t count_inhibited_part;
  size_t count_inhibited_gpart;
  size_t count_inhibited_spart;
126
  size_t count_inhibited_bpart;
127
128
129
  size_t count_extra_part;
  size_t count_extra_gpart;
  size_t count_extra_spart;
130
  size_t count_extra_bpart;
131
132
};

133
/**
134
 * @brief Recursively dismantle a cell tree.
135
 *
136
137
 * @param s The #space.
 * @param c The #cell to recycle.
Matthieu Schaller's avatar
Matthieu Schaller committed
138
139
140
141
142
143
 * @param cell_rec_begin Pointer to the start of the list of cells to recycle.
 * @param cell_rec_end Pointer to the end of the list of cells to recycle.
 * @param multipole_rec_begin Pointer to the start of the list of multipoles to
 * recycle.
 * @param multipole_rec_end Pointer to the end of the list of multipoles to
 * recycle.
144
 */
145
void space_rebuild_recycle_rec(struct space *s, struct cell *c,
146
147
                               struct cell **cell_rec_begin,
                               struct cell **cell_rec_end,
148
149
                               struct gravity_tensors **multipole_rec_begin,
                               struct gravity_tensors **multipole_rec_end) {
150
  if (c->split)
151
    for (int k = 0; k < 8; k++)
152
      if (c->progeny[k] != NULL) {
153
154
155
156
157
158
        space_rebuild_recycle_rec(s, c->progeny[k], cell_rec_begin,
                                  cell_rec_end, multipole_rec_begin,
                                  multipole_rec_end);

        c->progeny[k]->next = *cell_rec_begin;
        *cell_rec_begin = c->progeny[k];
159

160
        if (s->with_self_gravity) {
161
162
          c->progeny[k]->grav.multipole->next = *multipole_rec_begin;
          *multipole_rec_begin = c->progeny[k]->grav.multipole;
163
        }
164
165

        if (*cell_rec_end == NULL) *cell_rec_end = *cell_rec_begin;
166
        if (s->with_self_gravity && *multipole_rec_end == NULL)
167
168
          *multipole_rec_end = *multipole_rec_begin;

169
        c->progeny[k]->grav.multipole = NULL;
170
171
172
173
        c->progeny[k] = NULL;
      }
}

174
175
176
177
178
179
180
181
void space_rebuild_recycle_mapper(void *map_data, int num_elements,
                                  void *extra_data) {

  struct space *s = (struct space *)extra_data;
  struct cell *cells = (struct cell *)map_data;

  for (int k = 0; k < num_elements; k++) {
    struct cell *c = &cells[k];
182
    struct cell *cell_rec_begin = NULL, *cell_rec_end = NULL;
183
184
    struct gravity_tensors *multipole_rec_begin = NULL,
                           *multipole_rec_end = NULL;
185
186
187
188
189
    space_rebuild_recycle_rec(s, c, &cell_rec_begin, &cell_rec_end,
                              &multipole_rec_begin, &multipole_rec_end);
    if (cell_rec_begin != NULL)
      space_recycle_list(s, cell_rec_begin, cell_rec_end, multipole_rec_begin,
                         multipole_rec_end);
190
    c->hydro.sorts = NULL;
Loic Hausammann's avatar
Loic Hausammann committed
191
    c->stars.sorts = NULL;
192
    c->nr_tasks = 0;
193
194
195
196
    c->grav.nr_mm_tasks = 0;
    c->hydro.density = NULL;
    c->hydro.gradient = NULL;
    c->hydro.force = NULL;
197
    c->hydro.limiter = NULL;
198
199
    c->grav.grav = NULL;
    c->grav.mm = NULL;
200
201
    c->hydro.dx_max_part = 0.0f;
    c->hydro.dx_max_sort = 0.0f;
Loic Hausammann's avatar
Loic Hausammann committed
202
    c->stars.dx_max_part = 0.f;
Loic Hausammann's avatar
Loic Hausammann committed
203
    c->stars.dx_max_sort = 0.f;
204
    c->black_holes.dx_max_part = 0.f;
205
    c->hydro.sorted = 0;
Matthieu Schaller's avatar
Matthieu Schaller committed
206
    c->hydro.sort_allocated = 0;
Loic Hausammann's avatar
Loic Hausammann committed
207
    c->stars.sorted = 0;
208
    c->hydro.count = 0;
209
    c->hydro.count_total = 0;
210
    c->hydro.updated = 0;
211
    c->grav.count = 0;
212
    c->grav.count_total = 0;
213
    c->grav.updated = 0;
214
    c->stars.count = 0;
215
    c->stars.count_total = 0;
216
    c->stars.updated = 0;
217
218
219
    c->black_holes.count = 0;
    c->black_holes.count_total = 0;
    c->black_holes.updated = 0;
220
221
222
223
224
225
    c->grav.init = NULL;
    c->grav.init_out = NULL;
    c->hydro.extra_ghost = NULL;
    c->hydro.ghost_in = NULL;
    c->hydro.ghost_out = NULL;
    c->hydro.ghost = NULL;
226
227
    c->hydro.star_formation = NULL;
    c->hydro.stars_resort = NULL;
228
229
    c->stars.ghost = NULL;
    c->stars.density = NULL;
Alexei Borissov's avatar
Alexei Borissov committed
230
    c->stars.feedback = NULL;
231
232
233
    c->black_holes.density_ghost = NULL;
    c->black_holes.swallow_ghost[0] = NULL;
    c->black_holes.swallow_ghost[1] = NULL;
234
    c->black_holes.swallow_ghost[2] = NULL;
235
    c->black_holes.density = NULL;
236
    c->black_holes.swallow = NULL;
237
238
    c->black_holes.do_gas_swallow = NULL;
    c->black_holes.do_bh_swallow = NULL;
239
    c->black_holes.feedback = NULL;
240
241
    c->kick1 = NULL;
    c->kick2 = NULL;
242
    c->timestep = NULL;
243
    c->timestep_limiter = NULL;
244
    c->timestep_sync = NULL;
245
    c->hydro.end_force = NULL;
246
    c->hydro.drift = NULL;
247
    c->stars.drift = NULL;
248
249
    c->stars.stars_in = NULL;
    c->stars.stars_out = NULL;
250
    c->black_holes.drift = NULL;
251
252
    c->black_holes.black_holes_in = NULL;
    c->black_holes.black_holes_out = NULL;
253
    c->grav.drift = NULL;
254
    c->grav.drift_out = NULL;
255
256
257
258
259
    c->hydro.cooling = NULL;
    c->grav.long_range = NULL;
    c->grav.down_in = NULL;
    c->grav.down = NULL;
    c->grav.mesh = NULL;
260
    c->grav.end_force = NULL;
261
    c->top = c;
262
    c->super = c;
263
264
265
266
    c->hydro.super = c;
    c->grav.super = c;
    c->hydro.parts = NULL;
    c->hydro.xparts = NULL;
267
    c->grav.parts = NULL;
268
    c->grav.parts_rebuild = NULL;
269
    c->stars.parts = NULL;
270
    c->stars.parts_rebuild = NULL;
271
    c->black_holes.parts = NULL;
272
    c->flags = 0;
273
274
275
276
    c->hydro.ti_end_min = -1;
    c->hydro.ti_end_max = -1;
    c->grav.ti_end_min = -1;
    c->grav.ti_end_max = -1;
Loic Hausammann's avatar
Loic Hausammann committed
277
    c->stars.ti_end_min = -1;
278
    c->stars.ti_end_max = -1;
279
280
    c->black_holes.ti_end_min = -1;
    c->black_holes.ti_end_max = -1;
281
    star_formation_logger_init(&c->stars.sfh);
Loic Hausammann's avatar
Loic Hausammann committed
282
#if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH)
283
284
    c->cellID = 0;
#endif
285
286
    if (s->with_self_gravity)
      bzero(c->grav.multipole, sizeof(struct gravity_tensors));
287

288
289
    cell_free_hydro_sorts(c);
    cell_free_stars_sorts(c);
290
#if WITH_MPI
291
    c->mpi.tag = -1;
292
    c->mpi.recv = NULL;
293
    c->mpi.send = NULL;
294
295
296
297
#endif
  }
}

298
299
/**
 * @brief Free up any allocated cells.
300
301
 *
 * @param s The #space.
302
303
 */
void space_free_cells(struct space *s) {
304
305
306

  ticks tic = getticks();

Matthieu Schaller's avatar
Matthieu Schaller committed
307
  threadpool_map(&s->e->threadpool, space_rebuild_recycle_mapper, s->cells_top,
308
309
                 s->nr_cells, sizeof(struct cell), threadpool_auto_chunk_size,
                 s);
310
  s->maxdepth = 0;
311
312
313
314

  if (s->e->verbose)
    message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
            clocks_getunit());
315
316
}

317
318
319
320
/**
 * @brief Free any memory in use for foreign particles.
 *
 * @param s The #space.
321
322
 * @param clear_cell_pointers Are we also setting all the foreign cell particle
 * pointers to NULL?
323
 */
324
void space_free_foreign_parts(struct space *s, const int clear_cell_pointers) {
325
326
327

#ifdef WITH_MPI
  if (s->parts_foreign != NULL) {
Peter W. Draper's avatar
Peter W. Draper committed
328
    swift_free("parts_foreign", s->parts_foreign);
329
330
331
332
    s->size_parts_foreign = 0;
    s->parts_foreign = NULL;
  }
  if (s->gparts_foreign != NULL) {
Peter W. Draper's avatar
Peter W. Draper committed
333
    swift_free("gparts_foreign", s->gparts_foreign);
334
335
336
337
    s->size_gparts_foreign = 0;
    s->gparts_foreign = NULL;
  }
  if (s->sparts_foreign != NULL) {
Peter W. Draper's avatar
Peter W. Draper committed
338
    swift_free("sparts_foreign", s->sparts_foreign);
339
340
341
    s->size_sparts_foreign = 0;
    s->sparts_foreign = NULL;
  }
342
343
344
345
346
  if (s->bparts_foreign != NULL) {
    swift_free("bparts_foreign", s->bparts_foreign);
    s->size_bparts_foreign = 0;
    s->bparts_foreign = NULL;
  }
347
348
349
350
351
352
353
  if (clear_cell_pointers) {
    for (int k = 0; k < s->e->nr_proxies; k++) {
      for (int j = 0; j < s->e->proxies[k].nr_cells_in; j++) {
        cell_unlink_foreign_particles(s->e->proxies[k].cells_in[j]);
      }
    }
  }
354
355
356
#endif
}

357
/**
358
 * @brief Re-build the top-level cell grid.
359
 *
360
 * @param s The #space.
361
 * @param verbose Print messages to stdout or not.
362
 */
363
void space_regrid(struct space *s, int verbose) {
364

365
  const size_t nr_parts = s->nr_parts;
Loic Hausammann's avatar
Loic Hausammann committed
366
  const size_t nr_sparts = s->nr_sparts;
367
  const size_t nr_bparts = s->nr_bparts;
368
  const ticks tic = getticks();
369
  const integertime_t ti_current = (s->e != NULL) ? s->e->ti_current : 0;
370

371
  /* Run through the cells and get the current h_max. */
372
  // tic = getticks();
373
  float h_max = s->cell_min / kernel_gamma / space_stretch;
374
  if (nr_parts > 0) {
375
376
377
378
379
380

    /* Can we use the list of local non-empty top-level cells? */
    if (s->local_cells_with_particles_top != NULL) {
      for (int k = 0; k < s->nr_local_cells_with_particles; ++k) {
        const struct cell *c =
            &s->cells_top[s->local_cells_with_particles_top[k]];
381
        if (c->hydro.h_max > h_max) {
382
          h_max = c->hydro.h_max;
383
        }
Loic Hausammann's avatar
Loic Hausammann committed
384
        if (c->stars.h_max > h_max) {
385
          h_max = c->stars.h_max;
Loic Hausammann's avatar
Loic Hausammann committed
386
        }
387
388
389
        if (c->black_holes.h_max > h_max) {
          h_max = c->black_holes.h_max;
        }
390
      }
391
392

      /* Can we instead use all the top-level cells? */
393
    } else if (s->cells_top != NULL) {
Tom Theuns's avatar
Tom Theuns committed
394
      for (int k = 0; k < s->nr_cells; k++) {
395
        const struct cell *c = &s->cells_top[k];
396
        if (c->nodeID == engine_rank && c->hydro.h_max > h_max) {
397
          h_max = c->hydro.h_max;
398
        }
Loic Hausammann's avatar
Loic Hausammann committed
399
        if (c->nodeID == engine_rank && c->stars.h_max > h_max) {
400
          h_max = c->stars.h_max;
Loic Hausammann's avatar
Loic Hausammann committed
401
        }
402
403
404
        if (c->nodeID == engine_rank && c->black_holes.h_max > h_max) {
          h_max = c->black_holes.h_max;
        }
405
      }
406
407

      /* Last option: run through the particles */
408
    } else {
409
      for (size_t k = 0; k < nr_parts; k++) {
Matthieu Schaller's avatar
Matthieu Schaller committed
410
        if (s->parts[k].h > h_max) h_max = s->parts[k].h;
411
      }
Loic Hausammann's avatar
Loic Hausammann committed
412
413
414
      for (size_t k = 0; k < nr_sparts; k++) {
        if (s->sparts[k].h > h_max) h_max = s->sparts[k].h;
      }
415
416
417
      for (size_t k = 0; k < nr_bparts; k++) {
        if (s->bparts[k].h > h_max) h_max = s->bparts[k].h;
      }
418
419
420
421
422
423
424
425
426
427
    }
  }

/* If we are running in parallel, make sure everybody agrees on
   how large the largest cell should be. */
#ifdef WITH_MPI
  {
    float buff;
    if (MPI_Allreduce(&h_max, &buff, 1, MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD) !=
        MPI_SUCCESS)
428
      error("Failed to aggregate the rebuild flag across nodes.");
429
430
431
    h_max = buff;
  }
#endif
432
  if (verbose) message("h_max is %.3e (cell_min=%.3e).", h_max, s->cell_min);
433
434

  /* Get the new putative cell dimensions. */
435
  const int cdim[3] = {
436
437
438
439
440
441
      (int)floor(s->dim[0] /
                 fmax(h_max * kernel_gamma * space_stretch, s->cell_min)),
      (int)floor(s->dim[1] /
                 fmax(h_max * kernel_gamma * space_stretch, s->cell_min)),
      (int)floor(s->dim[2] /
                 fmax(h_max * kernel_gamma * space_stretch, s->cell_min))};
442
443
444
445
446

  /* Check if we have enough cells for periodicity. */
  if (s->periodic && (cdim[0] < 3 || cdim[1] < 3 || cdim[2] < 3))
    error(
        "Must have at least 3 cells in each spatial dimension when periodicity "
447
448
449
        "is switched on.\nThis error is often caused by any of the "
        "followings:\n"
        " - too few particles to generate a sensible grid,\n"
450
451
        " - the initial value of 'Scheduler:max_top_level_cells' is too "
        "small,\n"
452
        " - the (minimal) time-step is too large leading to particles with "
453
        "predicted smoothing lengths too large for the box size,\n"
454
        " - particles with velocities so large that they move by more than two "
455
        "box sizes per time-step.\n");
456

457
458
459
/* In MPI-Land, changing the top-level cell size requires that the
 * global partition is recomputed and the particles redistributed.
 * Be prepared to do that. */
460
#ifdef WITH_MPI
Matthieu Schaller's avatar
Matthieu Schaller committed
461
  double oldwidth[3];
462
463
464
465
466
467
468
469
  double oldcdim[3];
  int *oldnodeIDs = NULL;
  if (cdim[0] < s->cdim[0] || cdim[1] < s->cdim[1] || cdim[2] < s->cdim[2]) {

    /* Capture state of current space. */
    oldcdim[0] = s->cdim[0];
    oldcdim[1] = s->cdim[1];
    oldcdim[2] = s->cdim[2];
470
471
472
    oldwidth[0] = s->width[0];
    oldwidth[1] = s->width[1];
    oldwidth[2] = s->width[2];
473

474
475
    if ((oldnodeIDs =
             (int *)swift_malloc("nodeIDs", sizeof(int) * s->nr_cells)) == NULL)
476
477
478
479
480
481
482
      error("Failed to allocate temporary nodeIDs.");

    int cid = 0;
    for (int i = 0; i < s->cdim[0]; i++) {
      for (int j = 0; j < s->cdim[1]; j++) {
        for (int k = 0; k < s->cdim[2]; k++) {
          cid = cell_getid(oldcdim, i, j, k);
483
          oldnodeIDs[cid] = s->cells_top[cid].nodeID;
484
485
486
487
488
        }
      }
    }
  }

Peter W. Draper's avatar
Peter W. Draper committed
489
  /* Are we about to allocate new top level cells without a regrid?
Peter W. Draper's avatar
Peter W. Draper committed
490
   * Can happen when restarting the application. */
491
  const int no_regrid = (s->cells_top == NULL && oldnodeIDs == NULL);
492
493
494
495
#endif

  /* Do we need to re-build the upper-level cells? */
  // tic = getticks();
496
  if (s->cells_top == NULL || cdim[0] < s->cdim[0] || cdim[1] < s->cdim[1] ||
497
498
      cdim[2] < s->cdim[2]) {

499
500
/* Be verbose about this. */
#ifdef SWIFT_DEBUG_CHECKS
501
    message("(re)griding space cdim=(%d %d %d)", cdim[0], cdim[1], cdim[2]);
502
503
504
    fflush(stdout);
#endif

505
    /* Free the old cells, if they were allocated. */
506
    if (s->cells_top != NULL) {
507
      space_free_cells(s);
508
509
510
      swift_free("local_cells_with_tasks_top", s->local_cells_with_tasks_top);
      swift_free("local_cells_top", s->local_cells_top);
      swift_free("cells_with_particles_top", s->cells_with_particles_top);
511
512
      swift_free("local_cells_with_particles_top",
                 s->local_cells_with_particles_top);
513
514
      swift_free("cells_top", s->cells_top);
      swift_free("multipoles_top", s->multipoles_top);
515
516
    }

517
518
519
520
    /* Also free the task arrays, these will be regenerated and we can use the
     * memory while copying the particle arrays. */
    if (s->e != NULL) scheduler_free_tasks(&s->e->sched);

521
    /* Set the new cell dimensions only if smaller. */
522
    for (int k = 0; k < 3; k++) {
523
      s->cdim[k] = cdim[k];
524
525
      s->width[k] = s->dim[k] / cdim[k];
      s->iwidth[k] = 1.0 / s->width[k];
526
    }
527
    const float dmin = min3(s->width[0], s->width[1], s->width[2]);
528
529
530

    /* Allocate the highest level of cells. */
    s->tot_cells = s->nr_cells = cdim[0] * cdim[1] * cdim[2];
531

532
    if (swift_memalign("cells_top", (void **)&s->cells_top, cell_align,
533
                       s->nr_cells * sizeof(struct cell)) != 0)
534
      error("Failed to allocate top-level cells.");
535
    bzero(s->cells_top, s->nr_cells * sizeof(struct cell));
536

537
    /* Allocate the multipoles for the top-level cells. */
538
    if (s->with_self_gravity) {
539
540
      if (swift_memalign("multipoles_top", (void **)&s->multipoles_top,
                         multipole_align,
541
                         s->nr_cells * sizeof(struct gravity_tensors)) != 0)
542
        error("Failed to allocate top-level multipoles.");
543
      bzero(s->multipoles_top, s->nr_cells * sizeof(struct gravity_tensors));
544
545
    }

546
    /* Allocate the indices of local cells */
547
548
    if (swift_memalign("local_cells_top", (void **)&s->local_cells_top,
                       SWIFT_STRUCT_ALIGNMENT, s->nr_cells * sizeof(int)) != 0)
549
550
551
      error("Failed to allocate indices of local top-level cells.");
    bzero(s->local_cells_top, s->nr_cells * sizeof(int));

552
    /* Allocate the indices of local cells with tasks */
553
554
    if (swift_memalign("local_cells_with_tasks_top",
                       (void **)&s->local_cells_with_tasks_top,
555
                       SWIFT_STRUCT_ALIGNMENT, s->nr_cells * sizeof(int)) != 0)
556
      error("Failed to allocate indices of local top-level cells with tasks.");
557
558
    bzero(s->local_cells_with_tasks_top, s->nr_cells * sizeof(int));

559
    /* Allocate the indices of cells with particles */
560
561
    if (swift_memalign("cells_with_particles_top",
                       (void **)&s->cells_with_particles_top,
562
                       SWIFT_STRUCT_ALIGNMENT, s->nr_cells * sizeof(int)) != 0)
563
564
      error("Failed to allocate indices of top-level cells with particles.");
    bzero(s->cells_with_particles_top, s->nr_cells * sizeof(int));
565

566
    /* Allocate the indices of local cells with particles */
567
568
    if (swift_memalign("local_cells_with_particles_top",
                       (void **)&s->local_cells_with_particles_top,
569
570
571
572
573
574
                       SWIFT_STRUCT_ALIGNMENT, s->nr_cells * sizeof(int)) != 0)
      error(
          "Failed to allocate indices of local top-level cells with "
          "particles.");
    bzero(s->local_cells_with_particles_top, s->nr_cells * sizeof(int));

575
    /* Set the cells' locks */
576
    for (int k = 0; k < s->nr_cells; k++) {
577
      if (lock_init(&s->cells_top[k].hydro.lock) != 0)
578
        error("Failed to init spinlock for hydro.");
579
      if (lock_init(&s->cells_top[k].grav.plock) != 0)
580
        error("Failed to init spinlock for gravity.");
581
      if (lock_init(&s->cells_top[k].grav.mlock) != 0)
582
        error("Failed to init spinlock for multipoles.");
Loic Hausammann's avatar
Loic Hausammann committed
583
584
      if (lock_init(&s->cells_top[k].grav.star_formation_lock) != 0)
        error("Failed to init spinlock for star formation (gpart).");
585
      if (lock_init(&s->cells_top[k].stars.lock) != 0)
586
        error("Failed to init spinlock for stars.");
Matthieu Schaller's avatar
Matthieu Schaller committed
587
588
      if (lock_init(&s->cells_top[k].black_holes.lock) != 0)
        error("Failed to init spinlock for black holes.");
589
      if (lock_init(&s->cells_top[k].stars.star_formation_lock) != 0)
Loic Hausammann's avatar
Loic Hausammann committed
590
        error("Failed to init spinlock for star formation (spart).");
591
    }
592
593

    /* Set the cell location and sizes. */
594
595
596
    for (int i = 0; i < cdim[0]; i++)
      for (int j = 0; j < cdim[1]; j++)
        for (int k = 0; k < cdim[2]; k++) {
597
598
          const size_t cid = cell_getid(cdim, i, j, k);
          struct cell *restrict c = &s->cells_top[cid];
599
600
601
602
603
604
          c->loc[0] = i * s->width[0];
          c->loc[1] = j * s->width[1];
          c->loc[2] = k * s->width[2];
          c->width[0] = s->width[0];
          c->width[1] = s->width[1];
          c->width[2] = s->width[2];
605
606
          c->dmin = dmin;
          c->depth = 0;
607
          c->split = 0;
608
          c->hydro.count = 0;
609
610
          c->grav.count = 0;
          c->stars.count = 0;
611
          c->top = c;
612
          c->super = c;
613
614
          c->hydro.super = c;
          c->grav.super = c;
615
616
          c->hydro.ti_old_part = ti_current;
          c->grav.ti_old_part = ti_current;
617
          c->stars.ti_old_part = ti_current;
618
          c->black_holes.ti_old_part = ti_current;
619
          c->grav.ti_old_multipole = ti_current;
Pedro Gonnet's avatar
Pedro Gonnet committed
620
#ifdef WITH_MPI
621
          c->mpi.tag = -1;
622
          c->mpi.recv = NULL;
623
          c->mpi.send = NULL;
Pedro Gonnet's avatar
Pedro Gonnet committed
624
#endif  // WITH_MPI
625
          if (s->with_self_gravity) c->grav.multipole = &s->multipoles_top[cid];
Loic Hausammann's avatar
Loic Hausammann committed
626
#if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH)
Matthieu Schaller's avatar
Matthieu Schaller committed
627
628
          c->cellID = -last_cell_id;
          last_cell_id++;
629
#endif
Pedro Gonnet's avatar
Pedro Gonnet committed
630
        }
631
632

    /* Be verbose about the change. */
633
634
635
    if (verbose)
      message("set cell dimensions to [ %i %i %i ].", cdim[0], cdim[1],
              cdim[2]);
636

637
#ifdef WITH_MPI
638
639
640
641
642
    if (oldnodeIDs != NULL) {
      /* We have changed the top-level cell dimension, so need to redistribute
       * cells around the nodes. We repartition using the old space node
       * positions as a grid to resample. */
      if (s->e->nodeID == 0)
643
644
645
        message(
            "basic cell dimensions have increased - recalculating the "
            "global partition.");
646

Matthieu Schaller's avatar
Matthieu Schaller committed
647
      if (!partition_space_to_space(oldwidth, oldcdim, oldnodeIDs, s)) {
648
649
650
651

        /* Failed, try another technique that requires no settings. */
        message("Failed to get a new partition, trying less optimal method");
        struct partition initial_partition;
652
#if defined(HAVE_PARMETIS) || defined(HAVE_METIS)
653
654
655
656
657
658
659
660
661
662
663
664
665
        initial_partition.type = INITPART_METIS_NOWEIGHT;
#else
        initial_partition.type = INITPART_VECTORIZE;
#endif
        partition_initial_partition(&initial_partition, s->e->nodeID,
                                    s->e->nr_nodes, s);
      }

      /* Re-distribute the particles to their new nodes. */
      engine_redistribute(s->e);

      /* Make the proxies. */
      engine_makeproxies(s->e);
666

667
      /* Finished with these. */
668
      swift_free("nodeIDs", oldnodeIDs);
Peter W. Draper's avatar
Peter W. Draper committed
669
670

    } else if (no_regrid && s->e != NULL) {
Peter W. Draper's avatar
Peter W. Draper committed
671
672
673
674
675
676
677
678
679
680
681
682
683
      /* If we have created the top-levels cells and not done an initial
       * partition (can happen when restarting), then the top-level cells
       * are not assigned to a node, we must do that and then associate the
       * particles with the cells. Note requires that
       * partition_store_celllist() was called once before, or just before
       * dumping the restart files.*/
      partition_restore_celllist(s, s->e->reparttype);

      /* Now re-distribute the particles, should just add to cells? */
      engine_redistribute(s->e);

      /* Make the proxies. */
      engine_makeproxies(s->e);
684
    }
Pedro Gonnet's avatar
Pedro Gonnet committed
685
#endif /* WITH_MPI */
686
687
688
689

    // message( "rebuilding upper-level cells took %.3f %s." ,
    // clocks_from_ticks(double)(getticks() - tic), clocks_getunit());

690
  }      /* re-build upper-level cells? */
691
  else { /* Otherwise, just clean up the cells. */
692
693

    /* Free the old cells, if they were allocated. */
694
    space_free_cells(s);
695
  }
696
697
698
699

  if (verbose)
    message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
            clocks_getunit());
700
}
701

702
703
704
705
706
707
/**
 * @brief Allocate memory for the extra particles used for on-the-fly creation.
 *
 * This rarely actually allocates memory. Most of the time, we convert
 * pre-allocated memory inot extra particles.
 *
708
709
 * This function also sets the extra particles' location to their top-level
 * cells. They can then be sorted into their correct memory position later on.
710
711
712
713
 *
 * @param s The current #space.
 * @param verbose Are we talkative?
 */
714
715
716
717
void space_allocate_extras(struct space *s, int verbose) {

  const int local_nodeID = s->e->nodeID;

718
719
  /* Anything to do here? (Abort if we don't want extras)*/
  if (space_extra_parts == 0 && space_extra_gparts == 0 &&
720
      space_extra_sparts == 0 && space_extra_bparts == 0)
721
722
    return;

723
724
725
726
727
728
  /* The top-level cells */
  const struct cell *cells = s->cells_top;
  const double half_cell_width[3] = {0.5 * cells[0].width[0],
                                     0.5 * cells[0].width[1],
                                     0.5 * cells[0].width[2]};

729
  /* The current number of particles (including spare ones) */
730
731
732
  size_t nr_parts = s->nr_parts;
  size_t nr_gparts = s->nr_gparts;
  size_t nr_sparts = s->nr_sparts;
733
  size_t nr_bparts = s->nr_bparts;
734

735
736
737
738
  /* The current number of actual particles */
  size_t nr_actual_parts = nr_parts - s->nr_extra_parts;
  size_t nr_actual_gparts = nr_gparts - s->nr_extra_gparts;
  size_t nr_actual_sparts = nr_sparts - s->nr_extra_sparts;
739
  size_t nr_actual_bparts = nr_bparts - s->nr_extra_bparts;
740

741
742
743
744
  /* The number of particles we allocated memory for (MPI overhead) */
  size_t size_parts = s->size_parts;
  size_t size_gparts = s->size_gparts;
  size_t size_sparts = s->size_sparts;
745
  size_t size_bparts = s->size_bparts;
746

747
748
749
750
751
  int *local_cells = (int *)malloc(sizeof(int) * s->nr_cells);
  if (local_cells == NULL)
    error("Failed to allocate list of local top-level cells");

  /* List the local cells */
752
  size_t nr_local_cells = 0;
753
754
755
756
757
758
  for (int i = 0; i < s->nr_cells; ++i) {
    if (s->cells_top[i].nodeID == local_nodeID) {
      local_cells[nr_local_cells] = i;
      ++nr_local_cells;
    }
  }
759

760
  /* Number of extra particles we want for each type */
761
762
763
  const size_t expected_num_extra_parts = nr_local_cells * space_extra_parts;
  const size_t expected_num_extra_gparts = nr_local_cells * space_extra_gparts;
  const size_t expected_num_extra_sparts = nr_local_cells * space_extra_sparts;
764
  const size_t expected_num_extra_bparts = nr_local_cells * space_extra_bparts;
765

766
  if (verbose) {
767
768
769
770
771
772
773
774
775
    message("Currently have %zd/%zd/%zd/%zd real particles.", nr_actual_parts,
            nr_actual_gparts, nr_actual_sparts, nr_actual_bparts);
    message("Currently have %zd/%zd/%zd/%zd spaces for extra particles.",
            s->nr_extra_parts, s->nr_extra_gparts, s->nr_extra_sparts,
            s->nr_extra_bparts);
    message(
        "Requesting space for future %zd/%zd/%zd/%zd part/gpart/sparts/bparts.",
        expected_num_extra_parts, expected_num_extra_gparts,
        expected_num_extra_sparts, expected_num_extra_bparts);
776
  }
777

778
779
780
781
782
783
  if (expected_num_extra_parts < s->nr_extra_parts)
    error("Reduction in top-level cells number not handled.");
  if (expected_num_extra_gparts < s->nr_extra_gparts)
    error("Reduction in top-level cells number not handled.");
  if (expected_num_extra_sparts < s->nr_extra_sparts)
    error("Reduction in top-level cells number not handled.");
784
785
  if (expected_num_extra_bparts < s->nr_extra_bparts)
    error("Reduction in top-level cells number not handled.");
786

787
788
  /* Do we have enough space for the extra gparts (i.e. we haven't used up any)
   * ? */
Loic Hausammann's avatar
Loic Hausammann committed
789
  if (nr_actual_gparts + expected_num_extra_gparts > nr_gparts) {
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804

    /* Ok... need to put some more in the game */

    /* Do we need to reallocate? */
    if (nr_actual_gparts + expected_num_extra_gparts > size_gparts) {

      size_gparts = (nr_actual_gparts + expected_num_extra_gparts) *
                    engine_redistribute_alloc_margin;

      if (verbose)
        message("Re-allocating gparts array from %zd to %zd", s->size_gparts,
                size_gparts);

      /* Create more space for parts */
      struct gpart *gparts_new = NULL;
805
      if (swift_memalign("gparts", (void **)&gparts_new, gpart_align,
806
807
808
809
                         sizeof(struct gpart) * size_gparts) != 0)
        error("Failed to allocate new gpart data");
      const ptrdiff_t delta = gparts_new - s->gparts;
      memcpy(gparts_new, s->gparts, sizeof(struct gpart) * s->size_gparts);
810
      swift_free("gparts", s->gparts);
811
812
813
814
815
816
817
818
819
820
821
822
823
824
      s->gparts = gparts_new;

      /* Update the counter */
      s->size_gparts = size_gparts;

      /* We now need to reset all the part and spart pointers */
      for (size_t i = 0; i < nr_parts; ++i) {
        if (s->parts[i].time_bin != time_bin_not_created)
          s->parts[i].gpart += delta;
      }
      for (size_t i = 0; i < nr_sparts; ++i) {
        if (s->sparts[i].time_bin != time_bin_not_created)
          s->sparts[i].gpart += delta;
      }
Loic Hausammann's avatar
Loic Hausammann committed
825
826
827
828
      for (size_t i = 0; i < nr_bparts; ++i) {
        if (s->bparts[i].time_bin != time_bin_not_created)
          s->bparts[i].gpart += delta;
      }
829
830
831
832
833
834
835
836
837
838
839
    }

    /* Turn some of the allocated spares into particles we can use */
    for (size_t i = nr_gparts; i < nr_actual_gparts + expected_num_extra_gparts;
         ++i) {
      bzero(&s->gparts[i], sizeof(struct gpart));
      s->gparts[i].time_bin = time_bin_not_created;
      s->gparts[i].type = swift_type_dark_matter;
      s->gparts[i].id_or_neg_offset = -1;
    }

840
    /* Put the spare particles in their correct cell */
841
    size_t local_cell_id = 0;
842
843
    int current_cell = local_cells[local_cell_id];
    int count_in_cell = 0;
844
845
846
847
848
849
850
851
852
853
854
    size_t count_extra_gparts = 0;
    for (size_t i = 0; i < nr_actual_gparts + expected_num_extra_gparts; ++i) {

#ifdef SWIFT_DEBUG_CHECKS
      if (current_cell == s->nr_cells)
        error("Cell counter beyond the maximal nr. cells.");
#endif

      if (s->gparts[i].time_bin == time_bin_not_created) {

        /* We want the extra particles to be at the centre of their cell */
855
856
857
        s->gparts[i].x[0] = cells[current_cell].loc[0] + half_cell_width[0];
        s->gparts[i].x[1] = cells[current_cell].loc[1] + half_cell_width[1];
        s->gparts[i].x[2] = cells[current_cell].loc[2] + half_cell_width[2];
858
859
860
861
862
863
864
        ++count_in_cell;
        count_extra_gparts++;
      }

      /* Once we have reached the number of extra gpart per cell, we move to the
       * next */
      if (count_in_cell == space_extra_gparts) {
865
866
867
868
869
        ++local_cell_id;

        if (local_cell_id == nr_local_cells) break;

        current_cell = local_cells[local_cell_id];
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
        count_in_cell = 0;
      }
    }

#ifdef SWIFT_DEBUG_CHECKS
    if (count_extra_gparts != expected_num_extra_gparts)
      error("Constructed the wrong number of extra gparts (%zd vs. %zd)",
            count_extra_gparts, expected_num_extra_gparts);
#endif

    /* Update the counters */
    s->nr_gparts = nr_actual_gparts + expected_num_extra_gparts;
    s->nr_extra_gparts = expected_num_extra_gparts;
  }

885
886
  /* Do we have enough space for the extra parts (i.e. we haven't used up any) ?
   */
887
  if (nr_actual_parts + expected_num_extra_parts > nr_parts) {
888

889
890
    /* Ok... need to put some more in the game */

891
892
893
894
895
896
897
898
899
900
901
902
    /* Do we need to reallocate? */
    if (nr_actual_parts + expected_num_extra_parts > size_parts) {

      size_parts =