cell.h 33.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
    /*! 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
152
    /*! Minimal integer end-of-timestep in this cell for stars tasks */
    integertime_t ti_end_min;

153
154
155
    /*! Maximal integer end-of-timestep in this cell for stars tasks */
    integertime_t ti_end_max;

156
157
158
    /*! Integer time of the last drift of the #spart in this cell */
    integertime_t ti_old_part;

159
160
  } stars;

161
162
163
  /*! Maximal depth in that part of the tree */
  int maxdepth;

164
165
  /*! Relative indices of the cell's progeny. */
  int progeny[8];
166

167
168
169
170
171
#ifdef SWIFT_DEBUG_CHECKS
  /* Cell ID (for debugging) */
  int cellID;
#endif

172
} SWIFT_STRUCT_ALIGN;
173

174
175
176
177
178
/**
 * @brief Cell information at the end of a time-step.
 */
struct pcell_step {

179
180
181
182
183
  /*! Hydro variables */
  struct {

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

185
186
    /*! Minimal integer end-of-timestep in this cell (hydro) */
    integertime_t ti_end_max;
187

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

191
  } hydro;
192

193
194
195
196
197
198
199
200
  /*! 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;
201

202
  } grav;
203
204
205

  /*! Stars variables */
  struct {
Loic Hausammann's avatar
Loic Hausammann committed
206

207
208
209
    /*! Minimal integer end-of-timestep in this cell (stars) */
    integertime_t ti_end_min;

210
211
212
213
214
215
    /*! Maximal integer end-of-timestep in this cell (stars) */
    integertime_t ti_end_max;
    
    /*! Maximal distance any #part has travelled since last rebuild */
    float dx_max_part;

216
  } stars;
217
218
};

219
220
221
222
223
/**
 * @brief Cell within the tree structure.
 *
 * Contains particles, links to tasks, a multipole object and counters.
 */
224
225
struct cell {

226
  /*! The cell location on the grid. */
227
228
  double loc[3];

229
  /*! The cell dimensions. */
230
  double width[3];
231

232
  /*! Pointers to the next level of cells. */
233
234
  struct cell *progeny[8];

235
236
237
  /*! Linking pointer for "memory management". */
  struct cell *next;

238
  /*! Parent cell. */
239
240
  struct cell *parent;

241
  /*! Super cell, i.e. the highest-level parent cell with *any* task */
242
  struct cell *super;
243

244
245
  /*! Hydro variables */
  struct {
246

247
248
    /*! Pointer to the #part data. */
    struct part *parts;
249

250
251
    /*! Pointer to the #xpart data. */
    struct xpart *xparts;
252

253
254
    /*! Pointer for the sorted indices. */
    struct entry *sort[13];
255

256
257
    /*! Super cell, i.e. the highest-level parent cell that has a hydro
     * pair/self tasks */
258
    struct cell *super;
259

260
261
    /*! The task computing this cell's sorts. */
    struct task *sorts;
262

263
264
    /*! The drift task for parts */
    struct task *drift;
265

266
267
268
269
270
271
272
273
274
    /*! Linked list of the tasks computing this cell's hydro density. */
    struct link *density;

    /* Linked list of the tasks computing this cell's hydro gradients. */
    struct link *gradient;

    /*! Linked list of the tasks computing this cell's hydro forces. */
    struct link *force;

275
276
277
    /*! Linked list of the tasks computing this cell's limiter. */
    struct link *limiter;

278
279
280
281
282
283
284
285
286
287
288
289
    /*! Dependency implicit task for the ghost  (in->ghost->out)*/
    struct task *ghost_in;

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

    /*! The ghost task itself */
    struct task *ghost;

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

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

293
294
295
296
297
    /*! Task for cooling */
    struct task *cooling;

