cell.h 22.6 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
147
148
  /*! Stars variables */
  struct {

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

  } stars;

149
150
  /*! Relative indices of the cell's progeny. */
  int progeny[8];
151

152
153
154
155
156
#ifdef SWIFT_DEBUG_CHECKS
  /* Cell ID (for debugging) */
  int cellID;
#endif

157
} SWIFT_STRUCT_ALIGN;
158

159
160
161
162
163
/**
 * @brief Cell information at the end of a time-step.
 */
struct pcell_step {

164
165
166
167
168
  /*! Hydro variables */
  struct {

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

170
171
    /*! Minimal integer end-of-timestep in this cell (hydro) */
    integertime_t ti_end_max;
172

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

176
  } hydro;
177

178
179
180
181
182
183
184
185
  /*! 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;
186

187
  } grav;
188
189
190
191

  /*! Stars variables */
  struct {
  } stars;
192
193
};

194
195
196
197
198
/**
 * @brief Cell within the tree structure.
 *
 * Contains particles, links to tasks, a multipole object and counters.
 */
199
200
struct cell {

201
  /*! The cell location on the grid. */
202
203
  double loc[3];

204
  /*! The cell dimensions. */
205
  double width[3];
206

207
208
  /*! Linking pointer for "memory management". */
  struct cell *next;
209

210
  /*! Pointers to the next level of cells. */
211
212
  struct cell *progeny[8];

213
  /*! Parent cell. */
214
215
  struct cell *parent;

216
  /*! Super cell, i.e. the highest-level parent cell with *any* task */
217
  struct cell *super;
218

219
220
  /*! Hydro variables */
  struct {
221

222
223
    /*! Pointer to the #part data. */
    struct part *parts;
224

225
226
    /*! Pointer to the #xpart data. */
    struct xpart *xparts;
227

228
229
    /*! Pointer for the sorted indices. */
    struct entry *sort[13];
230

231
232
    /*! Super cell, i.e. the highest-level parent cell that has a hydro
     * pair/self tasks */
233
    struct cell *super;
234

235
    /*! Last (integer) time the cell's part were drifted forward in time. */
236
    integertime_t ti_old_part;
237

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

241
242
    /*! Maximum particle movement in this cell since the last sort. */
    float dx_max_sort;
243

244
245
    /*! Max smoothing length in this cell. */
    double h_max;
246

247
248
    /*! Minimum end of (integer) time step in this cell for hydro tasks. */
    integertime_t ti_end_min;
249

250
251
    /*! Maximum end of (integer) time step in this cell for hydro tasks. */
    integertime_t ti_end_max;
252

253
254
    /*! Maximum beginning of (integer) time step in this cell for hydro tasks.
     */
255
    integertime_t ti_beg_max;
256

257
258
    /*! Nr of #part in this cell. */
    int count;
259

260
261
    /*! Spin lock for various uses (#part case). */
    swift_lock_type lock;
262

263
264
    /*! Number of #part updated in this cell. */
    int updated;
265

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

269
270
    /*! Values of h_max before the drifts, used for sub-cell tasks. */
    float h_max_old;
271

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

275
276
    /*! Values of dx_max_sort before the drifts, used for sub-cell tasks. */
    float dx_max_sort_old;
277

278
279
    /*! Bit mask of sort directions that will be needed in the next timestep. */
    unsigned int requires_sorts;
280

281
282
    /*! Bit mask of sorts that need to be computed for this cell. */
    unsigned int do_sort;
283

284
285
    /*! Does this cell need to be drifted (hydro)? */
    char do_drift;
286

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

290
291
    /*! Do any of this cell's sub-cells need to be sorted? */
    char do_sub_sort;
292

293
294
    /*! Bit-mask indicating the sorted directions */
    unsigned int sorted;
295

296
297
    /*! The task computing this cell's sorts. */
    struct task *sorts;
298

299
300
    /*! The drift task for parts */
    struct task *drift;
301

302
303
    /*! Linked list of the tasks computing this cell's hydro density. */
    struct link *density;
Loic Hausammann's avatar
Loic Hausammann committed
304

305
306
    /* Linked list of the tasks computing this cell's hydro gradients. */
    struct link *gradient;
Loic Hausammann's avatar
Loic Hausammann committed
307

308
309
    /*! Linked list of the tasks computing this cell's hydro forces. */
    struct link *force;
Loic Hausammann's avatar
Loic Hausammann committed
310

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

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

317
318
319
320
321
322
323
324
325
326
327
    /*! The ghost task itself */
    struct task *ghost;

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

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

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

329
#ifdef SWIFT_DEBUG_CHECKS
330

331
332
    /*! Last (integer) time the cell's sort arrays were updated. */
    integertime_t ti_sort;
333

334
#endif
335

336
  } hydro;
337

338
339
  /*! Grav variables */
  struct {
340

341
    /*! Pointer to the #gpart data. */
342
    struct gpart *parts;
343

344
345
    /*! This cell's multipole. */
    struct gravity_tensors *multipole;
346

347
348
349
    /*! Super cell, i.e. the highest-level parent cell that has a grav pair/self
     * tasks */
    struct cell *super;
350

351
352
    /*! Minimum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_min;
353

354
355
    /*! Maximum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_max;
356

357
358
359
    /*! Maximum beginning of (integer) time step in this cell for gravity tasks.
     */
    integertime_t ti_beg_max;
360

361
    /*! Last (integer) time the cell's gpart were drifted forward in time. */
362
    integertime_t ti_old_part;
363

364
365
    /*! Last (integer) time the cell's multipole was drifted forward in time. */
    integertime_t ti_old_multipole;
366

367
    /*! Nr of #gpart in this cell. */
368
    int count;
369

370
    /*! Spin lock for various uses (#gpart case). */
371
    swift_lock_type plock;
372

373
374
    /*! Spin lock for various uses (#multipole case). */
    swift_lock_type mlock;
375

376
    /*! Number of #gpart updated in this cell. */
377
    int updated;
378

379
    /*! Is the #gpart data of this cell being used in a sub-cell? */
380
    int phold;
381

382
383
    /*! Is the #multipole data of this cell being used in a sub-cell? */
    int mhold;
384

385
386
    /*! Does this cell need to be drifted (gravity)? */
    char do_drift;
387

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

391
    /*! The drift task for gparts */
392
    struct task *drift;
393

394
395
    /*! Linked list of the tasks computing this cell's gravity forces. */
    struct link *grav;
396

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

400
401
    /*! The multipole initialistation task */
    struct task *init;
402

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

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

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

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

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

418
419
    /*! Number of M-M tasks that are associated with this cell. */
    short int nr_mm_tasks;
420

421
  } grav;
422

423
424
  /*! Stars variables */
  struct {
425

426
427
    /*! Pointer to the #spart data. */
    struct spart *parts;
428

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

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

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

438
439
    /*! The star ghost task itself */
    struct task *ghost;
440

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

444
445
    /*! Number of #spart updated in this cell. */
    int updated;
446

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

450
451
    /*! Spin lock for various uses (#spart case). */
    swift_lock_type lock;
452

453
  } stars;
454

455
456
457
#ifdef WITH_MPI
  /*! MPI variables */
  struct {
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488

    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;

489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
    /* 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;
506

507
508
  } mpi;
#endif
509

510
511
  /*! The first kick task */
  struct task *kick1;
512

513
514
  /*! The second kick task */
  struct task *kick2;
515

516
517
518
519
520
521
522
523
  /*! The task to compute time-steps */
  struct task *timestep;

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

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

525
526
527
528
529
530
  /*! ID of the previous owner, e.g. runner. */
  int owner;

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

531
532
533
534
535
536
537
538
539
540
541
542
  /*! 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;

543
#ifdef SWIFT_DEBUG_CHECKS
544
545
546
  /* Cell ID (for debugging) */
  int cellID;

547
548
549
550
551
552
553
  /*! 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

554
} SWIFT_STRUCT_ALIGN;
555

556
557
558
559
/* Convert cell location to ID. */
#define cell_getid(cdim, i, j, k) \
  ((int)(k) + (cdim)[2] * ((int)(j) + (cdim)[1] * (int)(i)))

560
/* Function prototypes. */
561
562
void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
                struct cell_buff *buff, struct cell_buff *sbuff,
563
                struct cell_buff *gbuff);
564
void cell_sanitize(struct cell *c, int treated);
565
566
567
568
int cell_locktree(struct cell *c);
void cell_unlocktree(struct cell *c);
int cell_glocktree(struct cell *c);
void cell_gunlocktree(struct cell *c);
569
570
int cell_mlocktree(struct cell *c);
void cell_munlocktree(struct cell *c);
571
572
int cell_slocktree(struct cell *c);
void cell_sunlocktree(struct cell *c);
573
int cell_pack(struct cell *c, struct pcell *pc, const int with_gravity);
Matthieu Schaller's avatar
Matthieu Schaller committed
574
575
int cell_unpack(struct pcell *pc, struct cell *c, struct space *s,
                const int with_gravity);
576
577
int cell_pack_tags(const struct cell *c, int *tags);
int cell_unpack_tags(const int *tags, struct cell *c);
578
579
int cell_pack_end_step(struct cell *c, struct pcell_step *pcell);
int cell_unpack_end_step(struct cell *c, struct pcell_step *pcell);
580
581
int cell_pack_multipoles(struct cell *c, struct gravity_tensors *m);
int cell_unpack_multipoles(struct cell *c, struct gravity_tensors *m);
582
int cell_getsize(struct cell *c);
583
584
int cell_link_parts(struct cell *c, struct part *parts);
int cell_link_gparts(struct cell *c, struct gpart *gparts);
585
int cell_link_sparts(struct cell *c, struct spart *sparts);
586
void cell_clean_links(struct cell *c, void *data);
587
void cell_make_multipoles(struct cell *c, integertime_t ti_current);
588
589
void cell_check_multipole(struct cell *c);
void cell_check_foreign_multipole(const struct cell *c);
590
void cell_clean(struct cell *c);
591
592
void cell_check_part_drift_point(struct cell *c, void *data);
void cell_check_gpart_drift_point(struct cell *c, void *data);
593
void cell_check_multipole_drift_point(struct cell *c, void *data);
594
void cell_reset_task_counters(struct cell *c);
595
int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s);
596
int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s);
597
int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s);
598
void cell_set_super(struct cell *c, struct cell *super);
599
void cell_drift_part(struct cell *c, const struct engine *e, int force);
600
void cell_drift_gpart(struct cell *c, const struct engine *e, int force);
601
void cell_drift_multipole(struct cell *c, const struct engine *e);
602
void cell_drift_all_multipoles(struct cell *c, const struct engine *e);
603
void cell_check_timesteps(struct cell *c);
604
void cell_store_pre_drift_values(struct cell *c);
605
606
void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
                                       struct scheduler *s);
