Commit d2042445 authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Merge branch 'io_conversion' into 'master'

i/o conversion

Would that work ?

See merge request !201
parents f3b44d59 e9c1723b
......@@ -42,7 +42,7 @@ void hydro_read_particles(struct part* parts, struct io_props* list,
list[3] = io_make_input_field("SmoothingLength", FLOAT, 1, COMPULSORY,
UNIT_CONV_LENGTH, parts, h);
list[4] = io_make_input_field("InternalEnergy", FLOAT, 1, COMPULSORY,
UNIT_CONV_ENERGY, parts, u);
UNIT_CONV_ENERGY_PER_UNIT_MASS, parts, u);
list[5] = io_make_input_field("ParticleIDs", ULONGLONG, 1, COMPULSORY,
UNIT_CONV_NO_UNITS, parts, id);
list[6] = io_make_input_field("Accelerations", FLOAT, 3, OPTIONAL,
......@@ -72,7 +72,7 @@ void hydro_write_particles(struct part* parts, struct io_props* list,
io_make_output_field("Masses", FLOAT, 1, UNIT_CONV_MASS, parts, mass);
list[3] = io_make_output_field("SmoothingLength", FLOAT, 1, UNIT_CONV_LENGTH,
parts, h);
list[4] = io_make_output_field("Entropy", FLOAT, 1,
list[4] = io_make_output_field("InternalEnergy", FLOAT, 1,
UNIT_CONV_ENERGY_PER_UNIT_MASS, parts, u);
list[5] = io_make_output_field("ParticleIDs", ULONGLONG, 1,
UNIT_CONV_NO_UNITS, parts, id);
......
......@@ -17,6 +17,7 @@
*
******************************************************************************/
#include "adiabatic_index.h"
#include "io_properties.h"
#include "kernel_hydro.h"
......@@ -42,7 +43,7 @@ void hydro_read_particles(struct part* parts, struct io_props* list,
list[3] = io_make_input_field("SmoothingLength", FLOAT, 1, COMPULSORY,
UNIT_CONV_LENGTH, parts, h);
list[4] = io_make_input_field("InternalEnergy", FLOAT, 1, COMPULSORY,
UNIT_CONV_ENERGY, parts, entropy);
UNIT_CONV_ENERGY_PER_UNIT_MASS, parts, entropy);
list[5] = io_make_input_field("ParticleIDs", ULONGLONG, 1, COMPULSORY,
UNIT_CONV_NO_UNITS, parts, id);
list[6] = io_make_input_field("Accelerations", FLOAT, 3, OPTIONAL,
......@@ -51,6 +52,12 @@ void hydro_read_particles(struct part* parts, struct io_props* list,
UNIT_CONV_DENSITY, parts, rho);
}
float convert_u(struct engine* e, struct part* p) {
return p->entropy * pow_gamma_minus_one(p->rho) *
hydro_one_over_gamma_minus_one;
}
/**
* @brief Specifies which particle fields to write to a dataset
*
......@@ -61,7 +68,7 @@ void hydro_read_particles(struct part* parts, struct io_props* list,
void hydro_write_particles(struct part* parts, struct io_props* list,
int* num_fields) {
*num_fields = 8;
*num_fields = 9;
/* List what we want to write */
list[0] = io_make_output_field("Coordinates", DOUBLE, 3, UNIT_CONV_LENGTH,
......@@ -80,6 +87,9 @@ void hydro_write_particles(struct part* parts, struct io_props* list,
UNIT_CONV_ACCELERATION, parts, a_hydro);
list[7] =
io_make_output_field("Density", FLOAT, 1, UNIT_CONV_DENSITY, parts, rho);
list[8] = io_make_output_field_convert_part("InternalEnergy", FLOAT, 1,
UNIT_CONV_ENERGY_PER_UNIT_MASS,
parts, rho, convert_u);
}
/**
......@@ -102,4 +112,4 @@ void writeSPHflavour(hid_t h_grpsph) {
*
* @return 1 if entropy is in 'internal energy', 0 otherwise.
*/
int writeEntropyFlag() { return 1; }
int writeEntropyFlag() { return 0; }
......@@ -42,7 +42,7 @@ void hydro_read_particles(struct part* parts, struct io_props* list,
list[3] = io_make_input_field("SmoothingLength", FLOAT, 1, COMPULSORY,
UNIT_CONV_LENGTH, parts, h);
list[4] = io_make_input_field("InternalEnergy", FLOAT, 1, COMPULSORY,
UNIT_CONV_ENERGY, parts, u);
UNIT_CONV_ENERGY_PER_UNIT_MASS, parts, u);
list[5] = io_make_input_field("ParticleIDs", ULONGLONG, 1, COMPULSORY,
UNIT_CONV_NO_UNITS, parts, id);
list[6] = io_make_input_field("Accelerations", FLOAT, 3, OPTIONAL,
......@@ -72,7 +72,7 @@ void hydro_write_particles(struct part* parts, struct io_props* list,
io_make_output_field("Masses", FLOAT, 1, UNIT_CONV_MASS, parts, mass);
list[3] = io_make_output_field("SmoothingLength", FLOAT, 1, UNIT_CONV_LENGTH,
parts, h);
list[4] = io_make_output_field("Entropy", FLOAT, 1,
list[4] = io_make_output_field("InternalEnergy", FLOAT, 1,
UNIT_CONV_ENERGY_PER_UNIT_MASS, parts, u);
list[5] = io_make_output_field("ParticleIDs", ULONGLONG, 1,
UNIT_CONV_NO_UNITS, parts, id);
......
......@@ -54,6 +54,16 @@ struct io_props {
/* The size of the particles */
size_t partSize;
/* The particle arrays */
struct part* parts;
struct gpart* gparts;
/* Conversion function for part */
float (*convert_part)(struct engine*, struct part*);
/* Conversion function for gpart */
float (*convert_gpart)(struct engine*, struct gpart*);
};
/**
......@@ -68,7 +78,7 @@ struct io_props {
*
* @param name Name of the field to read
* @param type The type of the data
* @param dimension Dataset dimension (!D, 3D, ...)
* @param dimension Dataset dimension (1D, 3D, ...)
* @param importance Is this dataset compulsory ?
* @param units The units of the dataset
* @param field Pointer to the field of the first particle
......@@ -89,6 +99,10 @@ struct io_props io_make_input_field_(char name[FIELD_BUFFER_SIZE],
r.units = units;
r.field = field;
r.partSize = partSize;
r.parts = NULL;
r.gparts = NULL;
r.convert_part = NULL;
r.convert_gpart = NULL;
return r;
}
......@@ -105,7 +119,7 @@ struct io_props io_make_input_field_(char name[FIELD_BUFFER_SIZE],
*
* @param name Name of the field to read
* @param type The type of the data
* @param dimension Dataset dimension (!D, 3D, ...)
* @param dimension Dataset dimension (1D, 3D, ...)
* @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
......@@ -124,6 +138,98 @@ struct io_props io_make_output_field_(char name[FIELD_BUFFER_SIZE],
r.units = units;
r.field = field;
r.partSize = partSize;
r.parts = NULL;
r.gparts = NULL;
r.convert_part = NULL;
r.convert_gpart = NULL;
return r;
}
/**
* @brief Constructs an #io_props (with conversion) from its parameters
*/
#define io_make_output_field_convert_part(name, type, dim, units, part, field, \
convert) \
io_make_output_field_convert_part_(name, type, dim, units, \
(char*)(&(part[0]).field), \
sizeof(part[0]), part, 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 field Pointer to the field of the first particle
* @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.
*/
struct io_props io_make_output_field_convert_part_(
char name[FIELD_BUFFER_SIZE], enum DATA_TYPE type, int dimension,
enum UnitConversionFactor units, char* field, size_t partSize,
struct part* parts, float (*functionPtr)(struct engine*, struct part*)) {
struct io_props r;
strcpy(r.name, name);
r.type = type;
r.dimension = dimension;
r.importance = 0;
r.units = units;
r.field = field;
r.partSize = partSize;
r.parts = parts;
r.gparts = NULL;
r.convert_part = functionPtr;
r.convert_gpart = NULL;
return r;
}
/**
* @brief Constructs an #io_props (with conversion) from its parameters
*/
#define io_make_output_field_convert_gpart(name, type, dim, units, part, \
field, convert) \
io_make_output_field_convert_gpart_(name, type, dim, units, \
(char*)(&(part[0]).field), \
sizeof(part[0]), gpart, 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 field Pointer to the field of the first particle
* @param partSize 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.
*/
struct io_props io_make_output_field_convert_gpart_(
char name[FIELD_BUFFER_SIZE], enum DATA_TYPE type, int dimension,
enum UnitConversionFactor units, char* field, size_t partSize,
struct gpart* gparts, float (*functionPtr)(struct engine*, struct gpart*)) {
struct io_props r;
strcpy(r.name, name);
r.type = type;
r.dimension = dimension;
r.importance = 0;
r.units = units;
r.field = field;
r.partSize = partSize;
r.parts = NULL;
r.gparts = gparts;
r.convert_part = NULL;
r.convert_gpart = functionPtr;
return r;
}
......
......@@ -181,6 +181,7 @@ void readArray(hid_t grp, const struct io_props prop, size_t N,
/**
* @brief Writes a data array in given HDF5 group.
*
* @param e The #engine we are writing from.
* @param grp The group in which to write.
* @param fileName The name of the file in which the data is written
* @param xmfFile The FILE used to write the XMF description
......@@ -194,7 +195,7 @@ void readArray(hid_t grp, const struct io_props prop, size_t N,
* the part array will be written once the structures have been stabilized.
*
*/
void writeArray(hid_t grp, char* fileName, FILE* xmfFile,
void writeArray(struct engine* e, hid_t grp, char* fileName, FILE* xmfFile,
char* partTypeGroupName, const struct io_props props, size_t N,
long long N_total, int mpi_rank, long long offset,
const struct UnitSystem* internal_units,
......@@ -211,9 +212,25 @@ void writeArray(hid_t grp, char* fileName, FILE* xmfFile,
if (temp == NULL) error("Unable to allocate memory for temporary buffer");
/* Copy particle data to temporary buffer */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
memcpy(&temp_c[i * copySize], props.field + i * props.partSize, copySize);
if (props.convert_part == NULL &&
props.convert_gpart == NULL) { /* No conversion */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
memcpy(&temp_c[i * copySize], props.field + i * props.partSize, copySize);
} else if (props.convert_part != NULL) { /* conversion (for parts)*/
float* temp_f = temp;
for (size_t i = 0; i < N; ++i)
temp_f[i] = props.convert_part(e, &props.parts[i]);
} else if (props.convert_gpart != NULL) { /* conversion (for gparts)*/
float* temp_f = temp;
for (size_t i = 0; i < N; ++i)
temp_f[i] = props.convert_gpart(e, &props.gparts[i]);
}
/* Unit conversion if necessary */
const double factor =
......@@ -798,7 +815,7 @@ void write_output_parallel(struct engine* e, const char* baseName,
/* Write everything */
for (int i = 0; i < num_fields; ++i)
writeArray(h_grp, fileName, xmfFile, partTypeGroupName, list[i], N,
writeArray(e, h_grp, fileName, xmfFile, partTypeGroupName, list[i], N,
N_total[ptype], mpi_rank, offset[ptype], internal_units,
snapshot_units);
......
......@@ -261,6 +261,7 @@ void prepareArray(hid_t grp, char* fileName, FILE* xmfFile,
/**
* @brief Writes a data array in given HDF5 group.
*
* @param e The #engine we are writing from.
* @param grp The group in which to write.
* @param fileName The name of the file in which the data is written
* @param xmfFile The FILE used to write the XMF description
......@@ -276,7 +277,7 @@ void prepareArray(hid_t grp, char* fileName, FILE* xmfFile,
* @param us The UnitSystem currently in use
* @param convFactor The UnitConversionFactor for this arrayo
*/
void writeArray(hid_t grp, char* fileName, FILE* xmfFile,
void writeArray(struct engine* e, hid_t grp, char* fileName, FILE* xmfFile,
char* partTypeGroupName, const struct io_props props, size_t N,
long long N_total, int mpi_rank, long long offset,
const struct UnitSystem* internal_units,
......@@ -298,9 +299,25 @@ void writeArray(hid_t grp, char* fileName, FILE* xmfFile,
if (temp == NULL) error("Unable to allocate memory for temporary buffer");
/* Copy particle data to temporary buffer */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
memcpy(&temp_c[i * copySize], props.field + i * props.partSize, copySize);
if (props.convert_part == NULL &&
props.convert_gpart == NULL) { /* No conversion */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
memcpy(&temp_c[i * copySize], props.field + i * props.partSize, copySize);
} else if (props.convert_part != NULL) { /* conversion (for parts)*/
float* temp_f = temp;
for (size_t i = 0; i < N; ++i)
temp_f[i] = props.convert_part(e, &props.parts[i]);
} else if (props.convert_gpart != NULL) { /* conversion (for gparts)*/
float* temp_f = temp;
for (size_t i = 0; i < N; ++i)
temp_f[i] = props.convert_gpart(e, &props.gparts[i]);
}
/* Unit conversion if necessary */
const double factor =
......@@ -885,7 +902,7 @@ void write_output_serial(struct engine* e, const char* baseName,
/* Write everything */
for (int i = 0; i < num_fields; ++i)
writeArray(h_grp, fileName, xmfFile, partTypeGroupName, list[i], N,
writeArray(e, h_grp, fileName, xmfFile, partTypeGroupName, list[i], N,
N_total[ptype], mpi_rank, offset[ptype], internal_units,
snapshot_units);
......
......@@ -152,6 +152,7 @@ void readArray(hid_t h_grp, const struct io_props prop, size_t N,
/**
* @brief Writes a data array in given HDF5 group.
*
* @param e The #engine we are writing from.
* @param grp The group in which to write.
* @param fileName The name of the file in which the data is written
* @param xmfFile The FILE used to write the XMF description
......@@ -165,7 +166,7 @@ void readArray(hid_t h_grp, const struct io_props prop, size_t N,
* @todo A better version using HDF5 hyper-slabs to write the file directly from
* the part array will be written once the structures have been stabilized.
*/
void writeArray(hid_t grp, char* fileName, FILE* xmfFile,
void writeArray(struct engine* e, hid_t grp, char* fileName, FILE* xmfFile,
char* partTypeGroupName, const struct io_props props, size_t N,
const struct UnitSystem* internal_units,
const struct UnitSystem* snapshot_units) {
......@@ -181,9 +182,25 @@ void writeArray(hid_t grp, char* fileName, FILE* xmfFile,
if (temp == NULL) error("Unable to allocate memory for temporary buffer");
/* Copy particle data to temporary buffer */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
memcpy(&temp_c[i * copySize], props.field + i * props.partSize, copySize);
if (props.convert_part == NULL &&
props.convert_gpart == NULL) { /* No conversion */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
memcpy(&temp_c[i * copySize], props.field + i * props.partSize, copySize);
} else if (props.convert_part != NULL) { /* conversion (for parts)*/
float* temp_f = temp;
for (size_t i = 0; i < N; ++i)
temp_f[i] = props.convert_part(e, &props.parts[i]);
} else if (props.convert_gpart != NULL) { /* conversion (for gparts)*/
float* temp_f = temp;
for (size_t i = 0; i < N; ++i)
temp_f[i] = props.convert_gpart(e, &props.gparts[i]);
}
/* Unit conversion if necessary */
const double factor =
......@@ -695,7 +712,7 @@ void write_output_single(struct engine* e, const char* baseName,
/* Write everything */
for (int i = 0; i < num_fields; ++i)
writeArray(h_grp, fileName, xmfFile, partTypeGroupName, list[i], N,
writeArray(e, h_grp, fileName, xmfFile, partTypeGroupName, list[i], N,
internal_units, snapshot_units);
/* Free temporary array */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment