io_properties.h 41.1 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"
Matthieu Schaller's avatar
Matthieu Schaller committed
29
#include "io_compression.h"
30
#include "part.h"
31
#include "units.h"
32

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

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

42 43
/* Helper typedefs */
typedef void (*conversion_func_part_float)(const struct engine*,
44 45
                                           const struct part*,
                                           const struct xpart*, float*);
46
typedef void (*conversion_func_part_int)(const struct engine*,
47 48
                                         const struct part*,
                                         const struct xpart*, int*);
49
typedef void (*conversion_func_part_double)(const struct engine*,
50 51
                                            const struct part*,
                                            const struct xpart*, double*);
52 53 54
typedef void (*conversion_func_part_long_long)(const struct engine*,
                                               const struct part*,
                                               const struct xpart*, long long*);
55 56
typedef void (*conversion_func_gpart_float)(const struct engine*,
                                            const struct gpart*, float*);
57 58
typedef void (*conversion_func_gpart_int)(const struct engine*,
                                          const struct gpart*, int*);
59 60
typedef void (*conversion_func_gpart_double)(const struct engine*,
                                             const struct gpart*, double*);
61 62 63
typedef void (*conversion_func_gpart_long_long)(const struct engine*,
                                                const struct gpart*,
                                                long long*);
64 65
typedef void (*conversion_func_spart_float)(const struct engine*,
                                            const struct spart*, float*);
66 67
typedef void (*conversion_func_spart_int)(const struct engine*,
                                          const struct spart*, int*);
68 69
typedef void (*conversion_func_spart_double)(const struct engine*,
                                             const struct spart*, double*);
70 71 72
typedef void (*conversion_func_spart_long_long)(const struct engine*,
                                                const struct spart*,
                                                long long*);
73 74
typedef void (*conversion_func_bpart_float)(const struct engine*,
                                            const struct bpart*, float*);
75 76
typedef void (*conversion_func_bpart_int)(const struct engine*,
                                          const struct bpart*, int*);
77 78 79 80 81
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
82 83 84 85 86 87 88 89
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*);
90

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

  /* Name */
  char name[FIELD_BUFFER_SIZE];

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

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

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

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

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

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

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

Matthieu Schaller's avatar
Matthieu Schaller committed
120 121 122
  /* Lossy compression scheme to use for this field */
  enum lossy_compression_schemes lossy_compression;

123 124
  /* Pointer to the start of the temporary buffer used in i/o */
  char* start_temp_c;
125
  int* start_temp_i;
126 127
  float* start_temp_f;
  double* start_temp_d;
128
  long long* start_temp_l;
129 130 131 132

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

133 134
  /* The size of the particles */
  size_t partSize;
135 136

  /* The particle arrays */
137
  const struct part* parts;
138
  const struct xpart* xparts;
139
  const struct gpart* gparts;
140
  const struct spart* sparts;
141
  const struct bpart* bparts;
Loic Hausammann's avatar
Loic Hausammann committed
142
  const struct sink* sinks;
143 144 145

  /* Are we converting? */
  int conversion;
146 147

  /* Conversion function for part */
148
  conversion_func_part_float convert_part_f;
149
  conversion_func_part_int convert_part_i;
150
  conversion_func_part_double convert_part_d;
151
  conversion_func_part_long_long convert_part_l;
152

153
  /* Conversion function for gpart */
154
  conversion_func_gpart_float convert_gpart_f;
155
  conversion_func_gpart_int convert_gpart_i;
156
  conversion_func_gpart_double convert_gpart_d;
157
  conversion_func_gpart_long_long convert_gpart_l;
158 159 160

  /* Conversion function for spart */
  conversion_func_spart_float convert_spart_f;
161
  conversion_func_spart_int convert_spart_i;
162
  conversion_func_spart_double convert_spart_d;
163
  conversion_func_spart_long_long convert_spart_l;
164 165 166

  /* Conversion function for bpart */
  conversion_func_bpart_float convert_bpart_f;
167
  conversion_func_bpart_int convert_bpart_i;
168 169
  conversion_func_bpart_double convert_bpart_d;
  conversion_func_bpart_long_long convert_bpart_l;
