cell.h 25.1 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
  /*! Relative indices of the cell's progeny. */
  int progeny[8];
154

155
156
157
158
159
#ifdef SWIFT_DEBUG_CHECKS
  /* Cell ID (for debugging) */
  int cellID;
#endif

160
} SWIFT_STRUCT_ALIGN;
161

162
163
164
165
166
/**
 * @brief Cell information at the end of a time-step.
 */
struct pcell_step {

167
168
169
170
171
  /*! Hydro variables */
  struct {

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

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

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

179
  } hydro;
180

181
182
183
184
185
186
187
188
  /*! 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;
189

190
  } grav;
191
192
193

  /*! Stars variables */
  struct {
Loic Hausammann's avatar
Loic Hausammann committed
194
195
196
197

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

198
  } stars;
199
200
};

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

208
  /*! The cell location on the grid. */
209
210
  double loc[3];

211
  /*! The cell dimensions. */
212
  double width[3];
213

214
215
  /*! Linking pointer for "memory management". */
  struct cell *next;
216

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

220
  /*! Parent cell. */
221
222
  struct cell *parent;

223
  /*! Super cell, i.e. the highest-level parent cell with *any* task */
224
  struct cell *super;
225

226
227
  /*! Hydro variables */
  struct {
228

229
230
    /*! Pointer to the #part data. */
    struct part *parts;
231

232
233
    /*! Pointer to the #xpart data. */
    struct xpart *xparts;
234

235
236
    /*! Pointer for the sorted indices. */
    struct entry *sort[13];
237

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

242
    /*! Last (integer) time the cell's part were drifted forward in time. */
243
    integertime_t ti_old_part;
244

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

248
249
    /*! Maximum particle movement in this cell since the last sort. */
    float dx_max_sort;
250

251
252
    /*! Max smoothing length in this cell. */
    double h_max;
253

254
255
    /*! Minimum end of (integer) time step in this cell for hydro tasks. */
    integertime_t ti_end_min;
256

257
258
    /*! Maximum end of (integer) time step in this cell for hydro tasks. */
    integertime_t ti_end_max;
259

260
261
    /*! Maximum beginning of (integer) time step in this cell for hydro tasks.
     */
262
    integertime_t ti_beg_max;
263

264
265
    /*! Nr of #part in this cell. */
    int count;
266

267
268
    /*! Spin lock for various uses (#part case). */
    swift_lock_type lock;
269

270
271
    /*! Number of #part updated in this cell. */
    int updated;
272

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

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

279
280
    /*! Values of h_max before the drifts, used for sub-cell tasks. */
    float h_max_old;
281

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

285
286
    /*! Values of dx_max_sort before the drifts, used for sub-cell tasks. */
    float dx_max_sort_old;
287

288
289
    /*! Bit mask of sort directions that will be needed in the next timestep. */
    unsigned int requires_sorts;
290

291
292
    /*! Bit mask of sorts that need to be computed for this cell. */
    unsigned int do_sort;
293

294
295
    /*! Does this cell need to be drifted (hydro)? */
    char do_drift;
296

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

300
301
    /*! Do any of this cell's sub-cells need to be sorted? */
    char do_sub_sort;
302

303
304
    /*! Bit-mask indicating the sorted directions */
    unsigned int sorted;
305

306
307
    /*! The task computing this cell's sorts. */
    struct task *sorts;
308

309
310
    /*! The drift task for parts */
    struct task *drift;
311

312
313
    /*! Linked list of the tasks computing this cell's hydro density. */
    struct link *density;
Loic Hausammann's avatar
Loic Hausammann committed
314

315
316
    /* Linked list of the tasks computing this cell's hydro gradients. */
    struct link *gradient;
Loic Hausammann's avatar
Loic Hausammann committed
317

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

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

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

327
328
329
330
331
332
333
334
    /*! 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;
335

Matthieu Schaller's avatar
Matthieu Schaller committed
336
337
338
    /*! Task for star formation */
    struct task *star_formation;

339
#ifdef SWIFT_DEBUG_CHECKS
340

341
342
    /*! Last (integer) time the cell's sort arrays were updated. */
    integertime_t ti_sort;
343

344
#endif
345

346
  } hydro;
