diff --git a/src/common_io.c b/src/common_io.c index 46cf7077fe5b8a9e9404f5aaa27b7f9f9543529c..a9845b990ad1524fbd1bf6391a70ac140d8c251e 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -522,6 +522,46 @@ void io_convert_gpart_d_mapper(void* restrict temp, int N, props.convert_gpart_d(e, gparts + delta + i, &temp_d[i * dim]); } +/** + * @brief Mapper function to copy #spart into a buffer of floats using a + * conversion function. + */ +void io_convert_spart_f_mapper(void* restrict temp, int N, + void* restrict extra_data) { + + const struct io_props props = *((const struct io_props*)extra_data); + const struct spart* restrict sparts = props.sparts; + const struct engine* e = props.e; + const size_t dim = props.dimension; + + /* How far are we with this chunk? */ + float* restrict temp_f = (float*)temp; + const ptrdiff_t delta = (temp_f - props.start_temp_f) / dim; + + for (int i = 0; i < N; i++) + props.convert_spart_f(e, sparts + delta + i, &temp_f[i * dim]); +} + +/** + * @brief Mapper function to copy #spart into a buffer of doubles using a + * conversion function. + */ +void io_convert_spart_d_mapper(void* restrict temp, int N, + void* restrict extra_data) { + + const struct io_props props = *((const struct io_props*)extra_data); + const struct spart* restrict sparts = props.sparts; + const struct engine* e = props.e; + const size_t dim = props.dimension; + + /* How far are we with this chunk? */ + double* restrict temp_d = (double*)temp; + const ptrdiff_t delta = (temp_d - props.start_temp_d) / dim; + + for (int i = 0; i < N; i++) + props.convert_spart_d(e, sparts + delta + i, &temp_d[i * dim]); +} + /** * @brief Copy the particle data into a temporary buffer ready for i/o. * diff --git a/src/io_properties.h b/src/io_properties.h index 037d32338f015975489f6cbca4f7dfafac413e5f..9e948fc3991b0178d06fdd5d83fa900a98f84d2a 100644 --- a/src/io_properties.h +++ b/src/io_properties.h @@ -47,6 +47,10 @@ 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*); +typedef void (*conversion_func_spart_float)(const struct engine*, + const struct spart*, float*); +typedef void (*conversion_func_spart_double)(const struct engine*, + const struct spart*, double*); /** * @brief The properties of a given dataset for i/o @@ -86,6 +90,7 @@ struct io_props { const struct part* parts; const struct xpart* xparts; const struct gpart* gparts; + const struct spart* sparts; /* Are we converting? */ int conversion; @@ -97,6 +102,10 @@ struct io_props { /* Conversion function for gpart */ conversion_func_gpart_float convert_gpart_f; conversion_func_gpart_double convert_gpart_d; + + /* Conversion function for spart */ + conversion_func_spart_float convert_spart_f; + conversion_func_spart_double convert_spart_d; }; /** @@ -134,11 +143,14 @@ INLINE static struct io_props io_make_input_field_( r.parts = NULL; r.xparts = NULL; r.gparts = NULL; + r.sparts = NULL; r.conversion = 0; r.convert_part_f = NULL; r.convert_part_d = NULL; r.convert_gpart_f = NULL; r.convert_gpart_d = NULL; + r.convert_spart_f = NULL; + r.convert_spart_d = NULL; return r; } @@ -175,11 +187,14 @@ INLINE static struct io_props io_make_output_field_( r.partSize = partSize; r.parts = NULL; r.gparts = NULL; + r.sparts = NULL; r.conversion = 0; r.convert_part_f = NULL; r.convert_part_d = NULL; r.convert_gpart_f = NULL; r.convert_gpart_d = NULL; + r.convert_spart_f = NULL; + r.convert_spart_d = NULL; return r; } @@ -223,11 +238,14 @@ INLINE static struct io_props io_make_output_field_convert_part_FLOAT( r.parts = parts; r.xparts = xparts; r.gparts = NULL; + r.sparts = NULL; r.conversion = 1; r.convert_part_f = functionPtr; r.convert_part_d = NULL; r.convert_gpart_f = NULL; r.convert_gpart_d = NULL; + r.convert_spart_f = NULL; + r.convert_spart_d = NULL; return r; } @@ -242,7 +260,7 @@ INLINE static struct io_props io_make_output_field_convert_part_FLOAT( * @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 float + * @param functionPtr The function used to convert a particle to a double * * Do not call this function directly. Use the macro defined above. */ @@ -263,11 +281,14 @@ INLINE static struct io_props io_make_output_field_convert_part_DOUBLE( r.parts = parts; r.xparts = xparts; r.gparts = NULL; + r.sparts = NULL; r.conversion = 1; r.convert_part_f = NULL; r.convert_part_d = functionPtr; r.convert_gpart_f = NULL; r.convert_gpart_d = NULL; + r.convert_spart_f = NULL; + r.convert_spart_d = NULL; return r; } @@ -309,11 +330,14 @@ INLINE static struct io_props io_make_output_field_convert_gpart_FLOAT( r.parts = NULL; r.xparts = NULL; r.gparts = gparts; + r.sparts = NULL; r.conversion = 1; r.convert_part_f = NULL; r.convert_part_d = NULL; r.convert_gpart_f = functionPtr; r.convert_gpart_d = NULL; + r.convert_spart_f = NULL; + r.convert_spart_d = NULL; return r; } @@ -327,7 +351,7 @@ INLINE static struct io_props io_make_output_field_convert_gpart_FLOAT( * @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 + * @param functionPtr The function used to convert a g-particle to a double * * Do not call this function directly. Use the macro defined above. */ @@ -347,11 +371,104 @@ INLINE static struct io_props io_make_output_field_convert_gpart_DOUBLE( r.parts = NULL; r.xparts = NULL; r.gparts = gparts; + r.sparts = NULL; r.conversion = 1; r.convert_part_f = NULL; r.convert_part_d = NULL; r.convert_gpart_f = NULL; r.convert_gpart_d = functionPtr; + r.convert_spart_f = NULL; + r.convert_spart_d = NULL; + + return r; +} + +/** + * @brief Constructs an #io_props (with conversion) from its parameters + */ +#define io_make_output_field_convert_spart(name, type, dim, units, spart, \ + convert) \ + io_make_output_field_convert_spart_##type(name, type, dim, units, \ + sizeof(spart[0]), spart, convert) + +/** + * @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 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 + * + * 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, + enum unit_conversion_factor units, size_t spartSize, + const struct spart* sparts, conversion_func_spart_float 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 = spartSize; + r.parts = NULL; + r.xparts = NULL; + r.gparts = NULL; + r.sparts = sparts; + r.conversion = 1; + r.convert_part_f = NULL; + r.convert_part_d = NULL; + r.convert_gpart_f = NULL; + r.convert_gpart_d = NULL; + r.convert_spart_f = functionPtr; + r.convert_spart_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 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 + * + * 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, + enum unit_conversion_factor units, size_t spartSize, + const struct spart* sparts, conversion_func_spart_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 = spartSize; + r.parts = NULL; + r.xparts = NULL; + r.gparts = NULL; + r.sparts = sparts; + r.conversion = 1; + r.convert_part_f = NULL; + r.convert_part_d = NULL; + r.convert_gpart_f = NULL; + r.convert_gpart_d = NULL; + r.convert_spart_f = NULL; + r.convert_spart_d = functionPtr; return r; }