cell.h 25.9 KB
Newer Older
1
/*******************************************************************************
2
 * This file is part of SWIFT.
3
 * Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
4
5
6
7
 *                    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)
8
 *
9
10
11
12
 * 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.
13
 *
14
15
16
17
 * 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.
18
 *
19
20
 * 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/>.
21
 *
22
 ******************************************************************************/
23
24
#ifndef SWIFT_CELL_H
#define SWIFT_CELL_H
25

26
27
28
/* Config parameters. */
#include "../config.h"

29
/* Includes. */
30
31
32
#include <stddef.h>

/* Local includes. */
33
#include "align.h"
34
#include "kernel_hydro.h"
Pedro Gonnet's avatar
Pedro Gonnet committed
35
#include "lock.h"
36
#include "multipole.h"
37
#include "part.h"
38
#include "space.h"
39
#include "task.h"
40
#include "timeline.h"
41

42
/* Avoid cyclic inclusions */
43
struct engine;
44
struct scheduler;
45

46
47
48
/* Max tag size set to 2^29 to take into account some MPI implementations
 * that use 2^31 as the upper bound on MPI tags and the fact that
 * cell_next_tag is multiplied by 2 when passed to an MPI function.
49
50
 * The maximum was lowered by a further factor of 2 to be on the safe side.*/
#define cell_max_tag (1 << 29)
51

52
#define cell_align 128
53

54
55
56
/* Global variables. */
extern int cell_next_tag;

57
58
59
60
/* Struct to temporarily buffer the particle locations and bin id. */
struct cell_buff {
  double x[3];
  int ind;
61
} SWIFT_STRUCT_ALIGN;
62

63
64
65
66
67
68
69
70
71
72
/* Mini struct to link cells to tasks. Used as a linked list. */
struct link {

  /* The task pointer. */
  struct task *t;

  /* The next pointer. */
  struct link *next;
};

73
74
75
76
77
/**
 * @brief Packed cell for information correct at rebuild time.
 *
 * Contains all the information for a tree walk in a non-local cell.
 */
78
79
struct pcell {

80
81
  /*! Hydro variables */
  struct {
Matthieu Schaller's avatar
Matthieu Schaller committed
82

83
84
    /*! Maximal smoothing length. */
    double h_max;
85

86
87
    /*! Minimal integer end-of-timestep in this cell for hydro tasks */
    integertime_t ti_end_min;
88

89
90
    /*! Maximal integer end-of-timestep in this cell for hydro tasks */
    integertime_t ti_end_max;
91

92
93
    /*! Maximal integer beginning-of-timestep in this cell for hydro tasks */
    integertime_t ti_beg_max;
94

95
    /*! Integer time of the last drift of the #part in this cell */
96
    integertime_t ti_old_part;
97

98
99
    /*! Number of #part in this cell. */
    int count;
100

101
  } hydro;
102

103
104
  /*! Gravity variables */
  struct {
105

106
107
    /*! This cell's gravity-related tensors */
    struct multipole m_pole;
108

109
110
    /*! Centre of mass. */
    double CoM[3];
111

112
113
    /*! Centre of mass at rebuild time. */
    double CoM_rebuild[3];
114

115
116
    /*! Upper limit of the CoM<->gpart distance. */
    double r_max;
117

118
119
    /*! Upper limit of the CoM<->gpart distance at last rebuild. */
    double r_max_rebuild;
120

121
122
    /*! Minimal integer end-of-timestep in this cell for gravity tasks */
    integertime_t ti_end_min;
Pedro Gonnet's avatar
Pedro Gonnet committed
123

124
125
    /*! Maximal integer end-of-timestep in this cell for gravity tasks */
    integertime_t ti_end_max;
126

127
128
    /*! Maximal integer beginning-of-timestep in this cell for gravity tasks */
    integertime_t ti_beg_max;
129

130
    /*! Integer time of the last drift of the #gpart in this cell */
131
    integertime_t ti_old_part;
132

133
134
    /*! Integer time of the last drift of the #multipole in this cell */
    integertime_t ti_old_multipole;
135

136
    /*! Number of #gpart in this cell. */
137
    int count;
138
139
140

  } grav;

141
142
143
144
145
146
  /*! Stars variables */
  struct {

    /*! Number of #spart in this cell. */
    int count;

Loic Hausammann's avatar
Loic Hausammann committed
147
148
149
    /*! Maximal smoothing length. */
    double h_max;

150
151
  } stars;

152
153
154
  /*! Maximal depth in that part of the tree */
  int maxdepth;

155
156
  /*! Relative indices of the cell's progeny. */
  int progeny[8];
157

158
159
160
161
162
#ifdef SWIFT_DEBUG_CHECKS
  /* Cell ID (for debugging) */
  int cellID;
#endif

163
} SWIFT_STRUCT_ALIGN;
164

165
166
167
168
169
/**
 * @brief Cell information at the end of a time-step.
 */
struct pcell_step {

170
171
172
173
174
  /*! Hydro variables */
  struct {

    /*! Minimal integer end-of-timestep in this cell (hydro) */
    integertime_t ti_end_min;
175

176
177
    /*! Minimal integer end-of-timestep in this cell (hydro) */
    integertime_t ti_end_max;
178

179
    /*! Maximal distance any #part has travelled since last rebuild */
180
    float dx_max_part;
181

182
  } hydro;
183

184
185
186
187
188
189
190
191
  /*! Grav variables */
  struct {

    /*! Minimal integer end-of-timestep in this cell (gravity) */
    integertime_t ti_end_min;

    /*! Minimal integer end-of-timestep in this cell (gravity) */
    integertime_t ti_end_max;
192

193
  } grav;
194
195
196

  /*! Stars variables */
  struct {
Loic Hausammann's avatar
Loic Hausammann committed
197
198
199
200

    /*! Maximal distance any #part has travelled since last rebuild */
    float dx_max_part;

201
  } stars;
202
203
};

204
205
206
207
208
/**
 * @brief Cell within the tree structure.
 *
 * Contains particles, links to tasks, a multipole object and counters.
 */
209
210
struct cell {

211
  /*! The cell location on the grid. */
212
213
  double loc[3];

214
  /*! The cell dimensions. */
215
  double width[3];
216

217
  /*! Pointers to the next level of cells. */
218
219
  struct cell *progeny[8];

220
221
222
  /*! Linking pointer for "memory management". */
  struct cell *next;

223
  /*! Parent cell. */
224
225
  struct cell *parent;

226
  /*! Super cell, i.e. the highest-level parent cell with *any* task */
227
  struct cell *super;
228

229
230
  /*! Hydro variables */
  struct {
231

232
233
    /*! Pointer to the #part data. */
    struct part *parts;
234

235
236
    /*! Pointer to the #xpart data. */
    struct xpart *xparts;
237

238
239
    /*! Pointer for the sorted indices. */
    struct entry *sort[13];
240

241
242
    /*! Super cell, i.e. the highest-level parent cell that has a hydro
     * pair/self tasks */
243
    struct cell *super;
244

245
246
    /*! The task computing this cell's sorts. */
    struct task *sorts;
247

248
249
    /*! The drift task for parts */
    struct task *drift;
250

251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
    /*! Linked list of the tasks computing this cell's hydro density. */
    struct link *density;

    /* Linked list of the tasks computing this cell's hydro gradients. */
    struct link *gradient;

    /*! Linked list of the tasks computing this cell's hydro forces. */
    struct link *force;

    /*! Dependency implicit task for the ghost  (in->ghost->out)*/
    struct task *ghost_in;

    /*! Dependency implicit task for the ghost  (in->ghost->out)*/
    struct task *ghost_out;

    /*! The ghost task itself */
    struct task *ghost;

    /*! The extra ghost task for complex hydro schemes */
    struct task *extra_ghost;

    /*! Task for cooling */
    struct task *cooling;

    /*! Task for star formation */
    struct task *star_formation;
277

278
279
    /*! Max smoothing length in this cell. */
    double h_max;
280

281
282
283
    /*! Last (integer) time the cell's part were drifted forward in time. */
    integertime_t ti_old_part;

284
285
    /*! Minimum end of (integer) time step in this cell for hydro tasks. */
    integertime_t ti_end_min;
286

287
288
    /*! Maximum end of (integer) time step in this cell for hydro tasks. */
    integertime_t ti_end_max;
289

290
291
    /*! Maximum beginning of (integer) time step in this cell for hydro tasks.
     */
292
    integertime_t ti_beg_max;
293

294
295
    /*! Spin lock for various uses (#part case). */
    swift_lock_type lock;
296

297
298
    /*! Maximum part movement in this cell since last construction. */
    float dx_max_part;
299

300
301
    /*! Maximum particle movement in this cell since the last sort. */
    float dx_max_sort;
302

303
304
    /*! Values of h_max before the drifts, used for sub-cell tasks. */
    float h_max_old;
305

306
307
308
    /*! Values of dx_max before the drifts, used for sub-cell tasks. */
    float dx_max_part_old;

309
310
    /*! Values of dx_max_sort before the drifts, used for sub-cell tasks. */
    float dx_max_sort_old;
311

312
313
314
    /*! Nr of #part in this cell. */
    int count;

315
316
317
    /*! Nr of #part this cell can hold after addition of new #part. */
    int count_total;

318
319
320
321
322
323
324
325
326
    /*! Number of #part updated in this cell. */
    int updated;

    /*! Number of #part inhibited in this cell. */
    int inhibited;

    /*! Is the #part data of this cell being used in a sub-cell? */
    int hold;

327
328
    /*! Bit mask of sort directions that will be needed in the next timestep. */
    unsigned int requires_sorts;
329

330
331
    /*! Bit mask of sorts that need to be computed for this cell. */
    unsigned int do_sort;
332

333
334
335
    /*! Bit-mask indicating the sorted directions */
    unsigned int sorted;

336
337
    /*! Does this cell need to be drifted (hydro)? */
    char do_drift;
338

339
340
    /*! Do any of this cell's sub-cells need to be drifted (hydro)? */
    char do_sub_drift;
Tom Theuns's avatar
Tom Theuns committed
341

342
343
    /*! Do any of this cell's sub-cells need to be sorted? */
    char do_sub_sort;
344

345
#ifdef SWIFT_DEBUG_CHECKS
346

347
348
    /*! Last (integer) time the cell's sort arrays were updated. */
    integertime_t ti_sort;
349

350
#endif
351

352
  } hydro;
353

354
355
  /*! Grav variables */
  struct {
356

357
    /*! Pointer to the #gpart data. */
358
    struct gpart *parts;
359

360
361
    /*! This cell's multipole. */
    struct gravity_tensors *multipole;
362

363
364
365
    /*! Super cell, i.e. the highest-level parent cell that has a grav pair/self
     * tasks */
    struct cell *super;
366

367
368
369
    /*! The drift task for gparts */
    struct task *drift;

370
371
372
    /*! Implicit task (going up- and down the tree) for the #gpart drifts */
    struct task *drift_out;

373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
    /*! Linked list of the tasks computing this cell's gravity forces. */
    struct link *grav;

    /*! Linked list of the tasks computing this cell's gravity M-M forces. */
    struct link *mm;

    /*! The multipole initialistation task */
    struct task *init;

    /*! Implicit task for the gravity initialisation */
    struct task *init_out;

    /*! Task computing long range non-periodic gravity interactions */
    struct task *long_range;

    /*! Implicit task for the down propagation */
    struct task *down_in;

    /*! Task propagating the mesh forces to the particles */
    struct task *mesh;

    /*! Task propagating the multipole to the particles */
    struct task *down;

397
398
    /*! Minimum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_min;
399

400
401
    /*! Maximum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_max;
402

403
404
405
    /*! Maximum beginning of (integer) time step in this cell for gravity tasks.
     */
    integertime_t ti_beg_max;
406

407
    /*! Last (integer) time the cell's gpart were drifted forward in time. */
408
    integertime_t ti_old_part;
409

410
411
    /*! Last (integer) time the cell's multipole was drifted forward in time. */
    integertime_t ti_old_multipole;
412

413
    /*! Spin lock for various uses (#gpart case). */
414
    swift_lock_type plock;
415

416
417
    /*! Spin lock for various uses (#multipole case). */
    swift_lock_type mlock;
418

419
420
421
    /*! Nr of #gpart in this cell. */
    int count;

422
423
424
    /*! Nr of #gpart this cell can hold after addition of new #gpart. */
    int count_total;

425
    /*! Number of #gpart updated in this cell. */
426
    int updated;
427

428
429
430
    /*! Number of #gpart inhibited in this cell. */
    int inhibited;

431
    /*! Is the #gpart data of this cell being used in a sub-cell? */
432
    int phold;
433

434
435
    /*! Is the #multipole data of this cell being used in a sub-cell? */
    int mhold;
436

437
438
439
    /*! Number of M-M tasks that are associated with this cell. */
    short int nr_mm_tasks;

440
441
    /*! Does this cell need to be drifted (gravity)? */
    char do_drift;
442

443
444
    /*! Do any of this cell's sub-cells need to be drifted (gravity)? */
    char do_sub_drift;
Matthieu Schaller's avatar
Matthieu Schaller committed
445

446
  } grav;
447

448
449
  /*! Stars variables */
  struct {
450

451
452
    /*! Pointer to the #spart data. */
    struct spart *parts;
453

454
455
456
457
458
459
460
461
462
463
464
    /*! Dependency implicit task for the star ghost  (in->ghost->out)*/
    struct task *ghost_in;