    /*! Task for star formation */
    struct task *star_formation;
298

299
300
    /*! Max smoothing length in this cell. */
    double h_max;
301

302
303
304
    /*! Last (integer) time the cell's part were drifted forward in time. */
    integertime_t ti_old_part;

305
306
    /*! Minimum end of (integer) time step in this cell for hydro tasks. */
    integertime_t ti_end_min;
307

308
309
    /*! Maximum end of (integer) time step in this cell for hydro tasks. */
    integertime_t ti_end_max;
310

311
312
    /*! Maximum beginning of (integer) time step in this cell for hydro tasks.
     */
313
    integertime_t ti_beg_max;
314

315
316
    /*! Spin lock for various uses (#part case). */
    swift_lock_type lock;
317

318
319
    /*! Maximum part movement in this cell since last construction. */
    float dx_max_part;
320

321
322
    /*! Maximum particle movement in this cell since the last sort. */
    float dx_max_sort;
323

324
325
    /*! Values of h_max before the drifts, used for sub-cell tasks. */
    float h_max_old;
326

327
328
329
    /*! Values of dx_max before the drifts, used for sub-cell tasks. */
    float dx_max_part_old;

330
331
    /*! Values of dx_max_sort before the drifts, used for sub-cell tasks. */
    float dx_max_sort_old;
332

333
334
335
    /*! Nr of #part in this cell. */
    int count;

336
337
338
    /*! Nr of #part this cell can hold after addition of new #part. */
    int count_total;

339
340
341
342
343
344
345
346
347
    /*! Number of #part updated in this cell. */
    int updated;

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

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

348
349
    /*! Bit mask of sort directions that will be needed in the next timestep. */
    unsigned int requires_sorts;
350

351
352
    /*! Bit mask of sorts that need to be computed for this cell. */
    unsigned int do_sort;
353

354
355
356
    /*! Bit-mask indicating the sorted directions */
    unsigned int sorted;

357
358
    /*! Does this cell need to be drifted (hydro)? */
    char do_drift;
359

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

363
364
    /*! Do any of this cell's sub-cells need to be sorted? */
    char do_sub_sort;
365

366
367
368
369
370
371
    /*! Does this cell need to be limited? */
    char do_limiter;

    /*! Do any of this cell's sub-cells need to be limited? */
    char do_sub_limiter;

Matthieu Schaller's avatar
Matthieu Schaller committed
372
#ifdef SWIFT_DEBUG_CHECKS
373

374
375
    /*! Last (integer) time the cell's sort arrays were updated. */
    integertime_t ti_sort;
376

377
#endif
378

379
  } hydro;
380

381
382
  /*! Grav variables */
  struct {
383

384
    /*! Pointer to the #gpart data. */
385
    struct gpart *parts;
386

387
388
    /*! This cell's multipole. */
    struct gravity_tensors *multipole;
389

390
391
392
    /*! Super cell, i.e. the highest-level parent cell that has a grav pair/self
     * tasks */
    struct cell *super;
393

394
395
396
    /*! The drift task for gparts */
    struct task *drift;

397
398
399
    /*! Implicit task (going up- and down the tree) for the #gpart drifts */
    struct task *drift_out;

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
    /*! Linked list of the tasks computing this cell's gravity forces. */
    struct link *grav;

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

    /*! The multipole initialistation task */
    struct task *init;

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

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

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

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

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

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

427
428
    /*! Minimum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_min;
429

430
431
    /*! Maximum end of (integer) time step in this cell for gravity tasks. */
    integertime_t ti_end_max;
432

433
434
435
    /*! Maximum beginning of (integer) time step in this cell for gravity tasks.
     */
    integertime_t ti_beg_max;
436

437
    /*! Last (integer) time the cell's gpart were drifted forward in time. */
438
    integertime_t ti_old_part;
439

440
441
    /*! Last (integer) time the cell's multipole was drifted forward in time. */
    integertime_t ti_old_multipole;
442

443
    /*! Spin lock for various uses (#gpart case). */
444
    swift_lock_type plock;
445

446
447
    /*! Spin lock for various uses (#multipole case). */
    swift_lock_type mlock;
448

449
450
451
    /*! Nr of #gpart in this cell. */
    int count;

452
453
454
    /*! Nr of #gpart this cell can hold after addition of new #gpart. */
    int count_total;

455
    /*! Number of #gpart updated in this cell. */
456
    int updated;
457

458
459
460
    /*! Number of #gpart inhibited in this cell. */
    int inhibited;

461
    /*! Is the #gpart data of this cell being used in a sub-cell? */
462
    int phold;
463

464
465
    /*! Is the #multipole data of this cell being used in a sub-cell? */
    int mhold;
466

467
468
469
    /*! Number of M-M tasks that are associated with this cell. */
    short int nr_mm_tasks;

470
471
    /*! Does this cell need to be drifted (gravity)? */
    char do_drift;
472

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

476
  } grav;
477

478
479
  /*! Stars variables */
  struct {
480

481
482
    /*! Pointer to the #spart data. */
    struct spart *parts;
483

484
485
486
487
488
    /*! The star ghost task itself */
    struct task *ghost;

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

Alexei Borissov's avatar
Alexei Borissov committed
490
491
492
    /*! Linked list of the tasks computing this cell's star feedback. */
    struct link *feedback;

493
    /*! The task computing this cell's sorts before the density. */
494
    struct task *sorts;
Matthieu Schaller's avatar
Matthieu Schaller committed
495

496
    /*! The drift task for sparts */
497
    struct task *drift;
498

499
500
501
502
    struct task *stars_in;

