logger.c 34.3 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*******************************************************************************
 * This file is part of SWIFT.
 * Copyright (c) 2017 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
 *
 * 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.
 *
 * 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.
 *
 * 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/>.
 *
 ******************************************************************************/

/* Config parameters. */
#include "../config.h"

23
#ifdef HAVE_POSIX_FALLOCATE /* Are we on a sensible platform? */
lhausamm's avatar
lhausamm committed
24
#ifdef WITH_LOGGER
25

26
/* Some standard headers. */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
27
#include <hdf5.h>
28
#include <math.h>
29
#include <stdint.h>
30
31
32
33
34
35
36
37
38
#include <stdlib.h>
#include <string.h>

/* This object's header. */
#include "logger.h"

/* Local headers. */
#include "atomic.h"
#include "dump.h"
Loic Hausammann's avatar
Format    
Loic Hausammann committed
39
#include "engine.h"
40
41
#include "error.h"
#include "part.h"
lhausamm's avatar
lhausamm committed
42
#include "units.h"
43

44
/*
45
46
 * Thoses are definitions from the format and therefore should not be changed!
 */
Loic Hausammann's avatar
Loic Hausammann committed
47
/* Number of bytes for a mask. */
48
// TODO change this to number of bits
Loic Hausammann's avatar
Loic Hausammann committed
49
#define logger_mask_size 2
50

Loic Hausammann's avatar
Loic Hausammann committed
51
/* Number of bits for chunk header. */
52
53
#define logger_header_bytes 8

Loic Hausammann's avatar
Loic Hausammann committed
54
/* Number bytes for an offset. */
55
#define logger_offset_size logger_header_bytes - logger_mask_size
56

Loic Hausammann's avatar
Loic Hausammann committed
57
/* Number of bytes for the file format information. */
Loic Hausammann's avatar
Loic Hausammann committed
58
#define logger_format_size 20
59

Loic Hausammann's avatar
Loic Hausammann committed
60
/* Number of bytes for the labels in the header. */
61
#define logger_label_size 20
62

Loic Hausammann's avatar
Loic Hausammann committed
63
char logger_file_format[logger_format_size] = "SWIFT_LOGGER";
lhausamm's avatar
lhausamm committed
64

Loic Hausammann's avatar
Loic Hausammann committed
65
const struct mask_data logger_mask_data[logger_count_mask] = {
Loic Hausammann's avatar
Loic Hausammann committed
66
    /* Particle's position. */
Loic Hausammann's avatar
Loic Hausammann committed
67
    {3 * sizeof(double), 1 << logger_x, "positions"},
Loic Hausammann's avatar
Loic Hausammann committed
68
    /* Particle's velocity. */
Loic Hausammann's avatar
Loic Hausammann committed
69
    {3 * sizeof(float), 1 << logger_v, "velocities"},
Loic Hausammann's avatar
Loic Hausammann committed
70
    /* Particle's acceleration. */
Loic Hausammann's avatar
Loic Hausammann committed
71
    {3 * sizeof(float), 1 << logger_a, "accelerations"},
Loic Hausammann's avatar
Loic Hausammann committed
72
    /* Particle's entropy. */
Loic Hausammann's avatar
Loic Hausammann committed
73
    {sizeof(float), 1 << logger_u, "entropy"},
Loic Hausammann's avatar
Loic Hausammann committed
74
    /* Particle's smoothing length. */
Loic Hausammann's avatar
Loic Hausammann committed
75
    {sizeof(float), 1 << logger_h, "smoothing length"},
Loic Hausammann's avatar
Loic Hausammann committed
76
    /* Particle's density. */
Loic Hausammann's avatar
Loic Hausammann committed
77
    {sizeof(float), 1 << logger_rho, "density"},
Loic Hausammann's avatar
Loic Hausammann committed
78
    /* Particle's constants: mass (float) and ID (long long). */
Loic Hausammann's avatar
Loic Hausammann committed
79
    {sizeof(float) + sizeof(long long), 1 << logger_consts, "consts"},
Loic Hausammann's avatar
Loic Hausammann committed
80
81
    /* Flag for special cases (e.g. change of MPI rank, star formation, ...) */
    {sizeof(int), 1 << logger_special_flags, "special flags"},
Loic Hausammann's avatar
Loic Hausammann committed
82
    /* Simulation time stamp: integertime and double time (e.g. scale
Loic Hausammann's avatar
Loic Hausammann committed
83
       factor or time). */
Loic Hausammann's avatar
Loic Hausammann committed
84
    {sizeof(integertime_t) + sizeof(double), 1 << logger_timestamp,
Loic Hausammann's avatar
Loic Hausammann committed
85
86
     "timestamp"},
};
87

lhausamm's avatar
lhausamm committed
88
/**
89
90
91
 * @brief Write the header of a chunk (offset + mask).
 *
 * This is maybe broken for big(?) endian.
lhausamm's avatar
lhausamm committed
92
93
94
95
96
97
98
99
 *
 * @param buff The writing buffer
 * @param mask The mask to write
 * @param offset The old offset
 * @param offset_new The new offset
 *
 * @return updated buff
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
100
101
char *logger_write_chunk_header(char *buff, const unsigned int *mask,
                                const size_t *offset, const size_t offset_new) {
Loic Hausammann's avatar
Loic Hausammann committed
102
  /* write mask. */
103
104
  memcpy(buff, mask, logger_mask_size);
  buff += logger_mask_size;
lhausamm's avatar
lhausamm committed
105

Loic Hausammann's avatar
Loic Hausammann committed
106
  /* write offset. */
Loic Hausammann's avatar
Loic Hausammann committed
107
  uint64_t diff_offset = offset_new - *offset;
108
109
  memcpy(buff, &diff_offset, logger_offset_size);
  buff += logger_offset_size;
lhausamm's avatar
lhausamm committed
110
111
112
113
114

  return buff;
}

/**
Loic Hausammann's avatar
Loic Hausammann committed
115
 * @brief Write to the dump.
lhausamm's avatar
lhausamm committed
116
117
 *
 * @param d #dump file
lhausamm's avatar
lhausamm committed
118
 * @param offset (return) offset of the data
lhausamm's avatar
lhausamm committed
119
120
121
 * @param size number of bytes to write
 * @param p pointer to the data
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
122
123
void logger_write_data(struct dump *d, size_t *offset, size_t size,
                       const void *p) {
Loic Hausammann's avatar
Loic Hausammann committed
124
  /* get buffer. */
