io_properties.h 10.5 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 "inline.h"
28

29 30 31 32
/**
 * @brief The two sorts of data present in the GADGET IC files: compulsory to
 * start a run or optional.
 */
33
enum DATA_IMPORTANCE { COMPULSORY = 1, OPTIONAL = 0, UNUSED = -1 };
34

35 36 37 38 39 40 41 42 43 44
/* Helper typedefs */
typedef void (*conversion_func_part_float)(const struct engine*,
                                           const struct part*, float*);
typedef void (*conversion_func_part_double)(const struct engine*,
                                            const struct part*, double*);
typedef void (*conversion_func_gpart_float)(const struct engine*,
                                            const struct gpart*, float*);
typedef void (*conversion_func_gpart_double)(const struct engine*,
                                             const struct gpart*, double*);

45 46 47 48 49 50 51 52 53
/**
 * @brief The properties of a given dataset for i/o
 */
struct io_props {

  /* Name */
  char name[FIELD_BUFFER_SIZE];

  /* Type of the field */
54
  enum IO_DATA_TYPE type;
55 56 57 58 59 60 61 62

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

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

  /* Units of the quantity */
63
  enum unit_conversion_factor units;
64 65 66 67

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

68 69 70 71 72 73 74 75
  /* Pointer to the start of the temporary buffer used in i/o */
  char* start_temp_c;
  float* start_temp_f;
  double* start_temp_d;

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

76 77
  /* The size of the particles */
  size_t partSize;
78 79

  /* The particle arrays */
80 81 82 83 84
  const struct part* parts;
  const struct gpart* gparts;

  /* Are we converting? */
  int conversion;
85 86

  /* Conversion function for part */
87 88
  conversion_func_part_float convert_part_f;
  conversion_func_part_double convert_part_d;
89

90
  /* Conversion function for gpart */
91 92
  conversion_func_gpart_float convert_gpart_f;
  conversion_func_gpart_double convert_gpart_d;
93 94 95 96 97 98 99 100 101 102 103 104 105 106
};

/**
 * @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
107
 * @param dimension Dataset dimension (1D, 3D, ...)
108 109 110 111 112 113 114
 * @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.
 */
115 116 117 118
INLINE static struct io_props io_make_input_field_(
    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
    enum DATA_IMPORTANCE importance, enum unit_conversion_factor units,
    char* field, size_t partSize) {
119 120 121 122 123 124 125 126
  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;
127 128
  r.parts = NULL;
  r.gparts = NULL;
129 130 131 132 133
  r.conversion = 0;
  r.convert_part_f = NULL;
  r.convert_part_d = NULL;
  r.convert_gpart_f = NULL;
  r.convert_gpart_d = NULL;
134 135 136 137 138 139 140

  return r;
}

/**
 * @brief Constructs an #io_props from its parameters
 */
141 142 143
#define io_make_output_field(name, type, dim, units, part, field)          \
  io_make_output_field_(name, type, dim, units, (char*)(&(part[0]).field), \
                        sizeof(part[0]))
144 145 146 147 148 149

/**
 * @brief Construct an #io_props from its parameters
 *
 * @param name Name of the field to read
 * @param type The type of the data
150
 * @param dimension Dataset dimension (1D, 3D, ...)
151 152 153 154 155 156
 * @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.
 */
157 158 159
INLINE static struct io_props io_make_output_field_(
    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
    enum unit_conversion_factor units, char* field, size_t partSize) {
160 161 162 163
  struct io_props r;
  strcpy(r.name, name);
  r.type = type;
  r.dimension = dimension;
164
  r.importance = UNUSED;
165 166 167
  r.units = units;
  r.field = field;
  r.partSize = partSize;
168 169
  r.parts = NULL;
  r.gparts = NULL;
170 171 172 173 174
  r.conversion = 0;
  r.convert_part_f = NULL;
  r.convert_part_d = NULL;
  r.convert_gpart_f = NULL;
  r.convert_gpart_d = NULL;
175 176 177 178 179 180 181

  return r;
}

/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
182 183 184 185
#define io_make_output_field_convert_part(name, type, dim, units, part, \
                                          convert)                      \
  io_make_output_field_convert_part_##type(name, type, dim, units,      \
                                           sizeof(part[0]), part, convert)