347

348
349
  /*! Grav variables */
  struct {
350

351
    /*! Pointer to the #gpart data. */
352
    struct gpart *parts;
353

354
355
    /*! This cell's multipole. */
    struct gravity_tensors *multipole;
356

357
358
359
    /*! Super cell, i.e. the highest-level parent cell that has a grav pair/self
     * tasks */
    struct cell *super;
360

361
362
    /*! Minimum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_min;
363

364
365
    /*! Maximum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_max;
366

367
368
369
    /*! Maximum beginning of (integer) time step in this cell for gravity tasks.
     */
    integertime_t ti_beg_max;
370

371
    /*! Last (integer) time the cell's gpart were drifted forward in time. */
372
    integertime_t ti_old_part;
373

374
375
    /*! Last (integer) time the cell's multipole was drifted forward in time. */
    integertime_t ti_old_multipole;
376

377
    /*! Nr of #gpart in this cell. */
378
    int count;
379

380
    /*! Spin lock for various uses (#gpart case). */
381
    swift_lock_type plock;
382

383
384
    /*! Spin lock for various uses (#multipole case). */
    swift_lock_type mlock;
385

386
    /*! Number of #gpart updated in this cell. */
387
    int updated;
388

389
390
391
    /*! Number of #gpart inhibited in this cell. */
    int inhibited;

392
    /*! Is the #gpart data of this cell being used in a sub-cell? */
393
    int phold;
394

395
396
    /*! Is the #multipole data of this cell being used in a sub-cell? */
    int mhold;
397

398
399
    /*! Does this cell need to be drifted (gravity)? */
    char do_drift;
400

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

404
    /*! The drift task for gparts */
405
    struct task *drift;
406

407
408
    /*! Linked list of the tasks computing this cell's gravity forces. */
    struct link *grav;
409

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

413
414
    /*! The multipole initialistation task */
    struct task *init;
415

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

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

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

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

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

431
432
    /*! Number of M-M tasks that are associated with this cell. */
    short int nr_mm_tasks;
433

434
  } grav;
435

436
437
  /*! Stars variables */
  struct {
438

439
440
    /*! Pointer to the #spart data. */
    struct spart *parts;
441

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

Loic Hausammann's avatar
Loic Hausammann committed
445
446
447
448
449
450
451
452
453
454
455
456
    /*! Max smoothing length in this cell. */
    double h_max;

    /*! 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;

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

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

463
464
    /*! The star ghost task itself */
    struct task *ghost;
465

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

469
470
    /*! Number of #spart updated in this cell. */
    int updated;
471

472
473
474
    /*! Number of #spart inhibited in this cell. */
    int inhibited;

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

478
479
    /*! Spin lock for various uses (#spart case). */
    swift_lock_type lock;
480

481
  } stars;
482

483
484
485
#ifdef WITH_MPI
  /*! MPI variables */
  struct {
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516

    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;

517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
    /* 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;
534

535
536
  } mpi;
#endif
537

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

541
542
  /*! The first kick task */
  struct task *kick1;
543

544
545
  /*! The second kick task */
  struct task *kick2;
546

547
548
549
550
551
552
  /*! The task to compute time-steps */
  struct task *timestep;

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

Loic Hausammann's avatar
Format    
Loic Hausammann committed
553
554
555
  /*! The logger task */
  struct task *logger;

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

559
560
561
562
563
564
  /*! ID of the previous owner, e.g. runner. */
  int owner;

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

565
566
567
568
569
570
571
572
573
574
575
576
  /*! 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;

577
#ifdef SWIFT_DEBUG_CHECKS
578
579
580
  /* Cell ID (for debugging) */
  int cellID;

581
582
583
584
585
586
587
  /*! 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

588
} SWIFT_STRUCT_ALIGN;
589

590
591
592
593
/* Convert cell location to ID. */
#define cell_getid(cdim, i, j, k) \
  ((int)(k) + (cdim)[2] * ((int)(j) + (cdim)[1] * (int)(i)))

594
/* Function prototypes. */
595
596
void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
                struct cell_buff *buff, struct cell_buff *sbuff,
597
                struct cell_buff *gbuff);