lhausamm's avatar
lhausamm committed
125
  char *buff = dump_get(d, size, offset);
lhausamm's avatar
lhausamm committed
126

Loic Hausammann's avatar
Loic Hausammann committed
127
  /* write data to the buffer. */
128
  memcpy(buff, p, size);
129

Loic Hausammann's avatar
Loic Hausammann committed
130
  /* Update offset to end of chunk. */
131
  *offset += size;
132
133
}

134
135
/**
 * @brief Compute the size of a message given its mask.
136
137
138
139
 *
 * @param mask The mask that will be used to dump a #part or #gpart.
 *
 * @return The size of the logger message in bytes.
140
 */
lhausamm's avatar
lhausamm committed
141
int logger_compute_chunk_size(unsigned int mask) {
142
143

  /* Start with 8 bytes for the header. */
lhausamm's avatar
lhausamm committed
144
  int size = logger_mask_size + logger_offset_size;
145
146

  /* Is this a particle or a timestep? */
147
  if (mask & logger_mask_data[logger_timestamp].mask) {
148
149

    /* The timestamp should not contain any other bits. */
150
    if (mask != logger_mask_data[logger_timestamp].mask)
151
152
153
      error("Timestamps should not include any other data.");

    /* A timestamp consists of an unsigned long long int. */
154
    size += logger_mask_data[logger_timestamp].size;
155
156
157

  } else {

Loic Hausammann's avatar
Loic Hausammann committed
158
    for (int i = 0; i < logger_count_mask; i++) {
159
      if (mask & logger_mask_data[i].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
160
        size += logger_mask_data[i].size;
161
      }
Loic Hausammann's avatar
Loic Hausammann committed
162
    }
163
164
165
166
  }

  return size;
}
167

lhausamm's avatar
lhausamm committed
168
/**
lhausamm's avatar
lhausamm committed
169
 * @brief log all particles in the engine.
lhausamm's avatar
lhausamm committed
170
 *
Loic Hausammann's avatar
Loic Hausammann committed
171
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
172
 * @param e The #engine
lhausamm's avatar
lhausamm committed
173
 */
Loic Hausammann's avatar
Loic Hausammann committed
174
void logger_log_all(struct logger_writer *log, const struct engine *e) {
175

Loic Hausammann's avatar
Loic Hausammann committed
176
  /* Ensure that enough space is available. */
Loic Hausammann's avatar
Loic Hausammann committed
177
  logger_ensure_size(log, e->s->nr_parts, e->s->nr_gparts, e->s->nr_sparts);
178

Loic Hausammann's avatar
Loic Hausammann committed
179
  /* some constants. */
lhausamm's avatar
lhausamm committed
180
  const struct space *s = e->s;
Loic Hausammann's avatar
Loic Hausammann committed
181
  const unsigned int mask_hydro =
182
183
184
185
      logger_mask_data[logger_x].mask | logger_mask_data[logger_v].mask |
      logger_mask_data[logger_a].mask | logger_mask_data[logger_u].mask |
      logger_mask_data[logger_h].mask | logger_mask_data[logger_rho].mask |
      logger_mask_data[logger_consts].mask;
lhausamm's avatar
lhausamm committed
186

Loic Hausammann's avatar
Loic Hausammann committed
187
  /* loop over all parts. */
Loic Hausammann's avatar
Loic Hausammann committed
188
189
190
191
  for (size_t i = 0; i < s->nr_parts; i++) {
    logger_log_part(log, &s->parts[i], mask_hydro,
                    &s->xparts[i].logger_data.last_offset,
                    /* Special flags */ 0);
192
    s->xparts[i].logger_data.steps_since_last_output = 0;
lhausamm's avatar
lhausamm committed
193
  }
lhausamm's avatar
lhausamm committed
194

Loic Hausammann's avatar
Loic Hausammann committed
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  const unsigned int mask_grav =
      logger_mask_data[logger_x].mask | logger_mask_data[logger_v].mask |
      logger_mask_data[logger_a].mask | logger_mask_data[logger_consts].mask;

  /* loop over all gparts */
  for (size_t i = 0; i < s->nr_gparts; i++) {
    /* Log only the dark matter */
    if (s->gparts[i].type != swift_type_dark_matter) continue;

    logger_log_gpart(log, &s->gparts[i], mask_grav,
                     &s->gparts[i].logger_data.last_offset,
                     /* Special flags */ 0);
    s->gparts[i].logger_data.steps_since_last_output = 0;
  }

  const unsigned int mask_stars = logger_mask_data[logger_x].mask |
                                  logger_mask_data[logger_v].mask |
                                  logger_mask_data[logger_consts].mask;

  /* loop over all sparts */
  for (size_t i = 0; i < s->nr_sparts; i++) {
    logger_log_spart(log, &s->sparts[i], mask_stars,
                     &s->sparts[i].logger_data.last_offset,
                     /* Special flags */ 0);
    s->sparts[i].logger_data.steps_since_last_output = 0;
  }
lhausamm's avatar
lhausamm committed
221

Loic Hausammann's avatar
Loic Hausammann committed
222
  if (e->total_nr_bparts > 0) error("Not implemented");
lhausamm's avatar
lhausamm committed
223
224
}

225
226
227
/**
 * @brief Dump a #part to the log.
 *
Loic Hausammann's avatar
Loic Hausammann committed
228
 * @param log The #logger_writer
Pedro Gonnet's avatar
Pedro Gonnet committed
229
 * @param p The #part to dump.
230
 * @param mask The mask of the data to dump.
Loic Hausammann's avatar
Format    
Loic Hausammann committed
231
 * @param offset Pointer to the offset of the previous log of this particle;
Loic Hausammann's avatar
Loic Hausammann committed
232
 * @param special_flags The value of the special flag.
Loic Hausammann's avatar
Format    
Loic Hausammann committed
233
 * (return) offset of this log.
234
 */
