cell.h 25.3 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
409
    /*! Implicit task (going up- and down the tree) for the #gpart drifts */
    struct task *drift_out;

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

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

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

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

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

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

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

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

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

437
  } grav;
438

439
440
  /*! Stars variables */
  struct {
441

442
443
    /*! Pointer to the #spart data. */
    struct spart *parts;
444

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

Loic Hausammann's avatar
Loic Hausammann committed
448
449
450
451
452
453
454
455
456
457
458
459
    /*! 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;

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

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

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

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

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

475
476
477
    /*! Number of #spart inhibited in this cell. */
    int inhibited;

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

481
482
    /*! Spin lock for various uses (#spart case). */
    swift_lock_type lock;
483

484
  } stars;
485

486
487
488
#ifdef WITH_MPI
  /*! MPI variables */
  struct {
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
517
518
519

    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;

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

538
539
  } mpi;
#endif
540

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

544
545
546
  /*! Implicit task (going up- and down the tree) for the end force */
  struct task *end_force_in;

547
548
  /*! The first kick task */
  struct task *kick1;
549

550
551
  /*! The second kick task */
  struct task *kick2;
552

553
554
555
556
557
558
  /*! The task to compute time-steps */
  struct task *timestep;

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

Loic Hausammann's avatar
Format    
Loic Hausammann committed
559
560
561
  /*! The logger task */
  struct task *logger;

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

565
566
567
568
569
570
  /*! ID of the previous owner, e.g. runner. */
  int owner;

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

571
572
573
574
575
576
577
578
579
580
581
582
  /*! 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;

583
#ifdef SWIFT_DEBUG_CHECKS
584
585
586
  /* Cell ID (for debugging) */
  int cellID;

587
588
589
590
591
592
593
  /*! 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

594
} SWIFT_STRUCT_ALIGN;
595

596
597
598
599
/* Convert cell location to ID. */
#define cell_getid(cdim, i, j, k) \
  ((int)(k) + (cdim)[2] * ((int)(j) + (cdim)[1] * (int)(i)))

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

/* 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
682
683
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_pair_hydro_task(const struct cell *c) {
684
685
686
687
688

  /* 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 */
689
  return c->split && ((kernel_gamma * c->hydro.h_max_old +
690
                       c->hydro.dx_max_part_old) < 0.5f * c->dmin);
691
692
693
694
695
696
697
698
}

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

702
  /* Is the cell split and not smaller than the smoothing length? */
703
  return c->split && (kernel_gamma * c->hydro.h_max_old < 0.5f * c->dmin);
704
705
}

706
707
708
709
710
711
712
713
714
/**
 * @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
715
716
717
718
719
720
  /* 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);
721
722
723
724
725
726
727
728
729
730
731
}

/**
 * @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
732
733
  /* 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);
734
735
}

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

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

  /* Is the cell split ? */
764
765
  /* If so, is the cut-off radius with some leeway smaller than */
  /* the sub-cell sizes ? */
766
767
  /* 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 */
768
769
  return c->split &&
         (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin);
770
771
}

772
773
774
775
776
777
778
779
780
/**
 * @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
781
782
783
784
785
786
787
  /* 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);
788
789
790
791
792
793
794
795
796
797
798
}

/**
 * @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
799
800
801
802
803
804
805
  /* 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);
806
807
}

808
809
810
811
812
813
/**
 * @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
814
815
__attribute__((always_inline)) INLINE static int
cell_can_split_pair_gravity_task(const struct cell *c) {
816

817
818
  /* Is the cell split and still far from the leaves ? */
  return c->split && ((c->maxdepth - c->depth) > space_subdepth_diff_grav);
819
820
821
822
823
824
825
826
}

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

830
831
  /* Is the cell split and still far from the leaves ? */
  return c->split && ((c->maxdepth - c->depth) > space_subdepth_diff_grav);
832
833
}

834
835
836
837
838
839
840
841
842
843
844
845
846
/**
 * @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 */
847
  return (kernel_gamma * max(ci->hydro.h_max, cj->hydro.h_max) +
848
              ci->hydro.dx_max_part + cj->hydro.dx_max_part >
849
850
          cj->dmin);
}
851

852
/**
853
854
855
 * @brief Add a unique tag to a cell mostly for MPI communications.
 *
 * @param c The #cell to tag.
856
 */
857
__attribute__((always_inline)) INLINE static void cell_tag(struct cell *c) {
858
#ifdef WITH_MPI
859
860

#ifdef SWIFT_DEBUG_CHECKS
861
  if (c->mpi.tag > 0) error("setting tag for already tagged cell");
862
863
#endif

864
865
  if (c->mpi.tag < 0 &&
      (c->mpi.tag = atomic_inc(&cell_next_tag)) > cell_max_tag)
866
867
868
869
870
871
    error("Ran out of cell tags.");
#else
  error("SWIFT was not compiled with MPI enabled.");
#endif  // WITH_MPI
}

872
#endif /* SWIFT_CELL_H */