Loic Hausammann's avatar
Loic Hausammann committed
170 171 172 173 174 175

  /* 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;
176 177 178 179 180 181 182 183 184 185 186 187 188 189
};

/**
 * @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
190
 * @param dimension Dataset dimension (1D, 3D, ...)
191 192 193 194 195 196 197
 * @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.
 */
198
INLINE static struct io_props io_make_input_field_(
199
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
200 201
    enum DATA_IMPORTANCE importance, enum unit_conversion_factor units,
    char* field, size_t partSize) {
202 203 204 205 206 207 208 209
  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;
210
  r.parts = NULL;
211
  r.xparts = NULL;
212
  r.gparts = NULL;
213
  r.sparts = NULL;
214
  r.bparts = NULL;
215 216 217
  r.conversion = 0;
  r.convert_part_f = NULL;
  r.convert_part_d = NULL;
218
  r.convert_part_l = NULL;
219 220
  r.convert_gpart_f = NULL;
  r.convert_gpart_d = NULL;
221
  r.convert_gpart_l = NULL;
222 223
  r.convert_spart_f = NULL;
  r.convert_spart_d = NULL;
224
  r.convert_spart_l = NULL;
225 226 227
  r.convert_bpart_f = NULL;
  r.convert_bpart_d = NULL;
  r.convert_bpart_l = NULL;
Loic Hausammann's avatar
Loic Hausammann committed
228 229 230
  r.convert_sink_f = NULL;
  r.convert_sink_d = NULL;
  r.convert_sink_l = NULL;
231 232 233 234 235 236 237

  return r;
}

/**
 * @brief Constructs an #io_props from its parameters
 */
238 239 240 241
#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)
242 243 244 245 246 247

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

262
  struct io_props r;
263 264
  bzero(&r, sizeof(struct io_props));

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

  return r;
}

/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
286 287 288 289 290
#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)
291

292 293 294 295 296 297 298
/**
 * @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
299
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
300 301 302 303
 * @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
304
 * @param description Description of the field added to the meta-data.
305 306 307 308 309
 *
 * 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,
310
    enum unit_conversion_factor units, float a_exponent, size_t partSize,
311
    const struct part* parts, const struct xpart* xparts,
312 313
    conversion_func_part_int functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
314 315

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

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

  return r;
}

338 339 340 341 342 343 344
/**
 * @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
345
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
346 347
 * @param partSize The size in byte of the particle
 * @param parts The particle array
348
 * @param xparts The xparticle array
349
 * @param functionPtr The function used to convert a particle to a float
350
 * @param description Description of the field added to the meta-data.
351 352 353
 *
 * Do not call this function directly. Use the macro defined above.
 */