    /*! Dependency implicit task for the star ghost  (in->ghost->out)*/
    struct task *ghost_out;

    /*! The star ghost task itself */
    struct task *ghost;

    /*! Linked list of the tasks computing this cell's star density. */
    struct link *density;
465

Loic Hausammann's avatar
Loic Hausammann committed
466
467
468
    /*! Max smoothing length in this cell. */
    double h_max;

469
470
471
472
473
474
    /*! Spin lock for various uses (#spart case). */
    swift_lock_type lock;

    /*! Nr of #spart in this cell. */
    int count;

475
476
477
    /*! Nr of #spart this cell can hold after addition of new #spart. */
    int count_total;

Loic Hausammann's avatar
Loic Hausammann committed
478
479
480
481
482
483
484
485
486
    /*! Values of h_max before the drifts, used for sub-cell tasks. */
    float h_max_old;

    /*! Maximum part movement in this cell since last construction. */
    float dx_max_part;

    /*! Values of dx_max before the drifts, used for sub-cell tasks. */
    float dx_max_part_old;

487
488
    /*! Number of #spart updated in this cell. */
    int updated;
489

490
491
492
    /*! Number of #spart inhibited in this cell. */
    int inhibited;

493
494
    /*! Is the #spart data of this cell being used in a sub-cell? */
    int hold;
495

496
  } stars;
497

498
499
500
#ifdef WITH_MPI
  /*! MPI variables */
  struct {
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531

    struct {
      /* Task receiving hydro data (positions). */
      struct task *recv_xv;

      /* Task receiving hydro data (density). */
      struct task *recv_rho;

      /* Task receiving hydro data (gradient). */
      struct task *recv_gradient;

      /* Linked list for sending hydro data (positions). */
      struct link *send_xv;

      /* Linked list for sending hydro data (density). */
      struct link *send_rho;

      /* Linked list for sending hydro data (gradient). */
      struct link *send_gradient;

    } hydro;

    struct {

      /* Task receiving gpart data. */
      struct task *recv;

      /* Linked list for sending gpart data. */
      struct link *send;
    } grav;

532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
    /* Task receiving data (time-step). */
    struct task *recv_ti;

    /* Linked list for sending data (time-step). */
    struct link *send_ti;

    /*! Bit mask of the proxies this cell is registered with. */
    unsigned long long int sendto;

    /*! Pointer to this cell's packed representation. */
    struct pcell *pcell;

    /*! Size of the packed representation */
    int pcell_size;

    /*! MPI tag associated with this cell */
    int tag;
549

550
551
  } mpi;
#endif
552

553
554
555
  /*! The task to end the force calculation */
  struct task *end_force;

556
557
  /*! The first kick task */
  struct task *kick1;
558

559
560
  /*! The second kick task */
  struct task *kick2;
561

562
563
564
565
566
567
  /*! The task to compute time-steps */
  struct task *timestep;

  /*! Task for source terms */
  struct task *sourceterms;

Loic Hausammann's avatar
Format    
Loic Hausammann committed
568
569
570
  /*! The logger task */
  struct task *logger;

571
572
  /*! Minimum dimension, i.e. smallest edge of this cell (min(width)). */
  float dmin;
573

574
575
576
577
578
579
  /*! ID of the previous owner, e.g. runner. */
  int owner;

  /*! ID of the node this cell lives on. */
  int nodeID;

580
581
582
583
584
585
586
587
588
589
590
591
  /*! Number of tasks that are associated with this cell. */
  short int nr_tasks;

  /*! The depth of this cell in the tree. */
  char depth;

  /*! Is this cell split ? */
  char split;

  /*! The maximal depth of this cell and its progenies */
  char maxdepth;

592
#ifdef SWIFT_DEBUG_CHECKS
593
594
595
  /* Cell ID (for debugging) */
  int cellID;

596
597
598
599
600
601
602
  /*! The list of tasks that have been executed on this cell */
  char tasks_executed[64];

