cell.h 22.4 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
96
    /*! Integer time of the last drift of the #part in this cell */
    integertime_t ti_old;
97

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

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

107
108
109
110
111
    /*! This cell's gravity-related tensors */
    struct multipole m_pole;
  
    /*! Centre of mass. */
    double CoM[3];
112

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

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

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

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

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

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

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

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

137
138
139
140
141
142
143
144
    /*! Number of #gpart in this cell. */
    int gcount;

  } grav;

  
  /*! Relative indices of the cell's progeny. */
  int progeny[8];
145
146
147
148

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

149
150
151
152
153
#ifdef SWIFT_DEBUG_CHECKS
  /* Cell ID (for debugging) */
  int cellID;
#endif

154
} SWIFT_STRUCT_ALIGN;
155

156
157
158
159
160
/**
 * @brief Cell information at the end of a time-step.
 */
struct pcell_step {

161
162
163
164
165
  /*! Hydro variables */
  struct {

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

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

170
171
    /*! Maximal distance any #part has travelled since last rebuild */
    float dx_max;
172

173
  } hydro;
174

175
176
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;
  } grav;
  
186
187
};

188
189
190
191
192
/**
 * @brief Cell within the tree structure.
 *
 * Contains particles, links to tasks, a multipole object and counters.
 */
193
194
struct cell {

195
  /*! The cell location on the grid. */
196
197
  double loc[3];

198
  /*! The cell dimensions. */
199
  double width[3];
200

201
202
  /*! Linking pointer for "memory management". */
  struct cell *next;
203

204
  /*! Pointer to the #spart data. */
205
  struct spart *sparts;
206

207
  /*! Pointers to the next level of cells. */
208
209
  struct cell *progeny[8];

210
  /*! Parent cell. */
211
212
  struct cell *parent;

213
  /*! Super cell, i.e. the highest-level parent cell with *any* task */
214
  struct cell *super;
215

216
217
  /*! Hydro variables */
  struct {
218

219
220
    /*! Pointer to the #part data. */
    struct part *parts;
221

222
223
    /*! Pointer to the #xpart data. */
    struct xpart *xparts;
224

225
226
    /*! Pointer for the sorted indices. */
    struct entry *sort[13];
227

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

232
233
    /*! Last (integer) time the cell's part were drifted forward in time. */
    integertime_t ti_old;
234

235
236
    /*! Maximum part movement in this cell since last construction. */
    float dx_max;
237

238
239
    /*! Maximum particle movement in this cell since the last sort. */
    float dx_max_sort;
240

241
242
    /*! Max smoothing length in this cell. */
    double h_max;
243

244
245
    /*! Minimum end of (integer) time step in this cell for hydro tasks. */
    integertime_t ti_end_min;
246

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

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

253
254
    /*! Nr of #part in this cell. */
    int count;
255

256
257
258
259
260
    /*! Spin lock for various uses (#part case). */
    swift_lock_type lock;
    
    /*! Number of #part updated in this cell. */
    int updated;
261

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

265
266
    /*! Values of dx_max before the drifts, used for sub-cell tasks. */
    float dx_max_old;
267

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

271
272
    /*! Values of dx_max_sort before the drifts, used for sub-cell tasks. */
    float dx_max_sort_old;
273

274
275
    /*! Bit mask of sort directions that will be needed in the next timestep. */
    unsigned int requires_sorts;
276

277
278
279
280
281
    /*! Bit mask of sorts that need to be computed for this cell. */
    unsigned int do_sort;
     
    /*! Does this cell need to be drifted (hydro)? */
    char do_drift;
282

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

286
287
288
289
290
    /*! Do any of this cell's sub-cells need to be sorted? */
    char do_sub_sort;
 