607
608
void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
                                      struct scheduler *s);
609
610
void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
                                       struct scheduler *s);
611
612
void cell_activate_subcell_external_grav_tasks(struct cell *ci,
                                               struct scheduler *s);
613
void cell_activate_drift_part(struct cell *c, struct scheduler *s);
614
void cell_activate_drift_gpart(struct cell *c, struct scheduler *s);
615
void cell_activate_sorts(struct cell *c, int sid, struct scheduler *s);
616
void cell_clear_drift_flags(struct cell *c, void *data);
Pedro Gonnet's avatar
Pedro Gonnet committed
617
void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data);
618
int cell_has_tasks(struct cell *c);
619
620
int cell_can_use_pair_mm(const struct cell *ci, const struct cell *cj,
                         const struct engine *e, const struct space *s);
621
int cell_can_use_pair_mm_rebuild(const struct cell *ci, const struct cell *cj,
Matthieu Schaller's avatar
Matthieu Schaller committed
622
                                 const struct engine *e, const struct space *s);
623
624
625
626
627
628
629
630
631

/* 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
632
633
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_pair_hydro_task(const struct cell *c) {
634
635
636
637
638

  /* 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 */
639
  return c->split && ((kernel_gamma * c->hydro.h_max_old +
640
                       c->hydro.dx_max_part_old) < 0.5f * c->dmin);
641
642
643
644
645
646
647
648
}

/**
 * @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
649
650
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_self_hydro_task(const struct cell *c) {
651

652
  /* Is the cell split and not smaller than the smoothing length? */
653
  return c->split && (kernel_gamma * c->hydro.h_max_old < 0.5f * c->dmin);
654
655
}

656
657
658
659
660
661
662
663
664
/**
 * @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) {

665
  // LOIC: To implement
666
667
668
669
670
671
672
673
674
675
676
677
  return 0;
}

/**
 * @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) {

678
  // LOIC: To implement
679
680
681
  return 0;
}

682
/**
683
 * @brief Can a pair hydro task associated with a cell be split into smaller
684
685
686
687
 * sub-tasks.
 *
 * @param c The #cell.
 */
688
__attribute__((always_inline)) INLINE static int cell_can_split_pair_hydro_task(
689
690
691
692
693
694
695
    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) */
696
697
  return c->split &&
         (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin);
698
699
700
}

/**
701
 * @brief Can a self hydro task associated with a cell be split into smaller
702
703
704
705
 * sub-tasks.
 *
 * @param c The #cell.
 */
706
__attribute__((always_inline)) INLINE static int cell_can_split_self_hydro_task(
707
708
709
    const struct cell *c) {

  /* Is the cell split ? */
710
711
  /* If so, is the cut-off radius with some leeway smaller than */
  /* the sub-cell sizes ? */
712
713
  /* 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 */
714
715
  return c->split &&
         (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin);
716
717
}