  /*! The list of sub-tasks that have been executed on this cell */
  char subtasks_executed[64];
#endif

603
} SWIFT_STRUCT_ALIGN;
604

605
606
607
608
/* Convert cell location to ID. */
#define cell_getid(cdim, i, j, k) \
  ((int)(k) + (cdim)[2] * ((int)(j) + (cdim)[1] * (int)(i)))

609
/* Function prototypes. */
610
611
void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
                struct cell_buff *buff, struct cell_buff *sbuff,
612
                struct cell_buff *gbuff);
613
void cell_sanitize(struct cell *c, int treated);
614
615
616
617
int cell_locktree(struct cell *c);
void cell_unlocktree(struct cell *c);
int cell_glocktree(struct cell *c);
void cell_gunlocktree(struct cell *c);
618
619
int cell_mlocktree(struct cell *c);
void cell_munlocktree(struct cell *c);
620
621
int cell_slocktree(struct cell *c);
void cell_sunlocktree(struct cell *c);
622
int cell_pack(struct cell *c, struct pcell *pc, const int with_gravity);
Matthieu Schaller's avatar
Matthieu Schaller committed
623
624
int cell_unpack(struct pcell *pc, struct cell *c, struct space *s,
                const int with_gravity);
625
626
int cell_pack_tags(const struct cell *c, int *tags);
int cell_unpack_tags(const int *tags, struct cell *c);
627
628
int cell_pack_end_step(struct cell *c, struct pcell_step *pcell);
int cell_unpack_end_step(struct cell *c, struct pcell_step *pcell);
629
630
int cell_pack_multipoles(struct cell *c, struct gravity_tensors *m);
int cell_unpack_multipoles(struct cell *c, struct gravity_tensors *m);
631
int cell_getsize(struct cell *c);
632
633
int cell_link_parts(struct cell *c, struct part *parts);
int cell_link_gparts(struct cell *c, struct gpart *gparts);
634
int cell_link_sparts(struct cell *c, struct spart *sparts);
635
void cell_clean_links(struct cell *c, void *data);
636
void cell_make_multipoles(struct cell *c, integertime_t ti_current);
637
638
void cell_check_multipole(struct cell *c);
void cell_check_foreign_multipole(const struct cell *c);
639
void cell_clean(struct cell *c);
640
641
void cell_check_part_drift_point(struct cell *c, void *data);
void cell_check_gpart_drift_point(struct cell *c, void *data);
642
void cell_check_multipole_drift_point(struct cell *c, void *data);
643
void cell_reset_task_counters(struct cell *c);
644
int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s);
645
int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s);
646
int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s);
647
void cell_set_super(struct cell *c, struct cell *super);
648
void cell_drift_part(struct cell *c, const struct engine *e, int force);
649
void cell_drift_gpart(struct cell *c, const struct engine *e, int force);
650
void cell_drift_multipole(struct cell *c, const struct engine *e);
651
void cell_drift_all_multipoles(struct cell *c, const struct engine *e);
652
void cell_check_timesteps(struct cell *c);
653
void cell_store_pre_drift_values(struct cell *c);
654
655
void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
                                       struct scheduler *s);
656
657
void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
                                      struct scheduler *s);
658
659
void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
                                       struct scheduler *s);
660
661
void cell_activate_subcell_external_grav_tasks(struct cell *ci,
                                               struct scheduler *s);
662
void cell_activate_drift_part(struct cell *c, struct scheduler *s);
663
void cell_activate_drift_gpart(struct cell *c, struct scheduler *s);
664
void cell_activate_sorts(struct cell *c, int sid, struct scheduler *s);
665
void cell_clear_drift_flags(struct cell *c, void *data);
Pedro Gonnet's avatar
Pedro Gonnet committed
666
void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data);
667
int cell_has_tasks(struct cell *c);
668
void cell_add_spart(const struct engine *e, struct cell *c);
669
670
void cell_remove_part(const struct engine *e, struct cell *c, struct part *p,
                      struct xpart *xp);
671
672
673
674
void cell_remove_gpart(const struct engine *e, struct cell *c,
                       struct gpart *gp);
void cell_remove_spart(const struct engine *e, struct cell *c,
                       struct spart *sp);
675
struct gpart* cell_convert_part_to_gpart(const struct engine *e, struct cell *c,
676
                                struct part *p, struct xpart *xp);