    /*! Bit-mask indicating the sorted directions */
    unsigned int sorted;
291

292
293
    /*! The task computing this cell's sorts. */
    struct task *sorts;
294

295
296
    /*! The drift task for parts */
    struct task *drift;
297

298
299
    /*! Linked list of the tasks computing this cell's hydro density. */
    struct link *density;
Loic Hausammann's avatar
Loic Hausammann committed
300

301
302
    /* Linked list of the tasks computing this cell's hydro gradients. */
    struct link *gradient;
Loic Hausammann's avatar
Loic Hausammann committed
303

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

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

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

313
314
315
316
317
318
319
320
321
322
323
    /*! 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;
324

325
#ifdef WITH_MPI
326
327
    /* Task receiving hydro data (positions). */
    struct task *recv_xv;
328

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

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

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

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

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

344
#endif
345

346
347
348
349
350
351
352
353
#ifdef SWIFT_DEBUG_CHECKS
    
    /*! Last (integer) time the cell's sort arrays were updated. */
    integertime_t ti_sort;
    
#endif
    
  } hydro;
354

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

358
359
    /*! Pointer to the #gpart data. */
    struct gpart *gparts;
360

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

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

368
369
370
371
372
    /*! Minimum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_min;
    
    /*! Maximum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_max;
373

374
375
376
377
378
379
    /*! Maximum beginning of (integer) time step in this cell for gravity tasks.
     */
    integertime_t ti_beg_max;
    
    /*! Last (integer) time the cell's gpart were drifted forward in time. */
    integertime_t ti_old_gpart;
380

381
382
383
384
385
    /*! Last (integer) time the cell's multipole was drifted forward in time. */
    integertime_t ti_old_multipole;
    
    /*! Nr of #gpart in this cell. */
    int gcount;
386

387
388
    /*! Spin lock for various uses (#gpart case). */
    swift_lock_type glock;
389

390
391
    /*! Spin lock for various uses (#multipole case). */
    swift_lock_type mlock;
392

393
394
    /*! Number of #gpart updated in this cell. */
    int g_updated;
395

396
397
    /*! Is the #gpart data of this cell being used in a sub-cell? */
    int ghold;
398

399
400
    /*! Is the #multipole data of this cell being used in a sub-cell? */
    int mhold;
401

402
403
    /*! Does this cell need to be drifted (gravity)? */
    char do_drift;
404

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

408
409
    /*! The drift task for gparts */
    struct task *drift_gpart;
410

411
412
    /*! Linked list of the tasks computing this cell's gravity forces. */
    struct link *grav;
413

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

417
418
    /*! The multipole initialistation task */
    struct task *init;
419

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

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

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

429
430
431
432
433
    /*! Task propagating the mesh forces to the particles */
    struct task *mesh;
    
    /*! Task propagating the multipole to the particles */
    struct task *down;
434

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

438
#ifdef WITH_MPI
439

440
441
    /* Task receiving gpart data. */
    struct task *recv;
442

443
444
    /* Linked list for sending gpart data. */
    struct link *send;
445

446
#endif
447

448
  } grav;
449

450
451
452
  
  /*! The first kick task */
  struct task *kick1;
453

454
455
  /*! The second kick task */
  struct task *kick2;
456

457
458
  /*! The task to compute time-steps */
  struct task *timestep;
459

460
461
  /*! Dependency implicit task for the star ghost  (in->ghost->out)*/
  struct task *stars_ghost_in;
462

463
464
  /*! Dependency implicit task for the star ghost  (in->ghost->out)*/
  struct task *stars_ghost_out;
465

466
467
  /*! The star ghost task itself */
  struct task *stars_ghost;
468

469
470
  /*! Linked list of the tasks computing this cell's star density. */
  struct link *stars_density;
471

472
473
  /*! Task for source terms */
  struct task *sourceterms;
474