    struct task *stars_out;

Loic Hausammann's avatar
Loic Hausammann committed
503
504
505
    /*! Max smoothing length in this cell. */
    double h_max;

506
507
508
    /*! Last (integer) time the cell's spart were drifted forward in time. */
    integertime_t ti_old_part;

509
510
511
512
513
514
    /*! Spin lock for various uses (#spart case). */
    swift_lock_type lock;

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

515
516
517
    /*! Nr of #spart this cell can hold after addition of new #spart. */
    int count_total;

Loic Hausammann's avatar
Loic Hausammann committed
518
519
520
521
522
523
524
525
526
    /*! 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;

Matthieu Schaller's avatar
Matthieu Schaller committed
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
    /*! Maximum particle movement in this cell since the last sort. */
    float dx_max_sort;

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

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

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

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

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

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

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

551
552
553
554
555
556
557
    /*! Maximum end of (integer) time step in this cell for star tasks. */
    integertime_t ti_end_max;

    /*! Maximum beginning of (integer) time step in this cell for star tasks.
     */
    integertime_t ti_beg_max;
    
558
559
    /*! Number of #spart updated in this cell. */
    int updated;
560

561
562
563
    /*! Number of #spart inhibited in this cell. */
    int inhibited;

564
565
    /*! Is the #spart data of this cell being used in a sub-cell? */
    int hold;
566

567
568
569
570
571
572
    /*! Does this cell need to be drifted (stars)? */
    char do_drift;

    /*! Do any of this cell's sub-cells need to be drifted (stars)? */
    char do_sub_drift;

Matthieu Schaller's avatar
Matthieu Schaller committed
573
574
575
576
577
#ifdef SWIFT_DEBUG_CHECKS
    /*! Last (integer) time the cell's sort arrays were updated. */
    integertime_t ti_sort;
#endif

578
  } stars;
579

580
581
582
#ifdef WITH_MPI
  /*! MPI variables */
  struct {
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613

    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;

614
    struct {
615
      /* Task receiving spart data. */
616
      struct task *recv;
617

618
619
620
621
622
623
      /* Linked list for sending spart data. */
      struct link *send;
    } stars;