598
void cell_sanitize(struct cell *c, int treated);
599
600
601
602
int cell_locktree(struct cell *c);
void cell_unlocktree(struct cell *c);
int cell_glocktree(struct cell *c);
void cell_gunlocktree(struct cell *c);
603
604
int cell_mlocktree(struct cell *c);
void cell_munlocktree(struct cell *c);
605
606
int cell_slocktree(struct cell *c);
void cell_sunlocktree(struct cell *c);
607
int cell_pack(struct cell *c, struct pcell *pc, const int with_gravity);
Matthieu Schaller's avatar
Matthieu Schaller committed
608
609
int cell_unpack(struct pcell *pc, struct cell *c, struct space *s,
                const int with_gravity);
610
611
int cell_pack_tags(const struct cell *c, int *tags);
int cell_unpack_tags(const int *tags, struct cell *c);
612
613
int cell_pack_end_step(struct cell *c, struct pcell_step *pcell);
int cell_unpack_end_step(struct cell *c, struct pcell_step *pcell);
614
615
int cell_pack_multipoles(struct cell *c, struct gravity_tensors *m);
int cell_unpack_multipoles(struct cell *c, struct gravity_tensors *m);
616
int cell_getsize(struct cell *c);
617
618
int cell_link_parts(struct cell *c, struct part *parts);
int cell_link_gparts(struct cell *c, struct gpart *gparts);
619
int cell_link_sparts(struct cell *c, struct spart *sparts);
620
void cell_clean_links(struct cell *c, void *data);
621
void cell_make_multipoles(struct cell *c, integertime_t ti_current);
622
623
void cell_check_multipole(struct cell *c);
void cell_check_foreign_multipole(const struct cell *c);
624
void cell_clean(struct cell *c);
625
626
void cell_check_part_drift_point(struct cell *c, void *data);
void cell_check_gpart_drift_point(struct cell *c, void *data);
627
void cell_check_multipole_drift_point(struct cell *c, void *data);
628
void cell_reset_task_counters(struct cell *c);
629
int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s);
630
int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s);
631
int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s);
632
void cell_set_super(struct cell *c, struct cell *super);
633
void cell_drift_part(struct cell *c, const struct engine *e, int force);
634
void cell_drift_gpart(struct cell *c, const struct engine *e, int force);
635
void cell_drift_multipole(struct cell *c, const struct engine *e);
636
void cell_drift_all_multipoles(struct cell *c, const struct engine *e);
637
void cell_check_timesteps(struct cell *c);
638
void cell_store_pre_drift_values(struct cell *c);
639
640
void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
                                       struct scheduler *s);
641
642
void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
                                      struct scheduler *s);
643
644
void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
                                       struct scheduler *s);
645
646
void cell_activate_subcell_external_grav_tasks(struct cell *ci,
                                               struct scheduler *s);
647
void cell_activate_drift_part(struct cell *c, struct scheduler *s);
648
void cell_activate_drift_gpart(struct cell *c, struct scheduler *s);
649
void cell_activate_sorts(struct cell *c, int sid, struct scheduler *s);
650
void cell_clear_drift_flags(struct cell *c, void *data);
Pedro Gonnet's avatar
Pedro Gonnet committed
651
void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data);
652
int cell_has_tasks(struct cell *c);
653
654
void cell_remove_part(const struct engine *e, struct cell *c, struct part *p,
                      struct xpart *xp);
655
656
657
658
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);
659
660
661
void cell_convert_part_to_gpart(const struct engine *e, struct cell *c,
                                struct part *p, struct xpart *xp);
void cell_convert_spart_to_gpart(const struct engine *e, struct cell *c,
662
                                 struct spart *sp);
663
664
int cell_can_use_pair_mm(const struct cell *ci, const struct cell *cj,
                         const struct engine *e, const struct space *s);
