io_properties.h 41 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 23 24
/*******************************************************************************
 * This file is part of SWIFT.
 * Copyright (c) 2016  Matthieu Schaller (matthieu.schaller@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/>.
 *
 ******************************************************************************/
#ifndef SWIFT_IO_PROPERTIES_H
#define SWIFT_IO_PROPERTIES_H

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

25
/* Local includes. */
26
#include "common_io.h"
27
#include "error.h"
28
#include "inline.h"
29
#include "part.h"
30
#include "units.h"
31

Matthieu Schaller's avatar
Matthieu Schaller committed
32 33 34
/* Standard includes. */
#include <string.h>

35 36 37 38
/**
 * @brief The two sorts of data present in the GADGET IC files: compulsory to
 * start a run or optional.
 */
39
enum DATA_IMPORTANCE { COMPULSORY = 1, OPTIONAL = 0, UNUSED = -1 };
40

41 42
/* Helper typedefs */
typedef void (*conversion_func_part_float)(const struct engine*,
43 44
                                           const struct part*,
                                           const struct xpart*, float*);
45
typedef void (*conversion_func_part_int)(const struct engine*,
46 47
                                         const struct part*,
                                         const struct xpart*, int*);
48
typedef void (*conversion_func_part_double)(const struct engine*,
49 50
                                            const struct part*,
                                            const struct xpart*, double*);
51 52 53
typedef void (*conversion_func_part_long_long)(const struct engine*,
                                               const struct part*,
                                               const struct xpart*, long long*);
54 55
typedef void (*conversion_func_gpart_float)(const struct engine*,
                                            const struct gpart*, float*);
56 57
typedef void (*conversion_func_gpart_int)(const struct engine*,
                                          const struct gpart*, int*);
58 59
typedef void (*conversion_func_gpart_double)(const struct engine*,
                                             const struct gpart*, double*);
60 61 62
typedef void (*conversion_func_gpart_long_long)(const struct engine*,
                                                const struct gpart*,
                                                long long*);
63 64
typedef void (*conversion_func_spart_float)(const struct engine*,
                                            const struct spart*, float*);
65 66
typedef void (*conversion_func_spart_int)(const struct engine*,
                                          const struct spart*, int*);
67 68
typedef void (*conversion_func_spart_double)(const struct engine*,
                                             const struct spart*, double*);
69 70 71
typedef void (*conversion_func_spart_long_long)(const struct engine*,
                                                const struct spart*,
                                                long long*);
72 73
typedef void (*conversion_func_bpart_float)(const struct engine*,
                                            const struct bpart*, float*);
74 75
typedef void (*conversion_func_bpart_int)(const struct engine*,
                                          const struct bpart*, int*);
76 77 78 79 80
typedef void (*conversion_func_bpart_double)(const struct engine*,
                                             const struct bpart*, double*);
typedef void (*conversion_func_bpart_long_long)(const struct engine*,
                                                const struct bpart*,
                                                long long*);
Loic Hausammann's avatar
Loic Hausammann committed
81 82 83 84 85 86 87 88
typedef void (*conversion_func_sink_float)(const struct engine*,
                                           const struct sink*, float*);
typedef void (*conversion_func_sink_int)(const struct engine*,
                                         const struct sink*, int*);
typedef void (*conversion_func_sink_double)(const struct engine*,
                                            const struct sink*, double*);
typedef void (*conversion_func_sink_long_long)(const struct engine*,
                                               const struct sink*, long long*);
89

90 91 92 93 94 95 96 97
/**
 * @brief The properties of a given dataset for i/o
 */
struct io_props {

  /* Name */
  char name[FIELD_BUFFER_SIZE];

98 99 100
  /* Description of the variable to write to the field's meta-data */
  char description[DESCRIPTION_BUFFER_SIZE];

101
  /* Type of the field */
102
  enum IO_DATA_TYPE type;
103 104 105 106 107 108 109 110

  /* Dimension (1D, 3D, ...) */
  int dimension;

  /* Is it compulsory ? (input only) */
  enum DATA_IMPORTANCE importance;

  /* Units of the quantity */
111
  enum unit_conversion_factor units;
112

113 114 115
  /* Scale-factor exponent to apply for unit conversion to physical */
  float scale_factor_exponent;

116 117 118
  /* Pointer to the field of the first particle in the array */
  char* field;

119 120
  /* Pointer to the start of the temporary buffer used in i/o */
  char* start_temp_c;
121
  int* start_temp_i;
122 123
  float* start_temp_f;
  double* start_temp_d;
124
  long long* start_temp_l;
125 126 127 128