475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
#ifdef WITH_MPI
  /*! MPI variables */
  struct {
    /* 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;
495

496
497
  } mpi;
#endif
498

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

502
503
  /*! Nr of #spart in this cell. */
  int scount;
504

505
506
  /*! Spin lock for various uses (#spart case). */
  swift_lock_type slock;
507

508
509
510
511
512
513
514
515
516
517
518
  /*! ID of the previous owner, e.g. runner. */
  int owner;

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

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

  /*! Is the #spart data of this cell being used in a sub-cell? */
  int shold;
519

520
521
522
523
524
525
526
527
528
529
530
531
  /*! 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;

532
#ifdef SWIFT_DEBUG_CHECKS
533
534
535
  /* Cell ID (for debugging) */
  int cellID;

536
537
538
539
540
541
542
  /*! 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

543
} SWIFT_STRUCT_ALIGN;
544

545
546
547
548
/* Convert cell location to ID. */
#define cell_getid(cdim, i, j, k) \
  ((int)(k) + (cdim)[2] * ((int)(j) + (cdim)[1] * (int)(i)))

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

/* 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
621
622
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_pair_hydro_task(const struct cell *c) {
623
624
625
626
627
628

  /* 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 &&
629
         ((kernel_gamma * c->hydro.h_max_old + c->hydro.dx_max_old) < 0.5f * c->dmin);
630
631
632
633
634
635
636
637
}

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

641
  /* Is the cell split and not smaller than the smoothing length? */
642
  return c->split && (kernel_gamma * c->hydro.h_max_old < 0.5f * c->dmin);
643
644
}

645
646
647
648
649
650
651
652
653
/**
 * @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) {

654
  // LOIC: To implement
655
656
657
658
659
660
661
662
663
664
665
666
  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) {

667
  // LOIC: To implement
668
669
670
  return 0;
}

671
/**
672
 * @brief Can a pair hydro task associated with a cell be split into smaller
673
674
675
676
 * sub-tasks.
 *
 * @param c The #cell.
 */
677
__attribute__((always_inline)) INLINE static int cell_can_split_pair_hydro_task(
678
679
680
681
682
683
684
    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) */
685
  return c->split && (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin);
686
687
688
}

/**
689
 * @brief Can a self hydro task associated with a cell be split into smaller
690
691
692
693
 * sub-tasks.
 *
 * @param c The #cell.
 */
694
__attribute__((always_inline)) INLINE static int cell_can_split_self_hydro_task(
695
696
697
    const struct cell *c) {

  /* Is the cell split ? */
698
699
  /* If so, is the cut-off radius with some leeway smaller than */
  /* the sub-cell sizes ? */
700
701
  /* 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 */
702
  return c->split && (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin);
703
704
}

705
706
707
708
709
710
711
712
713
/**
 * @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) {

714
  // LOIC: To implement
715
716
717
718
719
720
721
722
723
724
725
726
  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) {

727
  // LOIC: To implement
728
729
730
  return 0;
}

731
732
733
734
735
736
/**
 * @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
737
738
__attribute__((always_inline)) INLINE static int
cell_can_split_pair_gravity_task(const struct cell *c) {
739
740

  /* Is the cell split ? */
741
  return c->split && c->depth < space_subdepth_grav;
742
743
744
745
746
747
748
749
}

/**
 * @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
750
751
__attribute__((always_inline)) INLINE static int
cell_can_split_self_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
763
764
765
766
767
768
769
/**
 * @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 */
770
771
  return (kernel_gamma * max(ci->hydro.h_max, cj->hydro.h_max) + ci->hydro.dx_max +
              cj->hydro.dx_max >
772
773
          cj->dmin);
}
774

775
/**
776
777
778
 * @brief Add a unique tag to a cell mostly for MPI communications.
 *
 * @param c The #cell to tag.
779
 */
780
__attribute__((always_inline)) INLINE static void cell_tag(struct cell *c) {
781
#ifdef WITH_MPI
782
783

#ifdef SWIFT_DEBUG_CHECKS
784
  if (c->mpi.tag > 0) error("setting tag for already tagged cell");
785
786
#endif

787
  if (c->mpi.tag < 0 && (c->mpi.tag = atomic_inc(&cell_next_tag)) > cell_max_tag)
788
789
790
791
792
793
    error("Ran out of cell tags.");
#else
  error("SWIFT was not compiled with MPI enabled.");
#endif  // WITH_MPI
}

794
#endif /* SWIFT_CELL_H */