354
INLINE static struct io_props io_make_output_field_convert_part_FLOAT(
355
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
356
    enum unit_conversion_factor units, float a_exponent, size_t partSize,
357
    const struct part* parts, const struct xpart* xparts,
358 359
    conversion_func_part_float functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
360 361

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

364
  strcpy(r.name, name);
365 366 367 368 369
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
370 371
  r.type = type;
  r.dimension = dimension;
372
  r.importance = UNUSED;
373
  r.units = units;
374
  r.scale_factor_exponent = a_exponent;
375 376
  r.partSize = partSize;
  r.parts = parts;
377
  r.xparts = xparts;
378 379 380 381 382 383 384 385 386 387 388 389 390
  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
391
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
392 393
 * @param partSize The size in byte of the particle
 * @param parts The particle array
394
 * @param xparts The xparticle array
395
 * @param functionPtr The function used to convert a particle to a double
396
 * @param description Description of the field added to the meta-data.
397 398 399
 *
 * Do not call this function directly. Use the macro defined above.
 */
400
INLINE static struct io_props io_make_output_field_convert_part_DOUBLE(
401
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
402
    enum unit_conversion_factor units, float a_exponent, size_t partSize,
403
    const struct part* parts, const struct xpart* xparts,
404 405
    conversion_func_part_double functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
406 407

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

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

  return r;
}

430 431 432 433 434 435 436
/**
 * @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
437
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
438 439 440 441
 * @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
442
 * @param description Description of the field added to the meta-data.
443 444 445 446 447
 *
 * 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,
448
    enum unit_conversion_factor units, float a_exponent, size_t partSize,
449
    const struct part* parts, const struct xpart* xparts,
450 451
    conversion_func_part_long_long functionPtr,
    const char description[DESCRIPTION_BUFFER_SIZE]) {
452 453

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

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

  return r;
}

476 477 478
/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
479 480 481 482 483
#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)
484 485 486 487 488 489 490 491

/**
 * @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
492
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
493
 * @param gpartSize The size in byte of the particle
494 495
 * @param gparts The particle array
 * @param functionPtr The function used to convert a g-particle to a float
496
 * @param description Description of the field added to the meta-data.
497 498 499 500 501
 *
 * 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,
502 503 504
    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]) {
505 506 507 508 509

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

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

  return r;
}

528 529 530 531 532 533 534
/**
 * @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
535
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
536
 * @param gpartSize The size in byte of the particle
537 538
 * @param gparts The particle array
 * @param functionPtr The function used to convert a g-particle to a float
539
 * @param description Description of the field added to the meta-data.
540 541 542
 *
 * Do not call this function directly. Use the macro defined above.
 */
543
INLINE static struct io_props io_make_output_field_convert_gpart_FLOAT(
544
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
545 546 547
    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]) {
548 549

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

552
  strcpy(r.name, name);
553 554 555 556 557
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
558 559
  r.type = type;
  r.dimension = dimension;
560
  r.importance = UNUSED;
561
  r.units = units;
562
  r.scale_factor_exponent = a_exponent;
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
  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
578
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
579 580
 * @param gpartSize The size in byte of the particle
 * @param gparts The particle array
581
 * @param functionPtr The function used to convert a g-particle to a double
582
 * @param description Description of the field added to the meta-data.
583 584 585
 *
 * Do not call this function directly. Use the macro defined above.
 */
586
INLINE static struct io_props io_make_output_field_convert_gpart_DOUBLE(
587
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
588 589 590
    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]) {
591 592

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

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

  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
621
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
622 623 624
 * @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
625
 * @param description Description of the field added to the meta-data.
626 627 628 629 630
 *
 * 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,
631 632 633
    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]) {
634 635

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

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

  return r;
}

/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
660 661 662 663 664
#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)
665 666 667 668 669 670 671 672

/**
 * @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
673
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
674 675
 * @param spartSize The size in byte of the particle
 * @param sparts The particle array
676 677
 * @param functionPtr The function used to convert a s-particle to a float
 * @param description Description of the field added to the meta-data.
678 679 680 681 682
 *
 * 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,
683 684 685
    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]) {
686 687 688 689 690

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

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

  return r;
}

709 710 711 712 713 714 715
/**
 * @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
716
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
717 718 719
 * @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
720
 * @param description Description of the field added to the meta-data.
721 722 723 724 725
 *
 * 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,
726 727 728
    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]) {
729 730

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

733
  strcpy(r.name, name);
734 735 736 737 738
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
739 740 741 742
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
743
  r.scale_factor_exponent = a_exponent;
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
  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
759
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
760 761 762
 * @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
763
 * @param description Description of the field added to the meta-data.
764 765 766 767 768
 *
 * 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,
769 770 771
    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]) {
772 773

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

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

  return r;
}

795 796 797 798 799 800 801
/**
 * @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
802
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
803 804 805
 * @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
806
 * @param description Description of the field added to the meta-data.
807 808 809 810 811
 *
 * 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,
812 813 814
    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]) {
815 816

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

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

  return r;
}

/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
841 842 843 844 845
#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)
846

847 848 849 850 851 852 853 854 855 856 857 858 859 860 861
/**
 * @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.
 */
862
INLINE static struct io_props io_make_output_field_convert_bpart_INT(
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
    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;
}