186 187 188 189 190 191 192 193 194 195 196 197 198 199

/**
 * @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 partSize The size in byte of the particle
 * @param parts The particle array
 * @param functionPtr The function used to convert a particle to a float
 *
 * Do not call this function directly. Use the macro defined above.
 */
200
INLINE static struct io_props io_make_output_field_convert_part_FLOAT(
201
    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
202 203
    enum unit_conversion_factor units, size_t partSize,
    const struct part* parts, conversion_func_part_float functionPtr) {
204 205 206 207 208

  struct io_props r;
  strcpy(r.name, name);
  r.type = type;
  r.dimension = dimension;
209
  r.importance = UNUSED;
210
  r.units = units;
211
  r.field = NULL;
212 213 214
  r.partSize = partSize;
  r.parts = parts;
  r.gparts = NULL;
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
  r.conversion = 1;
  r.convert_part_f = functionPtr;
  r.convert_part_d = NULL;
  r.convert_gpart_f = NULL;
  r.convert_gpart_d = NULL;

  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 partSize The size in byte of the particle
 * @param parts The particle array
 * @param functionPtr The function used to convert a particle to a float
 *
 * Do not call this function directly. Use the macro defined above.
 */
237
INLINE static struct io_props io_make_output_field_convert_part_DOUBLE(
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
    enum unit_conversion_factor units, size_t partSize,
    const struct part* parts, conversion_func_part_double functionPtr) {

  struct io_props r;
  strcpy(r.name, name);
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
  r.field = NULL;
  r.partSize = partSize;
  r.parts = parts;
  r.gparts = NULL;
  r.conversion = 1;
  r.convert_part_f = NULL;
  r.convert_part_d = functionPtr;
  r.convert_gpart_f = NULL;
  r.convert_gpart_d = NULL;
257 258 259 260 261 262 263

  return r;
}

/**
 * @brief Constructs an #io_props (with conversion) from its parameters
 */
264 265 266 267
#define io_make_output_field_convert_gpart(name, type, dim, units, gpart, \
                                           convert)                       \
  io_make_output_field_convert_gpart_##type(name, type, dim, units,       \
                                            sizeof(gpart[0]), gpart, convert)
268 269 270 271 272 273 274 275

/**
 * @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
276
 * @param gpartSize The size in byte of the particle
277 278
 * @param gparts The particle array
 * @param functionPtr The function used to convert a g-particle to a float
279 280 281
 *
 * Do not call this function directly. Use the macro defined above.
 */
282
INLINE static struct io_props io_make_output_field_convert_gpart_FLOAT(
283
    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
284 285
    enum unit_conversion_factor units, size_t gpartSize,
    const struct gpart* gparts, conversion_func_gpart_float functionPtr) {
286 287 288 289 290

  struct io_props r;
  strcpy(r.name, name);
  r.type = type;
  r.dimension = dimension;
291
  r.importance = UNUSED;
292
  r.units = units;
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
  r.field = NULL;
  r.partSize = gpartSize;
  r.parts = NULL;
  r.gparts = gparts;
  r.conversion = 1;
  r.convert_part_f = NULL;
  r.convert_part_d = NULL;
  r.convert_gpart_f = functionPtr;
  r.convert_gpart_d = NULL;

  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 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 float
 *
 * Do not call this function directly. Use the macro defined above.
 */
319
INLINE static struct io_props io_make_output_field_convert_gpart_DOUBLE(
320 321 322 323 324 325 326 327 328 329 330 331
    char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
    enum unit_conversion_factor units, size_t gpartSize,
    const struct gpart* gparts, conversion_func_gpart_double functionPtr) {

  struct io_props r;
  strcpy(r.name, name);
  r.type = type;
  r.dimension = dimension;
  r.importance = UNUSED;
  r.units = units;
  r.field = NULL;
  r.partSize = gpartSize;
332 333
  r.parts = NULL;
  r.gparts = gparts;
334 335 336 337 338
  r.conversion = 1;
  r.convert_part_f = NULL;
  r.convert_part_d = NULL;
  r.convert_gpart_f = NULL;
  r.convert_gpart_d = functionPtr;
339 340 341 342 343

  return r;
}

#endif /* SWIFT_IO_PROPERTIES_H */