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

Loikki's avatar
Loikki committed
282
283
284
285
286
287
    /*! The logger task */
    struct task *logger;

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

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

291
292
    /*! Values of dx_max_sort before the drifts, used for sub-cell tasks. */
    float dx_max_sort_old;
293

294
295
    /*! Bit mask of sort directions that will be needed in the next timestep. */
    unsigned int requires_sorts;
296

297
298
    /*! Bit mask of sorts that need to be computed for this cell. */
    unsigned int do_sort;
299

300
301
    /*! Does this cell need to be drifted (hydro)? */
    char do_drift;
302

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

306
307
    /*! Do any of this cell's sub-cells need to be sorted? */
    char do_sub_sort;
308

309
310
    /*! Bit-mask indicating the sorted directions */
    unsigned int sorted;
311

312
313
    /*! The task computing this cell's sorts. */
    struct task *sorts;
314

315
316
    /*! The drift task for parts */
    struct task *drift;
317

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

321
322
    /* Linked list of the tasks computing this cell's hydro gradients. */
    struct link *gradient;
Loic Hausammann's avatar
Loic Hausammann committed
323

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

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

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

333
334
335
336
337
338
339
340
    /*! 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;
341

Matthieu Schaller's avatar
Matthieu Schaller committed
342
343
344
    /*! Task for star formation */
    struct task *star_formation;

345
#ifdef SWIFT_DEBUG_CHECKS
346

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

350
#endif
351

352
  } hydro;
353

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

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

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

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

367
368
    /*! Minimum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_min;
369

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

373
374
375
    /*! Maximum beginning of (integer) time step in this cell for gravity tasks.
     */
    integertime_t ti_beg_max;
376

377
    /*! Last (integer) time the cell's gpart were drifted forward in time. */
378
    integertime_t ti_old_part;
379

380
381
    /*! Last (integer) time the cell's multipole was drifted forward in time. */
    integertime_t ti_old_multipole;
382

383
    /*! Nr of #gpart in this cell. */
384
    int count;
385

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

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

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

395
396
397
    /*! Number of #gpart inhibited in this cell. */
    int inhibited;

398
    /*! Is the #gpart data of this cell being used in a sub-cell? */
399
    int phold;
400

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

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

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

410
    /*! The drift task for gparts */
411
    struct task *drift;
412

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

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

419
420
    /*! The multipole initialistation task */
    struct task *init;
421

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

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

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

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

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

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

440
  } grav;
441

442
443
  /*! Stars variables */
  struct {
444

445
446
    /*! Pointer to the #spart data. */
    struct spart *parts;
447

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

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

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

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

469
470
    /*! The star ghost task itself */
    struct task *ghost;
471

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

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

478
479
480
    /*! Number of #spart inhibited in this cell. */
    int inhibited;

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

484
485
    /*! Spin lock for various uses (#spart case). */
    swift_lock_type lock;
486

487
  } stars;
488

489
490
491
#ifdef WITH_MPI
  /*! MPI variables */
  struct {
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
520
521
522

    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;

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

541
542
  } mpi;
#endif
543

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

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

562
563
564
565
566
567
  /*! ID of the previous owner, e.g. runner. */
  int owner;

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

568
569
570
571
572
573
574
575
576
577
578
579
  /*! 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;

580
#ifdef SWIFT_DEBUG_CHECKS
581
582
583
  /* Cell ID (for debugging) */
  int cellID;

584
585
586
587
588
589
590
  /*! 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

591
} SWIFT_STRUCT_ALIGN;
592

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

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

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

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

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

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

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

/**
 * @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
729
730
  /* 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);
731
732
}

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

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

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

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

/**
 * @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
796
797
798
799
800
801
802
  /* 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);
803
804
}

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

  /* Is the cell split ? */
815
  return c->split && c->depth < space_subdepth_grav;
816
817
818
819
820
821
822
823
}

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

  /* Is the cell split ? */
828
  return c->split && c->depth < space_subdepth_grav;
829
830
}

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

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

#ifdef SWIFT_DEBUG_CHECKS
858
  if (c->mpi.tag > 0) error("setting tag for already tagged cell");
859
860
#endif

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

869
#endif /* SWIFT_CELL_H */