    struct {
      /* Task receiving limiter data. */
624
625
      struct task *recv;

626
      /* Linked list for sending limiter data. */
627
628
629
      struct link *send;
    } limiter;

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
    /* 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;
647

648
649
  } mpi;
#endif
650

651
652
  /*! The first kick task */
  struct task *kick1;
653

654
655
  /*! The second kick task */
  struct task *kick2;
656

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

660
661
  /*! The task to limit the time-step of inactive particles */
  struct task *timestep_limiter;
662

Loic Hausammann's avatar
Format    
Loic Hausammann committed
663
664
665
  /*! The logger task */
  struct task *logger;

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

669
670
671
672
673
674
  /*! ID of the previous owner, e.g. runner. */
  int owner;

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

675
676
677
678
679
680
681
682
683
684
685
686
  /*! 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;

687
#ifdef SWIFT_DEBUG_CHECKS
688
689
690
  /* Cell ID (for debugging) */
  int cellID;

691
692
693
694
695
696
697
  /*! 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

698
} SWIFT_STRUCT_ALIGN;
699

700
701
702
703
/* Convert cell location to ID. */
#define cell_getid(cdim, i, j, k) \
  ((int)(k) + (cdim)[2] * ((int)(j) + (cdim)[1] * (int)(i)))

704
/* Function prototypes. */
705
706
void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset,
                struct cell_buff *buff, struct cell_buff *sbuff,
707
                struct cell_buff *gbuff);
708
void cell_sanitize(struct cell *c, int treated);
709
710
711
712
int cell_locktree(struct cell *c);
void cell_unlocktree(struct cell *c);
int cell_glocktree(struct cell *c);
void cell_gunlocktree(struct cell *c);
713
714
int cell_mlocktree(struct cell *c);
void cell_munlocktree(struct cell *c);
715
716
int cell_slocktree(struct cell *c);
void cell_sunlocktree(struct cell *c);
717
int cell_pack(struct cell *c, struct pcell *pc, const int with_gravity);
Matthieu Schaller's avatar
Matthieu Schaller committed
718
719
int cell_unpack(struct pcell *pc, struct cell *c, struct space *s,
                const int with_gravity);
720
721
int cell_pack_tags(const struct cell *c, int *tags);
int cell_unpack_tags(const int *tags, struct cell *c);
722
723
int cell_pack_end_step(struct cell *c, struct pcell_step *pcell);
int cell_unpack_end_step(struct cell *c, struct pcell_step *pcell);
724
725
int cell_pack_multipoles(struct cell *c, struct gravity_tensors *m);
int cell_unpack_multipoles(struct cell *c, struct gravity_tensors *m);
726
int cell_getsize(struct cell *c);
727
int cell_link_parts(struct cell *c, struct part *parts);
728
int cell_link_gparts(struct cell *c, struct gpart *gparts);
729
int cell_link_sparts(struct cell *c, struct spart *sparts);
730
731
int cell_link_foreign_parts(struct cell *c, struct part *parts);
int cell_link_foreign_gparts(struct cell *c, struct gpart *gparts);
732
int cell_count_parts_for_tasks(const struct cell *c);
733
int cell_count_gparts_for_tasks(const struct cell *c);
734
void cell_clean_links(struct cell *c, void *data);
735
void cell_make_multipoles(struct cell *c, integertime_t ti_current);
736
737
void cell_check_multipole(struct cell *c);
void cell_check_foreign_multipole(const struct cell *c);
738
void cell_clean(struct cell *c);
739
740
void cell_check_part_drift_point(struct cell *c, void *data);
void cell_check_gpart_drift_point(struct cell *c, void *data);
741
void cell_check_spart_drift_point(struct cell *c, void *data);
742
void cell_check_multipole_drift_point(struct cell *c, void *data);
743
void cell_reset_task_counters(struct cell *c);
744
int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s);
745
int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s);
746
int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s);
747
void cell_set_super(struct cell *c, struct cell *super);
748
void cell_drift_part(struct cell *c, const struct engine *e, int force);
749
void cell_drift_gpart(struct cell *c, const struct engine *e, int force);
750
void cell_drift_spart(struct cell *c, const struct engine *e, int force);
751
void cell_drift_multipole(struct cell *c, const struct engine *e);
752
void cell_drift_all_multipoles(struct cell *c, const struct engine *e);
753
void cell_check_timesteps(struct cell *c);
754
void cell_store_pre_drift_values(struct cell *c);
755
756
void cell_activate_subcell_hydro_tasks(struct cell *ci, struct cell *cj,
                                       struct scheduler *s);
757
758
void cell_activate_subcell_grav_tasks(struct cell *ci, struct cell *cj,
                                      struct scheduler *s);
759
760
void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj,
                                       struct scheduler *s);
761
762
void cell_activate_subcell_external_grav_tasks(struct cell *ci,
                                               struct scheduler *s);
763
void cell_activate_drift_part(struct cell *c, struct scheduler *s);
764
void cell_activate_drift_gpart(struct cell *c, struct scheduler *s);
Loic Hausammann's avatar
Loic Hausammann committed
765
void cell_activate_drift_spart(struct cell *c, struct scheduler *s);
766
void cell_activate_hydro_sorts(struct cell *c, int sid, struct scheduler *s);
Loic Hausammann's avatar
Loic Hausammann committed
767
void cell_activate_stars_sorts(struct cell *c, int sid, struct scheduler *s);
768
void cell_activate_limiter(struct cell *c, struct scheduler *s);
769
void cell_clear_drift_flags(struct cell *c, void *data);
770
void cell_clear_limiter_flags(struct cell *c, void *data);
Pedro Gonnet's avatar
Pedro Gonnet committed
771
void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data);
772
773
void cell_check_spart_pos(const struct cell *c,
                          const struct spart *global_sparts);
774
void cell_clear_stars_sort_flags(struct cell *c, const int is_super);
775
int cell_has_tasks(struct cell *c);
776
777
void cell_remove_part(const struct engine *e, struct cell *c, struct part *p,
                      struct xpart *xp);
778
779
780
781
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);
782
struct spart *cell_add_spart(struct engine *e, struct cell *c);
Matthieu Schaller's avatar
Matthieu Schaller committed
783
784
785
786
struct gpart *cell_convert_part_to_gpart(const struct engine *e, struct cell *c,
                                         struct part *p, struct xpart *xp);