  /* Pointer to the engine */
  const struct engine* e;

129 130
  /* The size of the particles */
  size_t partSize;
131 132

  /* The particle arrays */
133
  const struct part* parts;
134
  const struct xpart* xparts;
135
  const struct gpart* gparts;
136
  const struct spart* sparts;
137
  const struct bpart* bparts;
Loic Hausammann's avatar
Loic Hausammann committed
138
  const struct sink* sinks;
139 140 141

  /* Are we converting? */
  int conversion;
142 143

  /* Conversion function for part */
144
  conversion_func_part_float convert_part_f;
145
  conversion_func_part_int convert_part_i;
146
  conversion_func_part_double convert_part_d;
147
  conversion_func_part_long_long convert_part_l;
148

149
  /* Conversion function for gpart */
150
  conversion_func_gpart_float convert_gpart_f;
151
  conversion_func_gpart_int convert_gpart_i;
152
  conversion_func_gpart_double convert_gpart_d;
153
  conversion_func_gpart_long_long convert_gpart_l;
154 155 156

  /* Conversion function for spart */
  conversion_func_spart_float convert_spart_f;
157
  conversion_func_spart_int convert_spart_i;
158
  conversion_func_spart_double convert_spart_d;
159
  conversion_func_spart_long_long convert_spart_l;
160 161 162

  /* Conversion function for bpart */
  conversion_func_bpart_float convert_bpart_f;
163
  conversion_func_bpart_int convert_bpart_i;
164 165
  conversion_func_bpart_double convert_bpart_d;
  conversion_func_bpart_long_long convert_bpart_l;
Loic Hausammann's avatar
Loic Hausammann committed
166 167 168 169 170 171

  /* Conversion function for sink */
  conversion_func_sink_float convert_sink_f;
  conversion_func_sink_int convert_sink_i;
  conversion_func_sink_double convert_sink_d;
  conversion_func_sink_long_long convert_sink_l;
172 173 174 175 176 177 178 179 180 181 182 183 184 185
};

/**
 * @brief Constructs an #io_props from its parameters
 */
#define io_make_input_field(name, type, dim, importance, units, part, field) \
  io_make_input_field_(name, type, dim, importance, units,                   \
                       (char*)(&(part[0]).field), sizeof(part[0]))

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
186
 * @param dimension Dataset dimension (1D, 3D, ...)
187 188 189 190 191 192 193
 * @param importance Is this dataset compulsory ?
 * @param units The units of the dataset
 * @param field Pointer to the field of the first particle
 * @param partSize The size in byte of the particle
 *
 * Do not call this function directly. Use the macro defined above.
 */
194
INLINE static struct io_props io_make_input_field_(
195
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
196 197
    enum DATA_IMPORTANCE importance, enum unit_conversion_factor units,
    char* field, size_t partSize) {
198 199 200 201 202 203 204 205
  struct io_props r;
  strcpy(r.name, name);
  r.type = type;
  r.dimension = dimension;
  r.importance = importance;
  r.units = units;
  r.field = field;
  r.partSize = partSize;
206
  r.parts = NULL;
207
  r.xparts = NULL;
208
  r.gparts = NULL;
209
  r.sparts = NULL;
210
  r.bparts = NULL;
211 212 213
  r.conversion = 0;
  r.convert_part_f = NULL;
  r.convert_part_d = NULL;
214
  r.convert_part_l = NULL;
215 216
  r.convert_gpart_f = NULL;
  r.convert_gpart_d = NULL;
217
  r.convert_gpart_l = NULL;
218 219
  r.convert_spart_f = NULL;
  r.convert_spart_d = NULL;
220
  r.convert_spart_l = NULL;
221 222 223
  r.convert_bpart_f = NULL;
  r.convert_bpart_d = NULL;
  r.convert_bpart_l = NULL;
Loic Hausammann's avatar
Loic Hausammann committed
224 225 226
  r.convert_sink_f = NULL;
  r.convert_sink_d = NULL;
  r.convert_sink_l = NULL;
227 228 229 230 231 232 233

  return r;
}

/**
 * @brief Constructs an #io_props from its parameters
 */
234 235 236 237
#define io_make_output_field(name, type, dim, units, a_exponent, part, field, \
                             desc)                                            \
  io_make_output_field_(name, type, dim, units, a_exponent,                   \
                        (char*)(&(part[0]).field), sizeof(part[0]), desc)