Loic Hausammann's avatar
Loic Hausammann committed
235
void logger_log_part(struct logger_writer *log, const struct part *p,
Loic Hausammann's avatar
Loic Hausammann committed
236
237
                     unsigned int mask, size_t *offset,
                     const int special_flags) {
238
239

  /* Make sure we're not writing a timestamp. */
240
  if (mask & logger_mask_data[logger_timestamp].mask)
241
242
243
    error("You should not log particles as timestamps.");

  /* Start by computing the size of the message. */
lhausamm's avatar
lhausamm committed
244
  const int size = logger_compute_chunk_size(mask);
245
246
247

  /* Allocate a chunk of memory in the dump of the right size. */
  size_t offset_new;
248
  char *buff = (char *)dump_get(&log->dump, size, &offset_new);
249
250

  /* Write the header. */
lhausamm's avatar
lhausamm committed
251
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);
252
253

  /* Particle position as three doubles. */
254
  if (mask & logger_mask_data[logger_x].mask) {
255
256
    memcpy(buff, p->x, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
257
258
259
  }

  /* Particle velocity as three floats. */
260
  if (mask & logger_mask_data[logger_v].mask) {
261
262
    memcpy(buff, p->v, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
263
264
265
  }

  /* Particle accelleration as three floats. */
266
  if (mask & logger_mask_data[logger_a].mask) {
267
268
    memcpy(buff, p->a_hydro, logger_mask_data[logger_a].size);
    buff += logger_mask_data[logger_a].size;
269
270
  }

271
272
#if defined(GADGET2_SPH)

273
  /* Particle internal energy as a single float. */
274
  if (mask & logger_mask_data[logger_u].mask) {
275
276
    memcpy(buff, &p->entropy, logger_mask_data[logger_u].size);
    buff += logger_mask_data[logger_u].size;
277
278
279
  }

  /* Particle smoothing length as a single float. */
280
  if (mask & logger_mask_data[logger_h].mask) {
281
282
    memcpy(buff, &p->h, logger_mask_data[logger_h].size);
    buff += logger_mask_data[logger_h].size;
283
284
285
  }

  /* Particle density as a single float. */
286
  if (mask & logger_mask_data[logger_rho].mask) {
287
288
    memcpy(buff, &p->rho, logger_mask_data[logger_rho].size);
    buff += logger_mask_data[logger_rho].size;
289
290
291
  }

  /* Particle constants, which is a bit more complicated. */
292
  if (mask & logger_mask_data[logger_consts].mask) {
293
    // TODO make it dependent of logger_mask_data
294
295
    memcpy(buff, &p->mass, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
296
297
298
    const int64_t id = p->id;
    memcpy(buff, &id, sizeof(int64_t));
    buff += sizeof(int64_t);
299
300
  }

301
302
#endif

Loic Hausammann's avatar
Loic Hausammann committed
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  /* Special flags */
  if (mask & logger_mask_data[logger_special_flags].mask) {
    memcpy(buff, &special_flags, logger_mask_data[logger_special_flags].size);
    buff += logger_mask_data[logger_special_flags].size;
  }

  /* Update the log message offset. */
  *offset = offset_new;
}

/**
 * @brief Dump a #spart to the log.
 *
 * @param log The #logger_writer
 * @param sp The #spart to dump.
 * @param mask The mask of the data to dump.
 * @param offset Pointer to the offset of the previous log of this particle;
 * @param special_flags The value of the special flag.
 * (return) offset of this log.
 */
void logger_log_spart(struct logger_writer *log, const struct spart *sp,
                      unsigned int mask, size_t *offset,
                      const int special_flags) {

  /* Make sure we're not writing a timestamp. */
  if (mask & logger_mask_data[logger_timestamp].mask)
    error("You should not log particles as timestamps.");

  /* Make sure we're not looging fields not supported by gparts. */
  if (mask &
      (logger_mask_data[logger_u].mask | logger_mask_data[logger_rho].mask |
       logger_mask_data[logger_a].mask))
    error("Can't log SPH quantities for sparts.");

  /* Start by computing the size of the message. */
  const int size = logger_compute_chunk_size(mask);

  /* Allocate a chunk of memory in the dump of the right size. */
  size_t offset_new;
  char *buff = (char *)dump_get(&log->dump, size, &offset_new);

  /* Write the header. */
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);

  /* Particle position as three doubles. */
  if (mask & logger_mask_data[logger_x].mask) {
    memcpy(buff, sp->x, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
  }

  /* Particle velocity as three floats. */
  if (mask & logger_mask_data[logger_v].mask) {
    memcpy(buff, sp->v, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
  }

  /* Particle constants, which is a bit more complicated. */
  if (mask & logger_mask_data[logger_consts].mask) {
    // TODO make it dependent of logger_mask_data
    memcpy(buff, &sp->mass, sizeof(float));
    buff += sizeof(float);
    const int64_t id = sp->id;
    memcpy(buff, &id, sizeof(int64_t));
    buff += sizeof(int64_t);
  }

  /* Special flags */
  if (mask & logger_mask_data[logger_special_flags].mask) {
    memcpy(buff, &special_flags, logger_mask_data[logger_special_flags].size);
    buff += logger_mask_data[logger_special_flags].size;
  }

375
376
377
  /* Update the log message offset. */
  *offset = offset_new;
}
378
379
380
381

/**
 * @brief Dump a #gpart to the log.
 *
Loic Hausammann's avatar
Loic Hausammann committed
382
 * @param log The #logger_writer
Pedro Gonnet's avatar
Pedro Gonnet committed
383
 * @param p The #gpart to dump.
384
 * @param mask The mask of the data to dump.
Loic Hausammann's avatar
Format    
Loic Hausammann committed
385
 * @param offset Pointer to the offset of the previous log of this particle;
Loic Hausammann's avatar
Loic Hausammann committed
386
 * @param special_flags The value of the special flags.
Loic Hausammann's avatar
Format    
Loic Hausammann committed
387
 * (return) offset of this log.
388
 */
Loic Hausammann's avatar
Loic Hausammann committed
389
void logger_log_gpart(struct logger_writer *log, const struct gpart *p,
Loic Hausammann's avatar
Loic Hausammann committed
390
391
392
393
394
395
396
397
                      unsigned int mask, size_t *offset,
                      const int special_flags) {

#ifdef SWIFT_DEBUG_CHECKS
  if (p->id_or_neg_offset < 0) {
    error("Cannot log a gpart attached to another particle");
  }
#endif
398
399

  /* Make sure we're not writing a timestamp. */
400
  if (mask & logger_mask_data[logger_timestamp].mask)
401
402
403
    error("You should not log particles as timestamps.");

  /* Make sure we're not looging fields not supported by gparts. */
404
405
  if (mask &
      (logger_mask_data[logger_u].mask | logger_mask_data[logger_rho].mask))
406
407
408
    error("Can't log SPH quantities for gparts.");

  /* Start by computing the size of the message. */
lhausamm's avatar
lhausamm committed
409
  const int size = logger_compute_chunk_size(mask);
410
411
412

  /* Allocate a chunk of memory in the dump of the right size. */
  size_t offset_new;
413
  char *buff = (char *)dump_get(&log->dump, size, &offset_new);
414
415

  /* Write the header. */
lhausamm's avatar
lhausamm committed
416
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);
417
418

  /* Particle position as three doubles. */
419
  if (mask & logger_mask_data[logger_x].mask) {
420
421
    memcpy(buff, p->x, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
422
423
424
  }

  /* Particle velocity as three floats. */
425
  if (mask & logger_mask_data[logger_v].mask) {
426
427
    memcpy(buff, p->v_full, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
428
429
430
  }

  /* Particle accelleration as three floats. */
431
  if (mask & logger_mask_data[logger_a].mask) {
432
433
    memcpy(buff, p->a_grav, logger_mask_data[logger_a].size);
    buff += logger_mask_data[logger_a].size;
434
435
436
  }

  /* Particle constants, which is a bit more complicated. */
437
  if (mask & logger_mask_data[logger_consts].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
438
    // TODO make it dependent of logger_mask_data.
439
440
    memcpy(buff, &p->mass, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
441
442
443
444
445
446
447
448
449
    const int64_t id = p->id_or_neg_offset;
    memcpy(buff, &id, sizeof(int64_t));
    buff += sizeof(int64_t);
  }

  /* Special flags */
  if (mask & logger_mask_data[logger_special_flags].mask) {
    memcpy(buff, &special_flags, logger_mask_data[logger_special_flags].size);
    buff += logger_mask_data[logger_special_flags].size;
450
451
452
453
454
455
  }

  /* Update the log message offset. */
  *offset = offset_new;
}

lhausamm's avatar
lhausamm committed
456
457
458
/**
 * @brief write a timestamp
 *
Loic Hausammann's avatar
Loic Hausammann committed
459
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
460
 * @param timestamp time to write
461
 * @param time time or scale factor
Loic Hausammann's avatar
Format    
Loic Hausammann committed
462
463
 * @param offset Pointer to the offset of the previous log of this particle;
 * (return) offset of this log.
lhausamm's avatar
lhausamm committed
464
 */
Loic Hausammann's avatar
Loic Hausammann committed
465
void logger_log_timestamp(struct logger_writer *log, integertime_t timestamp,
466
                          double time, size_t *offset) {
467
  struct dump *dump = &log->dump;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
468

469
  /* Start by computing the size of the message. */
470
471
  const int size =
      logger_compute_chunk_size(logger_mask_data[logger_timestamp].mask);
472
473
474

  /* Allocate a chunk of memory in the dump of the right size. */
  size_t offset_new;
475
  char *buff = (char *)dump_get(dump, size, &offset_new);
476
477

  /* Write the header. */
478
  unsigned int mask = logger_mask_data[logger_timestamp].mask;
lhausamm's avatar
lhausamm committed
479
  buff = logger_write_chunk_header(buff, &mask, offset, offset_new);
Pedro Gonnet's avatar
Pedro Gonnet committed
480

481
  /* Store the timestamp. */
Loic Hausammann's avatar
Loic Hausammann committed
482
  // TODO make it dependent of logger_mask_data.
483
  memcpy(buff, &timestamp, sizeof(integertime_t));
484
485
  buff += sizeof(integertime_t);

Loic Hausammann's avatar
Loic Hausammann committed
486
  /* Store the time. */
487
  memcpy(buff, &time, sizeof(double));
488
489
490
491

  /* Update the log message offset. */
  *offset = offset_new;
}
Pedro Gonnet's avatar
Pedro Gonnet committed
492

lhausamm's avatar
lhausamm committed
493
/**
lhausamm's avatar
lhausamm committed
494
 * @brief Ensure that the buffer is large enough for a step.
lhausamm's avatar
lhausamm committed
495
496
 *
 * Check if logger parameters are large enough to write all particles
lhausamm's avatar
lhausamm committed
497
 * and ensure that enough space is available in the buffer.
lhausamm's avatar
lhausamm committed
498
 *
Loic Hausammann's avatar
Loic Hausammann committed
499
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
500
501
502
 * @param total_nr_parts total number of part
 * @param total_nr_gparts total number of gpart
 * @param total_nr_sparts total number of spart
lhausamm's avatar
lhausamm committed
503
 */
Loic Hausammann's avatar
Loic Hausammann committed
504
void logger_ensure_size(struct logger_writer *log, size_t total_nr_parts,
Loic Hausammann's avatar
Format    
Loic Hausammann committed
505
                        size_t total_nr_gparts, size_t total_nr_sparts) {
lhausamm's avatar
lhausamm committed
506

Loic Hausammann's avatar
Loic Hausammann committed
507
508
  /* count part memory */
  size_t limit = 0;
lhausamm's avatar
lhausamm committed
509

Loic Hausammann's avatar
Loic Hausammann committed
510
511
  /* count part memory */
  limit += total_nr_parts;
lhausamm's avatar
lhausamm committed
512

Loic Hausammann's avatar
Loic Hausammann committed
513
514
  /* count gpart memory */
  limit += total_nr_gparts;
515

Loic Hausammann's avatar
Loic Hausammann committed
516
  /* count spart memory. */
Loic Hausammann's avatar
Loic Hausammann committed
517
  limit += total_nr_sparts;
lhausamm's avatar
lhausamm committed
518

Loic Hausammann's avatar
Loic Hausammann committed
519
520
521
522
  // TODO improve estimate with the size of each particle
  limit *= log->max_chunk_size;

  /* ensure enough space in dump */
523
  dump_ensure(&log->dump, limit, log->buffer_scale * limit);
lhausamm's avatar
lhausamm committed
524
525
}

526
527
528
529
530
531
532
533
534
/** @brief Generate the name of the dump files
 *
 * @param log The #logger_writer.
 * @param filename The filename of the dump file.
 */
void logger_get_dump_name(struct logger_writer *log, char *filename) {
  sprintf(filename, "%s_%04i.dump", log->base_name, engine_rank);
}

lhausamm's avatar
lhausamm committed
535
536
537
/**
 * @brief intialize the logger structure
 *
Loic Hausammann's avatar
Loic Hausammann committed
538
 * @param log The #logger_writer
539
 * @param params The #swift_params
lhausamm's avatar
lhausamm committed
540
 */
Loic Hausammann's avatar
Loic Hausammann committed
541
542
void logger_init(struct logger_writer *log, struct swift_params *params) {
  /* read parameters. */
lhausamm's avatar
lhausamm committed
543
  log->delta_step = parser_get_param_int(params, "Logger:delta_step");
Loic Hausammann's avatar
Loic Hausammann committed
544
  size_t buffer_size =
Loic Hausammann's avatar
Loic Hausammann committed
545
546
      parser_get_opt_param_float(params, "Logger:initial_buffer_size", 0.5) *
      1e9;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
547
  log->buffer_scale =
548
      parser_get_opt_param_float(params, "Logger:buffer_scale", 10);
lhausamm's avatar
lhausamm committed
549
550
  parser_get_param_string(params, "Logger:basename", log->base_name);

Loic Hausammann's avatar
Loic Hausammann committed
551
552
553
  log->index.mem_frac =
      parser_get_opt_param_float(params, "Logger:index_mem_frac", 0.05);

Loic Hausammann's avatar
Loic Hausammann committed
554
  /* set initial value of parameters. */
lhausamm's avatar
lhausamm committed
555
  log->timestamp_offset = 0;
Loic Hausammann's avatar
Loic Hausammann committed
556
  log->index.dump_size_last_output = 0;
lhausamm's avatar
lhausamm committed
557

Loic Hausammann's avatar
Loic Hausammann committed
558
  /* generate dump filename. */
lhausamm's avatar
lhausamm committed
559
  char logger_name_file[PARSER_MAX_LINE_SIZE];
560
  logger_get_dump_name(log, logger_name_file);
lhausamm's avatar
lhausamm committed
561

Loic Hausammann's avatar
Loic Hausammann committed
562
  /* Compute max size for a particle chunk. */
563
564
  int max_size = logger_offset_size + logger_mask_size;

Loic Hausammann's avatar
Loic Hausammann committed
565
  /* Loop over all fields except timestamp. */
566
567
568
569
  for (int i = 0; i < logger_count_mask - 1; i++) {
    max_size += logger_mask_data[i].size;
  }
  log->max_chunk_size = max_size;
570

Loic Hausammann's avatar
Loic Hausammann committed
571
  /* init dump. */
572
  dump_init(&log->dump, logger_name_file, buffer_size);
lhausamm's avatar
lhausamm committed
573
574
575
576
577
}

/**
 * @brief Close dump file and desallocate memory
 *
Loic Hausammann's avatar
Loic Hausammann committed
578
 * @param log The #logger_writer
lhausamm's avatar
lhausamm committed
579
 */
Loic Hausammann's avatar
Loic Hausammann committed
580
void logger_free(struct logger_writer *log) { dump_close(&log->dump); }
lhausamm's avatar
lhausamm committed
581

582
583
584
/**
 * @brief Write a file header to a logger file
 *
Loic Hausammann's avatar
Loic Hausammann committed
585
 * @param log The #logger_writer
586
587
 *
 */
Loic Hausammann's avatar
Loic Hausammann committed
588
void logger_write_file_header(struct logger_writer *log) {
lhausamm's avatar
lhausamm committed
589

Loic Hausammann's avatar
Loic Hausammann committed
590
  /* get required variables. */
591
  struct dump *dump = &log->dump;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
592

Loic Hausammann's avatar
Loic Hausammann committed
593
  uint64_t file_offset = dump->file_offset;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
594

lhausamm's avatar
lhausamm committed
595
  if (file_offset != 0)
Loic Hausammann's avatar
Format    
Loic Hausammann committed
596
597
598
    error(
        "The logger is not empty."
        "This function should be called before writing anything in the logger");
599

Loic Hausammann's avatar
Loic Hausammann committed
600
  /* Write format information. */
Loic Hausammann's avatar
Loic Hausammann committed
601
602
  logger_write_data(dump, &file_offset, logger_format_size,
                    &logger_file_format);
Loic Hausammann's avatar
Loic Hausammann committed
603

Loic Hausammann's avatar
Loic Hausammann committed
604
  /* Write the major version number. */
Loic Hausammann's avatar
Loic Hausammann committed
605
606
607
  int major = logger_major_version;
  logger_write_data(dump, &file_offset, sizeof(int), &major);

Loic Hausammann's avatar
Loic Hausammann committed
608
  /* Write the minor version number. */
Loic Hausammann's avatar
Loic Hausammann committed
609
610
  int minor = logger_minor_version;
  logger_write_data(dump, &file_offset, sizeof(int), &minor);
Loic Hausammann's avatar
Format    
Loic Hausammann committed
611

Loic Hausammann's avatar
Loic Hausammann committed
612
  /* write offset direction. */
613
  const int reversed = 0;
614
  logger_write_data(dump, &file_offset, sizeof(int), &reversed);
lhausamm's avatar
lhausamm committed
615

Loic Hausammann's avatar
Loic Hausammann committed
616
  /* placeholder to write the offset of the first log here. */
617
  char *skip_header = dump_get(dump, logger_offset_size, &file_offset);
618

Loic Hausammann's avatar
Loic Hausammann committed
619
  /* write number of bytes used for names. */
620
621
  const unsigned int label_size = logger_label_size;
  logger_write_data(dump, &file_offset, sizeof(unsigned int), &label_size);
lhausamm's avatar
lhausamm committed
622

Loic Hausammann's avatar
Loic Hausammann committed
623
  /* write number of masks. */
624
625
  const unsigned int count_mask = logger_count_mask;
  logger_write_data(dump, &file_offset, sizeof(unsigned int), &count_mask);
626

Loic Hausammann's avatar
Loic Hausammann committed
627
628
  /* write masks. */
  // loop over all mask type.
629
  for (int i = 0; i < logger_count_mask; i++) {
Loic Hausammann's avatar
Loic Hausammann committed
630
    // mask name.
631
    logger_write_data(dump, &file_offset, logger_label_size,
632
                      &logger_mask_data[i].name);
633

Loic Hausammann's avatar
Loic Hausammann committed
634
    // mask size.
635
    logger_write_data(dump, &file_offset, sizeof(unsigned int),
636
                      &logger_mask_data[i].size);
637
  }
638

Loic Hausammann's avatar
Loic Hausammann committed
639
  /* last step: write first offset. */
640
  memcpy(skip_header, &file_offset, logger_offset_size);
lhausamm's avatar
lhausamm committed
641
}
642

lhausamm's avatar
lhausamm committed
643
644
645
646
647
/**
 * @brief read chunk header
 *
 * @param buff The reading buffer
 * @param mask The mask to read
lhausamm's avatar
lhausamm committed
648
 * @param offset (return) the offset pointed by this chunk (absolute)
Loic Hausammann's avatar
Loic Hausammann committed
649
 * @param cur_offset The current chunk offset
lhausamm's avatar
lhausamm committed
650
651
652
 *
 * @return Number of bytes read
 */
Loic Hausammann's avatar
Format    
Loic Hausammann committed
653
654
__attribute__((always_inline)) INLINE static int logger_read_chunk_header(
    const char *buff, unsigned int *mask, size_t *offset, size_t cur_offset) {
lhausamm's avatar
lhausamm committed
655
656
  memcpy(mask, buff, logger_mask_size);
  buff += logger_mask_size;
lhausamm's avatar
lhausamm committed
657
658

  *offset = 0;
lhausamm's avatar
lhausamm committed
659
  memcpy(offset, buff, logger_offset_size);
lhausamm's avatar
lhausamm committed
660
  *offset = cur_offset - *offset;
Loic Hausammann's avatar
Format    
Loic Hausammann committed
661

lhausamm's avatar
lhausamm committed
662
  return logger_mask_size + logger_offset_size;
lhausamm's avatar
lhausamm committed
663
664
}

Pedro Gonnet's avatar
Pedro Gonnet committed
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
/**
 * @brief Read a logger message and store the data in a #part.
 *
 * @param p The #part in which to store the values.
 * @param offset Pointer to the offset of the logger message in the buffer,
 *        will be overwritten with the offset of the previous message.
 * @param buff Pointer to the start of an encoded logger message.
 *
 * @return The mask containing the values read.
 */
int logger_read_part(struct part *p, size_t *offset, const char *buff) {

  /* Jump to the offset. */
  buff = &buff[*offset];

  /* Start by reading the logger mask for this entry. */
lhausamm's avatar
lhausamm committed
681
682
683
  const size_t cur_offset = *offset;
  unsigned int mask = 0;
  buff += logger_read_chunk_header(buff, &mask, offset, cur_offset);
Pedro Gonnet's avatar
Pedro Gonnet committed
684
685

  /* We are only interested in particle data. */
686
  if (mask & logger_mask_data[logger_timestamp].mask)
Pedro Gonnet's avatar
Pedro Gonnet committed
687
688
689
    error("Trying to read timestamp as particle.");

  /* Particle position as three doubles. */
690
  if (mask & logger_mask_data[logger_x].mask) {
691
692
    memcpy(p->x, buff, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
693
694
695
  }

  /* Particle velocity as three floats. */
696
  if (mask & logger_mask_data[logger_v].mask) {
697
698
    memcpy(p->v, buff, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
699
700
701
  }

  /* Particle accelleration as three floats. */
702
  if (mask & logger_mask_data[logger_a].mask) {
703
704
    memcpy(p->a_hydro, buff, logger_mask_data[logger_a].size);
    buff += logger_mask_data[logger_a].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
705
706
  }

707
708
#if defined(GADGET2_SPH)

Pedro Gonnet's avatar
Pedro Gonnet committed
709
  /* Particle internal energy as a single float. */
710
  if (mask & logger_mask_data[logger_u].mask) {
711
712
    memcpy(&p->entropy, buff, logger_mask_data[logger_u].size);
    buff += logger_mask_data[logger_u].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
713
714
715
  }

  /* Particle smoothing length as a single float. */
716
  if (mask & logger_mask_data[logger_h].mask) {
717
718
    memcpy(&p->h, buff, logger_mask_data[logger_h].size);
    buff += logger_mask_data[logger_h].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
719
720
721
  }

  /* Particle density as a single float. */
722
  if (mask & logger_mask_data[logger_rho].mask) {
723
724
    memcpy(&p->rho, buff, logger_mask_data[logger_rho].size);
    buff += logger_mask_data[logger_rho].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
725
726
727
  }

  /* Particle constants, which is a bit more complicated. */
728
  if (mask & logger_mask_data[logger_rho].mask) {
Loic Hausammann's avatar
Loic Hausammann committed
729
    // TODO make it dependent of logger_mask_data.
Pedro Gonnet's avatar
Pedro Gonnet committed
730
731
    memcpy(&p->mass, buff, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
732
733
734
735
    int64_t id = 0;
    memcpy(&id, buff, sizeof(int64_t));
    p->id = id;
    buff += sizeof(int64_t);
Pedro Gonnet's avatar
Pedro Gonnet committed
736
737
  }

738
739
#endif

Pedro Gonnet's avatar
Pedro Gonnet committed
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
  /* Finally, return the mask of the values we just read. */
  return mask;
}

/**
 * @brief Read a logger message and store the data in a #gpart.
 *
 * @param p The #gpart in which to store the values.
 * @param offset Pointer to the offset of the logger message in the buffer,
 *        will be overwritten with the offset of the previous message.
 * @param buff Pointer to the start of an encoded logger message.
 *
 * @return The mask containing the values read.
 */
int logger_read_gpart(struct gpart *p, size_t *offset, const char *buff) {

  /* Jump to the offset. */
  buff = &buff[*offset];

  /* Start by reading the logger mask for this entry. */
lhausamm's avatar
lhausamm committed
760
761
762
  const size_t cur_offset = *offset;
  unsigned int mask = 0;
  buff += logger_read_chunk_header(buff, &mask, offset, cur_offset);
Pedro Gonnet's avatar
Pedro Gonnet committed
763
764

  /* We are only interested in particle data. */
765
  if (mask & logger_mask_data[logger_timestamp].mask)
Pedro Gonnet's avatar
Pedro Gonnet committed
766
    error("Trying to read timestamp as particle.");
Pedro Gonnet's avatar
Pedro Gonnet committed
767

Pedro Gonnet's avatar
Pedro Gonnet committed
768
  /* We can't store all part fields in a gpart. */
769
770
  if (mask &
      (logger_mask_data[logger_u].mask | logger_mask_data[logger_rho].mask))
Pedro Gonnet's avatar
Pedro Gonnet committed
771
772
773
    error("Trying to read SPH quantities into a gpart.");

  /* Particle position as three doubles. */
774
  if (mask & logger_mask_data[logger_x].mask) {
775
776
    memcpy(p->x, buff, logger_mask_data[logger_x].size);
    buff += logger_mask_data[logger_x].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
777
778
779
  }

  /* Particle velocity as three floats. */
780
  if (mask & logger_mask_data[logger_v].mask) {
781
782
    memcpy(p->v_full, buff, logger_mask_data[logger_v].size);
    buff += logger_mask_data[logger_v].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
783
784
785
  }

  /* Particle accelleration as three floats. */
786
  if (mask & logger_mask_data[logger_a].mask) {
787
788
    memcpy(p->a_grav, buff, logger_mask_data[logger_a].size);
    buff += logger_mask_data[logger_a].size;
Pedro Gonnet's avatar
Pedro Gonnet committed
789
790
791
  }

  /* Particle constants, which is a bit more complicated. */
792
  if (mask & logger_mask_data[logger_rho].mask) {
793
    // TODO make it dependent of logger_mask_data
Pedro Gonnet's avatar
Pedro Gonnet committed
794
795
    memcpy(&p->mass, buff, sizeof(float));
    buff += sizeof(float);
Loic Hausammann's avatar
Loic Hausammann committed
796
797
798
    int64_t id = p->id_or_neg_offset;
    memcpy(&id, buff, sizeof(int64_t));
    buff += sizeof(int64_t);
Pedro Gonnet's avatar
Pedro Gonnet committed
799
800
801
802
803
804
805
806
807
808
  }

  /* Finally, return the mask of the values we just read. */
  return mask;
}

/**
 * @brief Read a logger message for a timestamp.
 *
 * @param t The timestamp in which to store the value.
Loic Hausammann's avatar
Loic Hausammann committed
809
 * @param time The time in which to store the value.
Pedro Gonnet's avatar
Pedro Gonnet committed
810
811
812
813
814
815
 * @param offset Pointer to the offset of the logger message in the buffer,
 *        will be overwritten with the offset of the previous message.
 * @param buff Pointer to the start of an encoded logger message.
 *
 * @return The mask containing the values read.
 */
816
817
int logger_read_timestamp(unsigned long long int *t, double *time,
                          size_t *offset, const char *buff) {
Pedro Gonnet's avatar
Pedro Gonnet committed
818
819
820
821
822

  /* Jump to the offset. */
  buff = &buff[*offset];

  /* Start by reading the logger mask for this entry. */
lhausamm's avatar
lhausamm committed
823
824
825
  const size_t cur_offset = *offset;
  unsigned int mask = 0;
  buff += logger_read_chunk_header(buff, &mask, offset, cur_offset);
Pedro Gonnet's avatar
Pedro Gonnet committed
826
827

  /* We are only interested in timestamps. */
828
  if (!(mask & logger_mask_data[logger_timestamp].mask))
Pedro Gonnet's avatar
Pedro Gonnet committed
829
    error("Trying to read timestamp from a particle.");
Pedro Gonnet's avatar
Pedro Gonnet committed
830

Pedro Gonnet's avatar
Pedro Gonnet committed
831
  /* Make sure we don't have extra fields. */
832
  if (mask != logger_mask_data[logger_timestamp].mask)
Pedro Gonnet's avatar
Pedro Gonnet committed
833
834
835
    error("Timestamp message contains extra fields.");

  /* Copy the timestamp value from the buffer. */
Loic Hausammann's avatar
Loic Hausammann committed
836
  // TODO make it dependent of logger_mask_data.
Pedro Gonnet's avatar
Pedro Gonnet committed
837
  memcpy(t, buff, sizeof(unsigned long long int));
838
839
840
  buff += sizeof(unsigned long long int);

  /* Copy the timestamp value from the buffer. */
841
  memcpy(time, buff, sizeof(double));
Pedro Gonnet's avatar
Pedro Gonnet committed
842
843
844
845

  /* Finally, return the mask of the values we just read. */
  return mask;
}
846

847
848
849
850
851

#ifdef WITH_MPI
/**
 * @brief Log all the particles leaving the current rank.
 *
852
853
854
 * @param log The #logger_writer.
 * @param nr_nodes Number of nodes used in the simulation.
 * @param sneding Are we sending the particles (or receiving)?
855
856
857
858
859
860
861
862
863
864
865
866
867
868
 * @param parts The list of #part.
 * @param nr_parts The number of parts.
 * @param count The number of parts in each ranks.
 * @param gparts The list of #gpart.
 * @param nr_gparts The number of gparts.
 * @param gcount The number of gparts in each ranks.
 * @param sparts The list of #spart.
 * @param nr_sparts The number of sparts.
 * @param s_counts The number of sparts in each ranks.
 * @param bparts The list of #bpart.
 * @param nr_bparts The number of bparts.
 * @param b_counts The number of bparts in each ranks.
 *
 */
869
870
871
void logger_log_repartition(
    struct logger_writer *log, int nr_nodes, int sending, struct part *parts,
    struct xpart *xparts, size_t nr_parts, int *counts,
872
873
874
875
    struct gpart *gparts, size_t nr_gparts, int *g_counts,
    struct spart *sparts, size_t nr_sparts, int *s_counts,
    struct bpart *bparts, size_t nr_bparts, int *b_counts) {

876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
  size_t part_offset = 0;
  size_t spart_offset = 0;
  size_t gpart_offset = 0;
  size_t bpart_offset = 0;

  for(int i = 0; i < nr_nodes; i++) {
    const size_t c_ind = sending ? engine_rank * nr_nodes + i:
      i * nr_nodes + engine_rank;

    /* No need to log the local particles. */
    if (i == engine_rank) {
      part_offset += counts[c_ind];
      spart_offset += s_counts[c_ind];
      gpart_offset += g_counts[c_ind];
      bpart_offset += b_counts[c_ind];
      continue;
    }

    const int flag = logger_generate_flag(
      logger_flag_mpi | logger_flag_delete, i);

    const unsigned int mask_hydro =
      logger_mask_data[logger_x].mask | logger_mask_data[logger_v].mask |
      logger_mask_data[logger_a].mask | logger_mask_data[logger_u].mask |
      logger_mask_data[logger_h].mask | logger_mask_data[logger_rho].mask |
      logger_mask_data[logger_consts].mask |
      logger_mask_data[logger_special_flags].mask;

    /* Log the hydro parts. */
    for(int j = 0; j < counts[c_ind]; j++) {
      size_t ind = part_offset + j;
      message("%i: %lli", sending, parts[ind].id);
      logger_log_part(log, &parts[ind], mask_hydro,
                      &xparts[ind].logger_data.last_offset,
                      flag);
      xparts[ind].logger_data.steps_since_last_output = 0;
    }

    const unsigned int mask_stars = logger_mask_data[logger_x].mask |
      logger_mask_data[logger_v].mask |
      logger_mask_data[logger_consts].mask |
      logger_mask_data[logger_special_flags].mask;

    /* Log the stellar parts. */
    for(int j = 0; j < s_counts[c_ind]; j++) {
      size_t ind = spart_offset + j;
      logger_log_spart(log, &sparts[ind], mask_stars,
                       &sparts[ind].logger_data.last_offset,
                       flag);
      sparts[ind].logger_data.steps_since_last_output = 0;
    }

    const unsigned int mask_grav =
      logger_mask_data[logger_x].mask | logger_mask_data[logger_v].mask |
      logger_mask_data[logger_a].mask | logger_mask_data[logger_consts].mask |
      logger_mask_data[logger_special_flags].mask;

    /* Log the gparts */
    for(int j = 0; j < g_counts[c_ind]; j++) {
      size_t ind = gpart_offset + j;
      /* Log only the dark matter */
      if (gparts[ind].type != swift_type_dark_matter) continue;

      logger_log_gpart(log, &gparts[ind], mask_grav,
                       &gparts[ind].logger_data.last_offset,
                       flag);
      gparts[ind].logger_data.steps_since_last_output = 0;
    }

    /* Log the bparts */
    if (b_counts[c_ind] > 0) {
      error("TODO");
    }

    /* Update the counters */
    part_offset += counts[c_ind];
    spart_offset += s_counts[c_ind];
    gpart_offset += g_counts[c_ind];
    bpart_offset += b_counts[c_ind];
  }
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
}

/**
 * @brief Log all the particles arriving in the current rank.
 *
 * @param parts The list of #part.
 * @param nr_parts The number of parts.
 * @param count The number of parts in each ranks.
 * @param gparts The list of #gpart.
 * @param nr_gparts The number of gparts.
 * @param gcount The number of gparts in each ranks.
 * @param sparts The list of #spart.
 * @param nr_sparts The number of sparts.
 * @param s_counts The number of sparts in each ranks.
 * @param bparts The list of #bpart.
 * @param nr_bparts The number of bparts.
 * @param b_counts The number of bparts in each ranks.
 *
 */
void logger_log_recv_strays(
    struct logger_writer *log,
Loic Hausammann's avatar
Loic Hausammann committed
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
    struct part *parts, struct xpart *xparts, size_t nr_parts,
    struct gpart *gparts, size_t nr_gparts,
    struct spart *sparts, size_t nr_sparts,
    struct bpart *bparts, size_t nr_bparts,
    int node_id) {

  const int flag = logger_generate_flag(logger_flag_mpi | logger_flag_create,
                                        node_id);

  /* Log the gas particles */
  const unsigned int mask_hydro =
    logger_mask_data[logger_x].mask | logger_mask_data[logger_v].mask |
    logger_mask_data[logger_a].mask | logger_mask_data[logger_u].mask |
    logger_mask_data[logger_h].mask | logger_mask_data[logger_rho].mask |
    logger_mask_data[logger_consts].mask |
    logger_mask_data[logger_special_flags].mask;

  for(size_t i = 0; i < nr_parts; i++) {
    logger_log_part(log, &parts[i], mask_hydro,
                    &xparts[i].logger_data.last_offset,
                    flag);
    xparts[i].logger_data.steps_since_last_output = 0;
  }

  /* Log the stellar particles */
  const unsigned int mask_stars = logger_mask_data[logger_x].mask |
    logger_mask_data[logger_v].mask |
    logger_mask_data[logger_consts].mask |
    logger_mask_data[logger_special_flags].mask;
  for(size_t i = 0; i < nr_sparts; i++) {
    logger_log_spart(log, &sparts[i], mask_stars,
                     &sparts[i].logger_data.last_offset,
                     /* Special flags */ 0);
    sparts[i].logger_data.steps_since_last_output = 0;
  }


  /* Log the gparts */
  const unsigned int mask_grav =
    logger_mask_data[logger_x].mask | logger_mask_data[logger_v].mask |
    logger_mask_data[logger_a].mask | logger_mask_data[logger_consts].mask |
    logger_mask_data[logger_special_flags].mask;
  for(size_t i = 0; i < nr_gparts; i++) {
    /* Log only the dark matter */
    if (gparts[i].type != swift_type_dark_matter) continue;

    logger_log_gpart(log, &gparts[i], mask_grav,
                     &gparts[i].logger_data.last_offset,
                     /* Special flags */ 0);
    gparts[i].logger_data.steps_since_last_output = 0;
  }

  /* Log the bparts */
  if (nr_bparts > 0) {
    error("TODO");
  }
1033
1034
1035
1036
}

#endif

Loic Hausammann's avatar
Loic Hausammann committed
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
/**
 * @brief Write a swift_params struct to the given FILE as a stream of bytes.
 *
 * @param log the struct
 * @param stream the file stream
 */
void logger_struct_dump(const struct logger_writer *log, FILE *stream) {
  restart_write_blocks((void *)log, sizeof(struct logger_writer), 1, stream,
                       "logger", "logger");
}

Loic Hausammann's avatar
Loic Hausammann committed
1048
1049
1050

// TODO remove that
void dump_restart(struct dump *dump, char *log_name, int size) {}
Loic Hausammann's avatar
Loic Hausammann committed
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
/**
 * @brief Restore a logger struct from the given FILE as a stream of
 * bytes.
 *
 * @param logger the struct
 * @param stream the file stream
 */
void logger_struct_restore(struct logger_writer *log, FILE *stream) {
  /* Read the block */
  restart_read_blocks((void *)log, sizeof(struct logger_writer), 1, stream,
                      NULL, "logger");

  /* generate dump filename */
  char logger_name_file[PARSER_MAX_LINE_SIZE];