677
struct gpart* cell_convert_spart_to_gpart(const struct engine *e, struct cell *c,
678
                                 struct spart *sp);
679
void cell_reorder_extra_parts(struct cell *c, const ptrdiff_t parts_offset);
680
681
void cell_reorder_extra_gparts(struct cell *c, struct part *parts,
                               struct spart *sparts);
682
void cell_reorder_extra_sparts(struct cell *c, const ptrdiff_t sparts_offset);
683
684
int cell_can_use_pair_mm(const struct cell *ci, const struct cell *cj,
                         const struct engine *e, const struct space *s);
685
int cell_can_use_pair_mm_rebuild(const struct cell *ci, const struct cell *cj,
Matthieu Schaller's avatar
Matthieu Schaller committed
686
                                 const struct engine *e, const struct space *s);
687
688
689
690
691
692
693
694
695

/* Inlined functions (for speed). */

/**
 * @brief Can a sub-pair hydro task recurse to a lower level based
 * on the status of the particles in the cell.
 *
 * @param c The #cell.
 */
Matthieu Schaller's avatar
Matthieu Schaller committed
696
697
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_pair_hydro_task(const struct cell *c) {
698
699
700
701
702

  /* Is the cell split ? */
  /* If so, is the cut-off radius plus the max distance the parts have moved */
  /* smaller than the sub-cell sizes ? */
  /* Note: We use the _old values as these might have been updated by a drift */
703
  return c->split && ((kernel_gamma * c->hydro.h_max_old +
704
                       c->hydro.dx_max_part_old) < 0.5f * c->dmin);
705
706
707
708
709
710
711
712
}

/**
 * @brief Can a sub-self hydro task recurse to a lower level based
 * on the status of the particles in the cell.
 *
 * @param c The #cell.
 */
Matthieu Schaller's avatar
Matthieu Schaller committed
713
714
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_self_hydro_task(const struct cell *c) {
715

716
  /* Is the cell split and not smaller than the smoothing length? */
717
  return c->split && (kernel_gamma * c->hydro.h_max_old < 0.5f * c->dmin);
718
719
}

720
721
722
723
724
725
726
727
728
/**
 * @brief Can a sub-pair star task recurse to a lower level based
 * on the status of the particles in the cell.
 *
 * @param c The #cell.
 */
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_pair_stars_task(const struct cell *c) {

Loic Hausammann's avatar
Loic Hausammann committed
729
730
731
732
733
734
  /* Is the cell split ? */
  /* If so, is the cut-off radius plus the max distance the parts have moved */
  /* smaller than the sub-cell sizes ? */
  /* Note: We use the _old values as these might have been updated by a drift */
  return c->split && ((kernel_gamma * c->stars.h_max_old +
                       c->stars.dx_max_part_old) < 0.5f * c->dmin);
735
736
737
738
739
740
741
742
743
744
745
}

/**
 * @brief Can a sub-self stars task recurse to a lower level based
 * on the status of the particles in the cell.
 *
 * @param c The #cell.
 */
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_self_stars_task(const struct cell *c) {

Loic Hausammann's avatar
Loic Hausammann committed
746
747
  /* Is the cell split and not smaller than the smoothing length? */
  return c->split && (kernel_gamma * c->stars.h_max_old < 0.5f * c->dmin);
748
749
}

750
/**
751
 * @brief Can a pair hydro task associated with a cell be split into smaller
752
753
754
755
 * sub-tasks.
 *
 * @param c The #cell.
 */
756
__attribute__((always_inline)) INLINE static int cell_can_split_pair_hydro_task(
757
758
759
760
761
762
763
    const struct cell *c) {

  /* Is the cell split ? */
  /* If so, is the cut-off radius with some leeway smaller than */
  /* the sub-cell sizes ? */
  /* Note that since tasks are create after a rebuild no need to take */
  /* into account any part motion (i.e. dx_max == 0 here) */
764
765
  return c->split &&
         (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin);
766
767
768
}

/**
769
 * @brief Can a self hydro task associated with a cell be split into smaller
770
771
772
773
 * sub-tasks.
 *
 * @param c The #cell.
 */
774
__attribute__((always_inline)) INLINE static int cell_can_split_self_hydro_task(
775
776
777
    const struct cell *c) {

  /* Is the cell split ? */
778
779
  /* If so, is the cut-off radius with some leeway smaller than */
  /* the sub-cell sizes ? */
780
781
  /* Note: No need for more checks here as all the sub-pairs and sub-self */
  /* tasks will be created. So no need to check for h_max */
782
783
  return c->split &&
         (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin);
784
785
}