238 239 240 241 242 243

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
244
 * @param dimension Dataset dimension (1D, 3D, ...)
245
 * @param units The units of the dataset
246
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
247 248
 * @param field Pointer to the field of the first particle
 * @param partSize The size in byte of the particle
249
 * @param description Description of the field added to the meta-data.
250 251 252
 *
 * Do not call this function directly. Use the macro defined above.
 */
253
INLINE static struct io_props io_make_output_field_(
254
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
255 256 257
    enum unit_conversion_factor units, float a_exponent, char* field,
    size_t partSize, const char description[DESCRIPTION_BUFFER_SIZE]) {

258
  struct io_props r;
259 260
  bzero(&r, sizeof(struct io_props));

261
  strcpy(r.name, name);
262 263 264 265 266
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
267 268
  r.type = type;
  r.dimension = dimension;
269
  r.importance = UNUSED;
270
  r.units = units;
271
  r.scale_factor_exponent = a_exponent;
272 273
  r.field = field;
  r.partSize = partSize;
274
  r.conversion = 0;
275 276 277 278 279 280 281

  return r;
}

/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
282 283 284 285 286
#define io_make_output_field_convert_part(name, type, dim, units, a_exponent,  \
                                          part, xpart, convert, desc)          \
  io_make_output_field_convert_part_##type(name, type, dim, units, a_exponent, \
                                           sizeof(part[0]), part, xpart,       \
                                           convert, desc)
287

288 289 290 291 292 293 294
/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
295
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
296 297 298 299
 * @param partSize The size in byte of the particle
 * @param parts The particle array
 * @param xparts The xparticle array
 * @param functionPtr The function used to convert a particle to an int
300
 * @param description Description of the field added to the meta-data.
301 302 303 304 305
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_part_INT(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
306
    enum unit_conversion_factor units, float a_exponent, size_t partSize,
307
    const struct part* parts, const struct xpart* xparts,
308 309
    conversion_func_part_int functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
310 311

  struct io_props r;
312 313
  bzero(&r, sizeof(struct io_props));

314
  strcpy(r.name, name);
315 316 317 318 319
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
320 321 322 323
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
324
  r.scale_factor_exponent = a_exponent;
325 326 327 328 329 330 331 332 333
  r.partSize = partSize;
  r.parts = parts;
  r.xparts = xparts;
  r.conversion = 1;
  r.convert_part_i = functionPtr;

  return r;
}

334 335 336 337 338 339 340
/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
341
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
342 343
 * @param partSize The size in byte of the particle
 * @param parts The particle array
344
 * @param xparts The xparticle array
345
 * @param functionPtr The function used to convert a particle to a float
346
 * @param description Description of the field added to the meta-data.
347 348 349
 *
 * Do not call this function directly. Use the macro defined above.
 */
350
INLINE static struct io_props io_make_output_field_convert_part_FLOAT(
351
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
352
    enum unit_conversion_factor units, float a_exponent, size_t partSize,
353
    const struct part* parts, const struct xpart* xparts,
354 355
    conversion_func_part_float functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
356 357

  struct io_props r;
358 359
  bzero(&r, sizeof(struct io_props));

360
  strcpy(r.name, name);
361 362 363 364 365
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
366 367
  r.type = type;
  r.dimension = dimension;
368
  r.importance = UNUSED;
369
  r.units = units;
370
  r.scale_factor_exponent = a_exponent;
371 372
  r.partSize = partSize;
  r.parts = parts;
373
  r.xparts = xparts;
374 375 376 377 378 379 380 381 382 383 384 385 386
  r.conversion = 1;
  r.convert_part_f = functionPtr;

  return r;
}

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
387
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
388 389
 * @param partSize The size in byte of the particle
 * @param parts The particle array
390
 * @param xparts The xparticle array
391
 * @param functionPtr The function used to convert a particle to a double
392
 * @param description Description of the field added to the meta-data.
393 394 395
 *
 * Do not call this function directly. Use the macro defined above.
 */