890 891 892 893 894 895 896
/**
 * @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
897
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
Matthieu Schaller's avatar
Matthieu Schaller committed
898 899
 * @param bpartSize The size in byte of the particle
 * @param bparts The particle array
900
 * @param functionPtr The function used to convert a g-particle to a float
901
 * @param description Description of the field added to the meta-data.
902 903 904 905 906
 *
 * 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,
907 908 909
    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]) {
910 911

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

914
  strcpy(r.name, name);
915 916 917 918 919
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
920 921 922 923
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
924
  r.scale_factor_exponent = a_exponent;
925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
  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
940
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
Matthieu Schaller's avatar
Matthieu Schaller committed
941 942
 * @param bpartSize The size in byte of the particle
 * @param bparts The particle array
943
 * @param functionPtr The function used to convert a s-particle to a double
944
 * @param description Description of the field added to the meta-data.
945 946 947 948 949
 *
 * 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,
950 951 952
    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]) {
953 954

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

957
  strcpy(r.name, name);
958 959 960 961 962
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
963 964 965 966
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
967
  r.scale_factor_exponent = a_exponent;
968 969 970 971 972 973 974 975 976 977 978 979 980 981 982
  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
983
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
Matthieu Schaller's avatar
Matthieu Schaller committed
984 985
 * @param bpartSize The size in byte of the particle
 * @param bparts The particle array
986
 * @param functionPtr The function used to convert a s-particle to a double
987
 * @param description Description of the field added to the meta-data.
988 989 990 991 992
 *
 * 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,
993 994 995
    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]) {
996 997

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

1000
  strcpy(r.name, name);
1001 1002 1003 1004 1005
  if (strlen(description) == 0) {
    sprintf(r.description, "No description given");
  } else {
    strcpy(r.description, description);
  }
1006 1007 1008 1009
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
1010
  r.scale_factor_exponent = a_exponent;
1011 1012 1013 1014
  r.partSize = bpartSize;
  r.bparts = bparts;
  r.conversion = 1;
  r.convert_bpart_l = functionPtr;
1015 1016 1017 1018

  return r;
}

Loic Hausammann's avatar
Loic Hausammann committed
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
#define io_make_output_field_convert_sink(name, type, dim, units, a_exponent,  \
                                          sink, convert, desc)                 \
  io_make_output_field_convert_sink_##type(name, type, dim, units, a_exponent, \
                                           sizeof(sink[0]), sink, convert,     \
                                           desc)

/**
 * @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 sinkSize The size in byte of the particle
 * @param sinks The particle array
 * @param functionPtr The function used to convert a sink-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.
 */
INLINE static struct io_props io_make_output_field_convert_sink_INT(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
    enum unit_conversion_factor units, float a_exponent, size_t sinkSize,
    const struct sink* sinks, conversion_func_sink_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 = sinkSize;
  r.sinks = sinks;
  r.conversion = 1;
  r.convert_sink_i = 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
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
 * @param sinkSize The size in byte of the particle
 * @param sinks The particle array
 * @param functionPtr The function used to convert a sink-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.
 */
INLINE static struct io_props io_make_output_field_convert_sink_FLOAT(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
    enum unit_conversion_factor units, float a_exponent, size_t sinkSize,
    const struct sink* sinks, conversion_func_sink_float 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 = sinkSize;
  r.sinks = sinks;
  r.conversion = 1;
  r.convert_sink_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
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
 * @param sinkSize The size in byte of the particle
 * @param sinks The particle array
 * @param functionPtr The function used to convert a sink-particle to a double
 * @param description Description of the field added to the meta-data.
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_sink_DOUBLE(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
    enum unit_conversion_factor units, float a_exponent, size_t sinkSize,
    const struct sink* sinks, conversion_func_sink_double 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 = sinkSize;
  r.sinks = sinks;
  r.conversion = 1;
  r.convert_sink_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
 * @param a_exponent Exponent of the scale-factor to convert to physical units.
 * @param sinkSize The size in byte of the particle
 * @param sinks The particle array
 * @param functionPtr The function used to convert a sink-particle to a double
 * @param description Description of the field added to the meta-data.
 *
 * Do not call this function directly. Use the macro defined above.
 */
INLINE static struct io_props io_make_output_field_convert_sink_LONGLONG(
    const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
    enum unit_conversion_factor units, float a_exponent, size_t sinkSize,
    const struct sink* sinks, conversion_func_sink_long_long 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 = sinkSize;
  r.sinks = sinks;
  r.conversion = 1;
  r.convert_sink_l = functionPtr;

  return r;
}

1200
#endif /* SWIFT_IO_PROPERTIES_H */