struct gpart *cell_convert_spart_to_gpart(const struct engine *e,
                                          struct cell *c, struct spart *sp);
787
788
struct spart *cell_convert_part_to_spart(struct engine *e, struct cell *c,
                                         struct part *p, struct xpart *xp);
789
void cell_reorder_extra_parts(struct cell *c, const ptrdiff_t parts_offset);
790
791
void cell_reorder_extra_gparts(struct cell *c, struct part *parts,
                               struct spart *sparts);
792
void cell_reorder_extra_sparts(struct cell *c, const ptrdiff_t sparts_offset);
793
794
int cell_can_use_pair_mm(const struct cell *ci, const struct cell *cj,
                         const struct engine *e, const struct space *s);
795
int cell_can_use_pair_mm_rebuild(const struct cell *ci, const struct cell *cj,
Matthieu Schaller's avatar
Matthieu Schaller committed
796
                                 const struct engine *e, const struct space *s);
797

798
/**
Peter W. Draper's avatar
Peter W. Draper committed
799
 * @brief Compute the square of the minimal distance between any two points in
Matthieu Schaller's avatar
Matthieu Schaller committed
800
 * two cells of the same size
801
802
803
804
805
806
 *
 * @param ci The first #cell.
 * @param cj The second #cell.
 * @param periodic Are we using periodic BCs?
 * @param dim The dimensions of the simulation volume
 */
Matthieu Schaller's avatar
Matthieu Schaller committed
807
808
809
__attribute__((always_inline)) INLINE static double cell_min_dist2_same_size(
    const struct cell *restrict ci, const struct cell *restrict cj,
    const int periodic, const double dim[3]) {
810
811

#ifdef SWIFT_DEBUG_CHECKS
Matthieu Schaller's avatar
Matthieu Schaller committed
812
813
814
  if (ci->width[0] != cj->width[0]) error("Cells of different size!");
  if (ci->width[1] != cj->width[1]) error("Cells of different size!");
  if (ci->width[2] != cj->width[2]) error("Cells of different size!");
815
816
#endif

Matthieu Schaller's avatar
Matthieu Schaller committed
817
818
819
820
821
822
823
824
825
826
827
828
  const double cix_min = ci->loc[0];
  const double ciy_min = ci->loc[1];
  const double ciz_min = ci->loc[2];
  const double cjx_min = cj->loc[0];
  const double cjy_min = cj->loc[1];
  const double cjz_min = cj->loc[2];

  const double cix_max = ci->loc[0] + ci->width[0];
  const double ciy_max = ci->loc[1] + ci->width[1];
  const double ciz_max = ci->loc[2] + ci->width[2];
  const double cjx_max = cj->loc[0] + cj->width[0];
  const double cjy_max = cj->loc[1] + cj->width[1];
829
830
831
832
833
  const double cjz_max = cj->loc[2] + cj->width[2];

  if (periodic) {

    const double dx = min4(fabs(nearest(cix_min - cjx_min, dim[0])),
Matthieu Schaller's avatar
Matthieu Schaller committed
834
835
836
837
                           fabs(nearest(cix_min - cjx_max, dim[0])),
                           fabs(nearest(cix_max - cjx_min, dim[0])),
                           fabs(nearest(cix_max - cjx_max, dim[0])));

838
    const double dy = min4(fabs(nearest(ciy_min - cjy_min, dim[1])),
Matthieu Schaller's avatar
Matthieu Schaller committed
839
840
841
842
                           fabs(nearest(ciy_min - cjy_max, dim[1])),
                           fabs(nearest(ciy_max - cjy_min, dim[1])),
                           fabs(nearest(ciy_max - cjy_max, dim[1])));

843
    const double dz = min4(fabs(nearest(ciz_min - cjz_min, dim[2])),
Matthieu Schaller's avatar
Matthieu Schaller committed
844
845
846
847
                           fabs(nearest(ciz_min - cjz_max, dim[2])),
                           fabs(nearest(ciz_max - cjz_min, dim[2])),
                           fabs(nearest(ciz_max - cjz_max, dim[2])));

848
849
850
851
    return dx * dx + dy * dy + dz * dz;

  } else {

Matthieu Schaller's avatar
Matthieu Schaller committed
852
853
854
    const double dx = min(fabs(cix_max - cjx_min), fabs(cix_min - cjx_max));
    const double dy = min(fabs(ciy_max - cjy_min), fabs(ciy_min - cjy_max));
    const double dz = min(fabs(ciz_max - cjz_min), fabs(ciz_min - cjz_max));
855
856
857
858
859

    return dx * dx + dy * dy + dz * dz;
  }
}