396
INLINE static struct io_props io_make_output_field_convert_part_DOUBLE(
397
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
398
    enum unit_conversion_factor units, float a_exponent, size_t partSize,
399
    const struct part* parts, const struct xpart* xparts,
400 401
    conversion_func_part_double functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
402 403

  struct io_props r;
404 405
  bzero(&r, sizeof(struct io_props));

406
  strcpy(r.name, name);
407 408 409 410 411
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
412 413 414 415
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
416
  r.scale_factor_exponent = a_exponent;
417 418
  r.partSize = partSize;
  r.parts = parts;
419
  r.xparts = xparts;
420 421
  r.conversion = 1;
  r.convert_part_d = functionPtr;
422 423 424 425

  return r;
}

426 427 428 429 430 431 432
/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
433
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
434 435 436 437
 * @param partSize The size in byte of the particle
 * @param parts The particle array
 * @param xparts The xparticle array
 * @param functionPtr The function used to convert a particle to a double
438
 * @param description Description of the field added to the meta-data.
439 440 441 442 443
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_part_LONGLONG(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
444
    enum unit_conversion_factor units, float a_exponent, size_t partSize,
445
    const struct part* parts, const struct xpart* xparts,
446 447
    conversion_func_part_long_long functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
448 449

  struct io_props r;
450 451
  bzero(&r, sizeof(struct io_props));

452
  strcpy(r.name, name);
453 454 455 456 457
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
458 459 460 461
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
462
  r.scale_factor_exponent = a_exponent;
463 464 465 466 467 468 469 470 471
  r.partSize = partSize;
  r.parts = parts;
  r.xparts = xparts;
  r.conversion = 1;
  r.convert_part_l = functionPtr;

  return r;
}

472 473 474
/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
475 476 477 478 479
#define io_make_output_field_convert_gpart(name, type, dim, units, a_exponent, \
                                           gpart, convert, desc)               \
  io_make_output_field_convert_gpart_##type(name, type, dim, units,            \
                                            a_exponent, sizeof(gpart[0]),      \
                                            gpart, convert, desc)
480 481 482 483 484 485 486 487

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
488
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
489
 * @param gpartSize The size in byte of the particle
490 491
 * @param gparts The particle array
 * @param functionPtr The function used to convert a g-particle to a float
492
 * @param description Description of the field added to the meta-data.
493 494 495 496 497
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_gpart_INT(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
498 499 500
    enum unit_conversion_factor units, float a_exponent, size_t gpartSize,
    const struct gpart* gparts, conversion_func_gpart_int functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
501 502 503 504 505

  struct io_props r;
  bzero(&r, sizeof(struct io_props));

  strcpy(r.name, name);
506 507 508 509 510
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
511 512 513 514
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
515
  r.scale_factor_exponent = a_exponent;
516 517 518 519 520 521 522 523
  r.partSize = gpartSize;
  r.gparts = gparts;
  r.conversion = 1;
  r.convert_gpart_i = functionPtr;

  return r;
}

524 525 526 527 528 529 530
/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
531
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
532
 * @param gpartSize The size in byte of the particle
533 534
 * @param gparts The particle array
 * @param functionPtr The function used to convert a g-particle to a float
535
 * @param description Description of the field added to the meta-data.
536 537 538
 *
 * Do not call this function directly. Use the macro defined above.
 */
539
INLINE static struct io_props io_make_output_field_convert_gpart_FLOAT(
540
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
541 542 543
    enum unit_conversion_factor units, float a_exponent, size_t gpartSize,
    const struct gpart* gparts, conversion_func_gpart_float functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
544 545

  struct io_props r;
546 547
  bzero(&r, sizeof(struct io_props));

548
  strcpy(r.name, name);
549 550 551 552 553
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
554 555
  r.type = type;
  r.dimension = dimension;
556
  r.importance = UNUSED;
557
  r.units = units;
558
  r.scale_factor_exponent = a_exponent;
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
  r.partSize = gpartSize;
  r.gparts = gparts;
  r.conversion = 1;
  r.convert_gpart_f = functionPtr;

  return r;
}

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
574
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
575 576
 * @param gpartSize The size in byte of the particle
 * @param gparts The particle array
577
 * @param functionPtr The function used to convert a g-particle to a double
578
 * @param description Description of the field added to the meta-data.
579 580 581
 *
 * Do not call this function directly. Use the macro defined above.
 */