665
int cell_can_use_pair_mm_rebuild(const struct cell *ci, const struct cell *cj,
Matthieu Schaller's avatar
Matthieu Schaller committed
666
                                 const struct engine *e, const struct space *s);
667
668
669
670
671
672
673
674
675

/* 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
676
677
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_pair_hydro_task(const struct cell *c) {
678
679
680
681
682

  /* 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 */
683
  return c->split && ((kernel_gamma * c->hydro.h_max_old +
684
                       c->hydro.dx_max_part_old) < 0.5f * c->dmin);
685
686
687
688
689
690
691
692
}

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

696
  /* Is the cell split and not smaller than the smoothing length? */
697
  return c->split && (kernel_gamma * c->hydro.h_max_old < 0.5f * c->dmin);
698
699
}

700
701
702
703
704
705
706
707
708
/**
 * @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
709
710
711
712
713
714
  /* 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);
715
716
717
718
719
720
721
722
723
724
725
}

/**
 * @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
726
727
  /* 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);
728
729
}

730
/**
731
 * @brief Can a pair hydro task associated with a cell be split into smaller
732
733
734
735
 * sub-tasks.
 *
 * @param c The #cell.
 */
736
__attribute__((always_inline)) INLINE static int cell_can_split_pair_hydro_task(
737
738
739
740
741
742
743
    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) */
744
745
  return c->split &&
         (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin);
746
747
748
}

/**
749
 * @brief Can a self hydro task associated with a cell be split into smaller
750
751
752
753
 * sub-tasks.
 *
 * @param c The #cell.
 */
754
__attribute__((always_inline)) INLINE static int cell_can_split_self_hydro_task(
755
756
757
    const struct cell *c) {

  /* Is the cell split ? */
758
759
  /* If so, is the cut-off radius with some leeway smaller than */
  /* the sub-cell sizes ? */
760
761
  /* 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 */
762
763
  return c->split &&
         (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin);
764
765
}

766
767
768
769
770
771
772
773
774
/**
 * @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
775
776
777
778
779
780
781
  /* 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);
782
783
784
785
786
787
788
789
790
791
792
}

/**
 * @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
793
794
795
796
797
798
799
  /* 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);
800
801
}

802
803
804
805
806
807
/**
 * @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
808
809
__attribute__((always_inline)) INLINE static int
cell_can_split_pair_gravity_task(const struct cell *c) {
810

811
812
  /* Is the cell split and still far from the leaves ? */
  return c->split && ((c->maxdepth - c->depth) > space_subdepth_diff_grav);
813
814
815
816
817
818
819
820
}

/**
 * @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
821
822
__attribute__((always_inline)) INLINE static int
cell_can_split_self_gravity_task(const struct cell *c) {
823

824
825
  /* Is the cell split and still far from the leaves ? */
  return c->split && ((c->maxdepth - c->depth) > space_subdepth_diff_grav);
826
827
}

828
829
830
831
832
833
834
835
836
837
838
839
840
/**
 * @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 */
841
  return (kernel_gamma * max(ci->hydro.h_max, cj->hydro.h_max) +
842
              ci->hydro.dx_max_part + cj->hydro.dx_max_part >
843
844
          cj->dmin);
}
845

846
/**
847
848
849
 * @brief Add a unique tag to a cell mostly for MPI communications.
 *
 * @param c The #cell to tag.
850
 */
851
__attribute__((always_inline)) INLINE static void cell_tag(struct cell *c) {
852
#ifdef WITH_MPI
853
854

#ifdef SWIFT_DEBUG_CHECKS
855
  if (c->mpi.tag > 0) error("setting tag for already tagged cell");
856
857
#endif

858
859
  if (c->mpi.tag < 0 &&
      (c->mpi.tag = atomic_inc(&cell_next_tag)) > cell_max_tag)
860
861
862
863
864
865
    error("Ran out of cell tags.");
#else
  error("SWIFT was not compiled with MPI enabled.");
#endif  // WITH_MPI
}

866
#endif /* SWIFT_CELL_H */