718
719
720
721
722
723
724
725
726
/**
 * @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) {

727
  // LOIC: To implement
728
729
730
731
732
733
734
735
736
737
738
739
  return 0;
}

/**
 * @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) {

740
  // LOIC: To implement
741
742
743
  return 0;
}

744
745
746
747
748
749
/**
 * @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
750
751
__attribute__((always_inline)) INLINE static int
cell_can_split_pair_gravity_task(const struct cell *c) {
752
753

  /* Is the cell split ? */
754
  return c->split && c->depth < space_subdepth_grav;
755
756
757
758
759
760
761
762
}

/**
 * @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
763
764
__attribute__((always_inline)) INLINE static int
cell_can_split_self_gravity_task(const struct cell *c) {
765
766

  /* Is the cell split ? */
767
  return c->split && c->depth < space_subdepth_grav;
768
769
}

770
771
772
773
774
775
776
777
778
779
780
781
782
/**
 * @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 */
783
  return (kernel_gamma * max(ci->hydro.h_max, cj->hydro.h_max) +
784
              ci->hydro.dx_max_part + cj->hydro.dx_max_part >
785
786
          cj->dmin);
}
787

788
/**
789
790
791
 * @brief Add a unique tag to a cell mostly for MPI communications.
 *
 * @param c The #cell to tag.
792
 */
793
__attribute__((always_inline)) INLINE static void cell_tag(struct cell *c) {
794
#ifdef WITH_MPI
795
796

#ifdef SWIFT_DEBUG_CHECKS
797
  if (c->mpi.tag > 0) error("setting tag for already tagged cell");
798
799
#endif

800
801
  if (c->mpi.tag < 0 &&
      (c->mpi.tag = atomic_inc(&cell_next_tag)) > cell_max_tag)
802
803
804
805
806
807
    error("Ran out of cell tags.");
#else
  error("SWIFT was not compiled with MPI enabled.");
#endif  // WITH_MPI
}

808
#endif /* SWIFT_CELL_H */