582
INLINE static struct io_props io_make_output_field_convert_gpart_DOUBLE(
583
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
584 585 586
    enum unit_conversion_factor units, float a_exponent, size_t gpartSize,
    const struct gpart* gparts, conversion_func_gpart_double functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
587 588

  struct io_props r;
589 590
  bzero(&r, sizeof(struct io_props));

591
  strcpy(r.name, name);
592 593 594 595 596
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
597 598 599 600
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
601
  r.scale_factor_exponent = a_exponent;
602
  r.partSize = gpartSize;
603
  r.gparts = gparts;
604 605
  r.conversion = 1;
  r.convert_gpart_d = functionPtr;
606 607 608 609 610 611 612 613 614 615 616

  return r;
}

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
617
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
618 619 620
 * @param gpartSize The size in byte of the particle
 * @param gparts The particle array
 * @param functionPtr The function used to convert a g-particle to a double
621
 * @param description Description of the field added to the meta-data.
622 623 624 625 626
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_gpart_LONGLONG(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
627 628 629
    enum unit_conversion_factor units, float a_exponent, size_t gpartSize,
    const struct gpart* gparts, conversion_func_gpart_long_long functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
630 631

  struct io_props r;
632 633
  bzero(&r, sizeof(struct io_props));

634
  strcpy(r.name, name);
635 636 637 638 639
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
640 641 642 643
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
644
  r.scale_factor_exponent = a_exponent;
645 646 647 648
  r.partSize = gpartSize;
  r.gparts = gparts;
  r.conversion = 1;
  r.convert_gpart_l = functionPtr;
649 650 651 652 653 654 655

  return r;
}

/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
656 657 658 659 660
#define io_make_output_field_convert_spart(name, type, dim, units, a_exponent, \
                                           spart, convert, desc)               \
  io_make_output_field_convert_spart_##type(name, type, dim, units,            \
                                            a_exponent, sizeof(spart[0]),      \
                                            spart, convert, desc)
661 662 663 664 665 666 667 668

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
669
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
670 671
 * @param spartSize The size in byte of the particle
 * @param sparts The particle array
672 673
 * @param functionPtr The function used to convert a s-particle to a float
 * @param description Description of the field added to the meta-data.
674 675 676 677 678
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_spart_INT(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
679 680 681
    enum unit_conversion_factor units, float a_exponent, size_t spartSize,
    const struct spart* sparts, conversion_func_spart_int functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
682 683 684 685 686

  struct io_props r;
  bzero(&r, sizeof(struct io_props));

  strcpy(r.name, name);
687 688 689 690 691
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
692 693 694 695
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
696
  r.scale_factor_exponent = a_exponent;
697 698 699 700 701 702 703 704
  r.partSize = spartSize;
  r.sparts = sparts;
  r.conversion = 1;
  r.convert_spart_i = functionPtr;

  return r;
}

705 706 707 708 709 710 711
/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
712
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
713 714 715
 * @param spartSize The size in byte of the particle
 * @param sparts The particle array
 * @param functionPtr The function used to convert a g-particle to a float
716
 * @param description Description of the field added to the meta-data.
717 718 719 720 721
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_spart_FLOAT(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
722 723 724
    enum unit_conversion_factor units, float a_exponent, size_t spartSize,
    const struct spart* sparts, conversion_func_spart_float functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
725 726

  struct io_props r;
727 728
  bzero(&r, sizeof(struct io_props));

729
  strcpy(r.name, name);
730 731 732 733 734
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
735 736 737 738
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
739
  r.scale_factor_exponent = a_exponent;
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
  r.partSize = spartSize;
  r.sparts = sparts;
  r.conversion = 1;
  r.convert_spart_f = functionPtr;

  return r;
}

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
755
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
756 757 758
 * @param spartSize The size in byte of the particle
 * @param sparts The particle array
 * @param functionPtr The function used to convert a s-particle to a double
759
 * @param description Description of the field added to the meta-data.
760 761 762 763 764
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_spart_DOUBLE(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
765 766 767
    enum unit_conversion_factor units, float a_exponent, size_t spartSize,
    const struct spart* sparts, conversion_func_spart_double functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
768 769

  struct io_props r;
770 771
  bzero(&r, sizeof(struct io_props));

772
  strcpy(r.name, name);
773 774 775 776 777
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
778 779 780 781
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
782
  r.scale_factor_exponent = a_exponent;
783 784 785 786
  r.partSize = spartSize;
  r.sparts = sparts;
  r.conversion = 1;
  r.convert_spart_d = functionPtr;
787 788 789 790

  return r;
}

791 792 793 794 795 796 797
/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
798
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
799 800 801
 * @param spartSize The size in byte of the particle
 * @param sparts The particle array
 * @param functionPtr The function used to convert a s-particle to a double