860
861
862
863
864
865
866
867
/* 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
868
869
__attribute__((always_inline)) INLINE static int
cell_can_recurse_in_pair_hydro_task(const struct cell *c) {
870
871
872
873
874

  /* 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 */
875
  return c->split && ((kernel_gamma * c->hydro.h_max_old +
876
                       c->hydro.dx_max_part_old) < 0.5f * c->dmin);
877
878
879
880
881
882
883
884
}

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

888
  /* Is the cell split and not smaller than the smoothing length? */
889
  return c->split && (kernel_gamma * c->hydro.h_max_old < 0.5f * c->dmin);
890
891
}

892
893
894
895
/**
 * @brief Can a sub-pair star task recurse to a lower level based
 * on the status of the particles in the cell.
 *
loikki's avatar
loikki committed
896
897
 * @param ci The #cell with stars.
 * @param cj The #cell with hydro parts.
898
899
 */
__attribute__((always_inline)) INLINE static int
900
901
cell_can_recurse_in_pair_stars_task(const struct cell *ci,
                                    const struct cell *cj) {
902

Loic Hausammann's avatar
Loic Hausammann committed
903
904
905
906
  /* 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 */
907
908
909
910
911
  return ci->split && cj->split &&
         ((kernel_gamma * ci->stars.h_max_old + ci->stars.dx_max_part_old) <
          0.5f * ci->dmin) &&
         ((kernel_gamma * cj->hydro.h_max_old + cj->hydro.dx_max_part_old) <
          0.5f * cj->dmin);
912
913
914
915
916
917
918
919
920
921
922
}

/**
 * @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
923
  /* Is the cell split and not smaller than the smoothing length? */
loikki's avatar
loikki committed
924
  return c->split && (kernel_gamma * c->stars.h_max_old < 0.5f * c->dmin) &&
925
         (kernel_gamma * c->hydro.h_max_old < 0.5f * c->dmin);
926
927
}

928
/**
929
 * @brief Can a pair hydro task associated with a cell be split into smaller
930
931
932
933
 * sub-tasks.
 *
 * @param c The #cell.
 */
934
__attribute__((always_inline)) INLINE static int cell_can_split_pair_hydro_task(
935
936
937
938
939
940
941
    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) */
942
  return c->split &&
943
944
         (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin) &&
         (space_stretch * kernel_gamma * c->stars.h_max < 0.5f * c->dmin);
945
946
947
}

/**
948
 * @brief Can a self hydro task associated with a cell be split into smaller
949
950
951
952
 * sub-tasks.
 *
 * @param c The #cell.
 */
953
__attribute__((always_inline)) INLINE static int cell_can_split_self_hydro_task(
954
955
956
    const struct cell *c) {

  /* Is the cell split ? */
957
958
  /* If so, is the cut-off radius with some leeway smaller than */
  /* the sub-cell sizes ? */
959
960
  /* 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 */
961
  return c->split &&
962
963
         (space_stretch * kernel_gamma * c->hydro.h_max < 0.5f * c->dmin) &&
         (space_stretch * kernel_gamma * c->stars.h_max < 0.5f * c->dmin);
964
965
}

966
967
968
969
/**
 * @brief Can a pair stars task associated with a cell be split into smaller
 * sub-tasks.
 *
loikki's avatar
loikki committed
970
971
 * @param ci The #cell with stars.
 * @param cj The #cell with hydro part.
972
973
 */
__attribute__((always_inline)) INLINE static int cell_can_split_pair_stars_task(
loikki's avatar
loikki committed
974
    const struct cell *ci, const struct cell *cj) {
975

Loic Hausammann's avatar
Loic Hausammann committed
976
977
978
979
980
  /* 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) */
loikki's avatar
loikki committed
981
  return ci->split && cj->split &&
982
983
         (space_stretch * kernel_gamma * ci->stars.h_max < 0.5f * ci->dmin) &&
         (space_stretch * kernel_gamma * cj->hydro.h_max < 0.5f * cj->dmin);
984
985
986
987
988
989
990
991
992
993
994
}

/**
 * @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
995
996
997
998
999
1000
  /* 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 &&