786
787
788
789
790
791
792
793
794
/**
 * @brief Can a pair stars task associated with a cell be split into smaller
 * sub-tasks.
 *
 * @param c The #cell.
 */
__attribute__((always_inline)) INLINE static int cell_can_split_pair_stars_task(
    const struct cell *c) {

Loic Hausammann's avatar
Loic Hausammann committed
795
796
797
798
799
800
801
  /* Is the cell split ? */
  /* If so, is the cut-off radius with some leeway smaller than */
  /* the sub-cell sizes ? */
  /* Note that since tasks are create after a rebuild no need to take */
  /* into account any part motion (i.e. dx_max == 0 here) */
  return c->split &&
         (space_stretch * kernel_gamma * c->stars.h_max < 0.5f * c->dmin);
802
803
804
805
806
807
808
809
810
811
812
}

/**
 * @brief Can a self stars task associated with a cell be split into smaller
 * sub-tasks.
 *
 * @param c The #cell.
 */
__attribute__((always_inline)) INLINE static int cell_can_split_self_stars_task(
    const struct cell *c) {

Loic Hausammann's avatar
Loic Hausammann committed
813
814
815
816
817
818
819
  /* Is the cell split ? */
  /* If so, is the cut-off radius with some leeway smaller than */
  /* the sub-cell sizes ? */
  /* Note: No need for more checks here as all the sub-pairs and sub-self */
  /* tasks will be created. So no need to check for h_max */
  return c->split &&
         (space_stretch * kernel_gamma * c->stars.h_max < 0.5f * c->dmin);
820
821
}

822
823
824
825
826
827
/**
 * @brief Can a pair gravity task associated with a cell be split into smaller
 * sub-tasks.
 *
 * @param c The #cell.
 */
Matthieu Schaller's avatar
Matthieu Schaller committed
828
829
__attribute__((always_inline)) INLINE static int
cell_can_split_pair_gravity_task(const struct cell *c) {
830

831
832
  /* Is the cell split and still far from the leaves ? */
  return c->split && ((c->maxdepth - c->depth) > space_subdepth_diff_grav);
833
834
835
836
837
838
839
840
}

/**
 * @brief Can a self gravity task associated with a cell be split into smaller
 * sub-tasks.
 *
 * @param c The #cell.
 */
Matthieu Schaller's avatar
Matthieu Schaller committed
841
842
__attribute__((always_inline)) INLINE static int
cell_can_split_self_gravity_task(const struct cell *c) {
843

844
845
  /* Is the cell split and still far from the leaves ? */
  return c->split && ((c->maxdepth - c->depth) > space_subdepth_diff_grav);
846
847
}

848
849
850
851
852
853
854
855
856
857
858
859
860
/**
 * @brief Have particles in a pair of cells moved too much and require a rebuild
 * ?
 *
 * @param ci The first #cell.
 * @param cj The second #cell.
 */
__attribute__((always_inline)) INLINE static int cell_need_rebuild_for_pair(
    const struct cell *ci, const struct cell *cj) {

  /* Is the cut-off radius plus the max distance the parts in both cells have */
  /* moved larger than the cell size ? */
  /* Note ci->dmin == cj->dmin */
861
  return (kernel_gamma * max(ci->hydro.h_max, cj->hydro.h_max) +
862
              ci->hydro.dx_max_part + cj->hydro.dx_max_part >
863
864
          cj->dmin);
}
865

866
/**
867
868
869
 * @brief Add a unique tag to a cell mostly for MPI communications.
 *
 * @param c The #cell to tag.
870
 */
871
__attribute__((always_inline)) INLINE static void cell_tag(struct cell *c) {
872
#ifdef WITH_MPI
873
874

#ifdef SWIFT_DEBUG_CHECKS
875
  if (c->mpi.tag > 0) error("setting tag for already tagged cell");
876
877
#endif

878
879
  if (c->mpi.tag < 0 &&
      (c->mpi.tag = atomic_inc(&cell_next_tag)) > cell_max_tag)
880
881
882
883
884
885
    error("Ran out of cell tags.");
#else
  error("SWIFT was not compiled with MPI enabled.");
#endif  // WITH_MPI
}

886
#endif /* SWIFT_CELL_H */