802
 * @param description Description of the field added to the meta-data.
803 804 805 806 807
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_spart_LONGLONG(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
808 809 810
    enum unit_conversion_factor units, float a_exponent, size_t spartSize,
    const struct spart* sparts, conversion_func_spart_long_long functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
811 812

  struct io_props r;
813 814
  bzero(&r, sizeof(struct io_props));

815
  strcpy(r.name, name);
816 817 818 819 820
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
821 822 823 824
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
825
  r.scale_factor_exponent = a_exponent;
826 827 828 829
  r.partSize = spartSize;
  r.sparts = sparts;
  r.conversion = 1;
  r.convert_spart_l = functionPtr;
830 831 832 833 834 835 836

  return r;
}

/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
837 838 839 840 841
#define io_make_output_field_convert_bpart(name, type, dim, units, a_exponent, \
                                           bpart, convert, desc)               \
  io_make_output_field_convert_bpart_##type(name, type, dim, units,            \
                                            a_exponent, sizeof(bpart[0]),      \
                                            bpart, convert, desc)
842

843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
 * @param bpartSize The size in byte of the particle
 * @param bparts The particle array
 * @param functionPtr The function used to convert a b-particle to a float
 * @param description Description of the field added to the meta-data.
 *
 * Do not call this function directly. Use the macro defined above.
 */
858
INLINE static struct io_props io_make_output_field_convert_bpart_INT(
859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
    enum unit_conversion_factor units, float a_exponent, size_t bpartSize,
    const struct bpart* bparts, conversion_func_bpart_int functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {

  struct io_props r;
  bzero(&r, sizeof(struct io_props));

  strcpy(r.name, name);
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
  r.scale_factor_exponent = a_exponent;
  r.partSize = bpartSize;
  r.bparts = bparts;
  r.conversion = 1;
  r.convert_bpart_i = functionPtr;

  return r;
}

886 887 888 889 890 891 892
/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
893
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
Matthieu Schaller's avatar
Matthieu Schaller committed
894 895
 * @param bpartSize The size in byte of the particle
 * @param bparts The particle array
896
 * @param functionPtr The function used to convert a g-particle to a float
897
 * @param description Description of the field added to the meta-data.
898 899 900 901 902
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_bpart_FLOAT(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
903 904 905
    enum unit_conversion_factor units, float a_exponent, size_t bpartSize,
    const struct bpart* bparts, conversion_func_bpart_float functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
906 907

  struct io_props r;
908 909
  bzero(&r, sizeof(struct io_props));

910
  strcpy(r.name, name);
911 912 913 914 915
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
916 917 918 919
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
920
  r.scale_factor_exponent = a_exponent;
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
  r.partSize = bpartSize;
  r.bparts = bparts;
  r.conversion = 1;
  r.convert_bpart_f = functionPtr;

  return r;
}

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
936
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
Matthieu Schaller's avatar
Matthieu Schaller committed
937 938
 * @param bpartSize The size in byte of the particle
 * @param bparts The particle array
939
 * @param functionPtr The function used to convert a s-particle to a double
940
 * @param description Description of the field added to the meta-data.
941 942 943 944 945
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_bpart_DOUBLE(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
946 947 948
    enum unit_conversion_factor units, float a_exponent, size_t bpartSize,
    const struct bpart* bparts, conversion_func_bpart_double functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
949 950

  struct io_props r;
951 952
  bzero(&r, sizeof(struct io_props));

953
  strcpy(r.name, name);
954 955 956 957 958
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
959 960 961 962
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
963
  r.scale_factor_exponent = a_exponent;
964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
  r.partSize = bpartSize;
  r.bparts = bparts;
  r.conversion = 1;
  r.convert_bpart_d = functionPtr;

  return r;
}

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
 * @param dimension Dataset dimension (1D, 3D, ...)
 * @param units The units of the dataset
979
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
Matthieu Schaller's avatar
Matthieu Schaller committed
980 981
 * @param bpartSize The size in byte of the particle
 * @param bparts The particle array
982
 * @param functionPtr The function used to convert a s-particle to a double
983
 * @param description Description of the field added to the meta-data.
984 985 986 987 988
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_bpart_LONGLONG(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
989 990 991
    enum unit_conversion_factor units, float a_exponent, size_t bpartSize,
    const struct bpart* bparts, conversion_func_bpart_long_long functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
992 993

  struct io_props r;
994 995
  bzero(&r, sizeof(struct io_props));