diff --git a/src/common_io.c b/src/common_io.c index 4be334ccd602c7b0c450f5dbe4aedd9155b35ff1..3133c64f45df7d2ef3711f375fdd318b154d7919 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -45,6 +45,9 @@ #include "kernel.h" #include "version.h" +const char *particle_type_names[NUM_PARTICLE_TYPES] = { + "Gas", "DM", "Boundary", "Dummy", "Stars", "BH" }; + /** * @brief Converts a C data type to the HDF5 equivalent. * @@ -406,24 +409,13 @@ void createXMFfile() { * @param hdfFileName The name of the HDF5 file corresponding to this output. * @param time The current simulation time. */ -void writeXMFheader(FILE* xmfFile, long long Nparts, char* hdfFileName, - float time) { +void writeXMFoutputheader(FILE* xmfFile, char* hdfFileName, float time) { /* Write end of file */ + fprintf(xmfFile, "<!-- XMF description for file: %s -->\n", hdfFileName); fprintf(xmfFile, "<Grid GridType=\"Collection\" CollectionType=\"Spatial\">\n"); fprintf(xmfFile, "<Time Type=\"Single\" Value=\"%f\"/>\n", time); - fprintf(xmfFile, "<Grid Name=\"Gas\" GridType=\"Uniform\">\n"); - fprintf(xmfFile, - "<Topology TopologyType=\"Polyvertex\" Dimensions=\"%lld\"/>\n", - Nparts); - fprintf(xmfFile, "<Geometry GeometryType=\"XYZ\">\n"); - fprintf(xmfFile, - "<DataItem Dimensions=\"%lld 3\" NumberType=\"Double\" " - "Precision=\"8\" " - "Format=\"HDF\">%s:/PartType0/Coordinates</DataItem>\n", - Nparts, hdfFileName); - fprintf(xmfFile, "</Geometry>"); } /** @@ -431,18 +423,40 @@ void writeXMFheader(FILE* xmfFile, long long Nparts, char* hdfFileName, * * @param xmfFile The file to write in. */ -void writeXMFfooter(FILE* xmfFile) { +void writeXMFoutputfooter(FILE* xmfFile, int output, float time) { /* Write end of the section of this time step */ - fprintf(xmfFile, "\n</Grid>\n"); - fprintf(xmfFile, "</Grid>\n"); - fprintf(xmfFile, "\n</Grid>\n"); + fprintf(xmfFile, "\n</Grid> <!-- output=%03i time=%f -->\n", output, time); + fprintf(xmfFile, "\n</Grid> <!-- timeSeries -->\n"); fprintf(xmfFile, "</Domain>\n"); fprintf(xmfFile, "</Xdmf>\n"); fclose(xmfFile); } + +void writeXMFgroupheader(FILE* xmfFile, char* hdfFileName, size_t N, + enum PARTICLE_TYPE ptype) { + fprintf(xmfFile, "\n<Grid Name=\"%s\" GridType=\"Uniform\">\n", + particle_type_names[ptype]); + fprintf(xmfFile, + "<Topology TopologyType=\"Polyvertex\" Dimensions=\"%zi\"/>\n", + N); + fprintf(xmfFile, "<Geometry GeometryType=\"XYZ\">\n"); + fprintf(xmfFile, + "<DataItem Dimensions=\"%zi 3\" NumberType=\"Double\" " + "Precision=\"8\" " + "Format=\"HDF\">%s:/PartType%d/Coordinates</DataItem>\n", + N, hdfFileName, ptype); + fprintf(xmfFile, "</Geometry>"); +} + +void writeXMFgroupfooter(FILE* xmfFile, enum PARTICLE_TYPE ptype) { + fprintf(xmfFile, "</Grid> <!-- parttype=%s -->\n", particle_type_names[ptype]); +} + + + /** * @brief Writes the lines corresponding to an array of the HDF5 output * @@ -455,21 +469,21 @@ void writeXMFfooter(FILE* xmfFile) { * * @todo Treat the types in a better way. */ -void writeXMFline(FILE* xmfFile, char* fileName, char* name, long long N, - int dim, enum DATA_TYPE type) { +void writeXMFline(FILE* xmfFile, char* fileName, char* partTypeGroupName, + char* name, size_t N, int dim, enum DATA_TYPE type) { fprintf(xmfFile, "<Attribute Name=\"%s\" AttributeType=\"%s\" Center=\"Node\">\n", name, dim == 1 ? "Scalar" : "Vector"); if (dim == 1) fprintf(xmfFile, - "<DataItem Dimensions=\"%lld\" NumberType=\"Double\" " - "Precision=\"%d\" Format=\"HDF\">%s:/PartType0/%s</DataItem>\n", - N, type == FLOAT ? 4 : 8, fileName, name); + "<DataItem Dimensions=\"%zi\" NumberType=\"Double\" " + "Precision=\"%d\" Format=\"HDF\">%s:%s/%s</DataItem>\n", + N, type == FLOAT ? 4 : 8, fileName, partTypeGroupName, name); else fprintf(xmfFile, - "<DataItem Dimensions=\"%lld %d\" NumberType=\"Double\" " - "Precision=\"%d\" Format=\"HDF\">%s:/PartType0/%s</DataItem>\n", - N, dim, type == FLOAT ? 4 : 8, fileName, name); + "<DataItem Dimensions=\"%zi %d\" NumberType=\"Double\" " + "Precision=\"%d\" Format=\"HDF\">%s:%s/%s</DataItem>\n", + N, dim, type == FLOAT ? 4 : 8, fileName, partTypeGroupName, name); fprintf(xmfFile, "</Attribute>\n"); } diff --git a/src/common_io.h b/src/common_io.h index 426fa6a01ec87a4413eceaaeb0d0880cbef8a214..6cc79ad51809d461b188003247e8cf021e3cf0fe 100644 --- a/src/common_io.h +++ b/src/common_io.h @@ -70,6 +70,8 @@ enum PARTICLE_TYPE { NUM_PARTICLE_TYPES }; +extern const char *particle_type_names[]; + #define FILENAME_BUFFER_SIZE 150 #define PARTICLE_GROUP_BUFFER_SIZE 20 @@ -95,10 +97,13 @@ void writeAttribute_s(hid_t grp, char* name, const char* str); void createXMFfile(); FILE* prepareXMFfile(); -void writeXMFfooter(FILE* xmfFile); -void writeXMFheader(FILE* xmfFile, long long N, char* hdfFileName, float time); -void writeXMFline(FILE* xmfFile, char* fileName, char* name, long long N, - int dim, enum DATA_TYPE type); +void writeXMFoutputheader(FILE* xmfFile, char* hdfFileName, float time); +void writeXMFoutputfooter(FILE* xmfFile, int outputCount, float time); +void writeXMFgroupheader(FILE* xmfFile, char* hdfFileName, size_t N, + enum PARTICLE_TYPE ptype); +void writeXMFgroupfooter(FILE* xmfFile, enum PARTICLE_TYPE ptype); +void writeXMFline(FILE* xmfFile, char* fileName, char* partTypeGroupName, + char* name, size_t N, int dim, enum DATA_TYPE type); void writeCodeDescription(hid_t h_file); void writeSPHflavour(hid_t h_file); diff --git a/src/gravity/Default/gravity_io.h b/src/gravity/Default/gravity_io.h index d707d69631e65eed8ad21a7fa9601c07d3c71263..2a7b0c1fc71b9d6b60f353ddab2e9b097cfed7ec 100644 --- a/src/gravity/Default/gravity_io.h +++ b/src/gravity/Default/gravity_io.h @@ -59,17 +59,20 @@ __attribute__((always_inline)) INLINE static void darkmatter_read_particles( * */ __attribute__((always_inline)) INLINE static void darkmatter_write_particles( - hid_t h_grp, char* fileName, FILE* xmfFile, int Ndm, long long Ndm_total, - int mpi_rank, long long offset, struct gpart* gparts, - struct UnitSystem* us) { + hid_t h_grp, char* fileName, char* partTypeGroupName, FILE* xmfFile, + int Ndm, long long Ndm_total, int mpi_rank, long long offset, + struct gpart* gparts, struct UnitSystem* us) { /* Write arrays */ - writeArray(h_grp, fileName, xmfFile, "Coordinates", DOUBLE, Ndm, 3, gparts, - Ndm_total, mpi_rank, offset, x, us, UNIT_CONV_LENGTH); - writeArray(h_grp, fileName, xmfFile, "Masses", FLOAT, Ndm, 1, gparts, - Ndm_total, mpi_rank, offset, mass, us, UNIT_CONV_MASS); - writeArray(h_grp, fileName, xmfFile, "Velocities", FLOAT, Ndm, 3, gparts, - Ndm_total, mpi_rank, offset, v_full, us, UNIT_CONV_SPEED); - writeArray(h_grp, fileName, xmfFile, "ParticleIDs", ULONGLONG, Ndm, 1, gparts, - Ndm_total, mpi_rank, offset, id, us, UNIT_CONV_NO_UNITS); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Coordinates", DOUBLE, + Ndm, 3, gparts, Ndm_total, mpi_rank, offset, x, us, + UNIT_CONV_LENGTH); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Masses", FLOAT, Ndm, + 1, gparts, Ndm_total, mpi_rank, offset, mass, us, UNIT_CONV_MASS); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Velocities", FLOAT, + Ndm, 3, gparts, Ndm_total, mpi_rank, offset, v_full, us, + UNIT_CONV_SPEED); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "ParticleIDs", + ULONGLONG, Ndm, 1, gparts, Ndm_total, mpi_rank, offset, id, us, + UNIT_CONV_NO_UNITS); } diff --git a/src/hydro/Gadget2/hydro_io.h b/src/hydro/Gadget2/hydro_io.h index 17c3d3013644c3572f3c26fc3e270b1c1bc465ed..d7e52497e873a00e204c7c7b4c32126897c792fa 100644 --- a/src/hydro/Gadget2/hydro_io.h +++ b/src/hydro/Gadget2/hydro_io.h @@ -67,27 +67,31 @@ __attribute__((always_inline)) INLINE static void hydro_read_particles( * */ __attribute__((always_inline)) INLINE static void hydro_write_particles( - hid_t h_grp, char* fileName, FILE* xmfFile, int N, long long N_total, - int mpi_rank, long long offset, struct part* parts, struct UnitSystem* us) { + hid_t h_grp, char* fileName, char* partTypeGroupName, FILE* xmfFile, int N, + long long N_total, int mpi_rank, long long offset, struct part* parts, + struct UnitSystem* us) { /* Write arrays */ - writeArray(h_grp, fileName, xmfFile, "Coordinates", DOUBLE, N, 3, parts, - N_total, mpi_rank, offset, x, us, UNIT_CONV_LENGTH); - writeArray(h_grp, fileName, xmfFile, "Velocities", FLOAT, N, 3, parts, - N_total, mpi_rank, offset, v, us, UNIT_CONV_SPEED); - writeArray(h_grp, fileName, xmfFile, "Masses", FLOAT, N, 1, parts, N_total, - mpi_rank, offset, mass, us, UNIT_CONV_MASS); - writeArray(h_grp, fileName, xmfFile, "SmoothingLength", FLOAT, N, 1, parts, - N_total, mpi_rank, offset, h, us, UNIT_CONV_LENGTH); - writeArray(h_grp, fileName, xmfFile, "InternalEnergy", FLOAT, N, 1, parts, - N_total, mpi_rank, offset, entropy, us, + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Coordinates", DOUBLE, + N, 3, parts, N_total, mpi_rank, offset, x, us, UNIT_CONV_LENGTH); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Velocities", FLOAT, + N, 3, parts, N_total, mpi_rank, offset, v, us, UNIT_CONV_SPEED); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Masses", FLOAT, N, 1, + parts, N_total, mpi_rank, offset, mass, us, UNIT_CONV_MASS); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "SmoothingLength", + FLOAT, N, 1, parts, N_total, mpi_rank, offset, h, us, + UNIT_CONV_LENGTH); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "InternalEnergy", + FLOAT, N, 1, parts, N_total, mpi_rank, offset, entropy, us, UNIT_CONV_ENTROPY_PER_UNIT_MASS); - writeArray(h_grp, fileName, xmfFile, "ParticleIDs", ULONGLONG, N, 1, parts, - N_total, mpi_rank, offset, id, us, UNIT_CONV_NO_UNITS); - writeArray(h_grp, fileName, xmfFile, "Acceleration", FLOAT, N, 3, parts, - N_total, mpi_rank, offset, a_hydro, us, UNIT_CONV_ACCELERATION); - writeArray(h_grp, fileName, xmfFile, "Density", FLOAT, N, 1, parts, N_total, - mpi_rank, offset, rho, us, UNIT_CONV_DENSITY); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "ParticleIDs", + ULONGLONG, N, 1, parts, N_total, mpi_rank, offset, id, us, + UNIT_CONV_NO_UNITS); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Acceleration", FLOAT, + N, 3, parts, N_total, mpi_rank, offset, a_hydro, us, + UNIT_CONV_ACCELERATION); + writeArray(h_grp, fileName, xmfFile, partTypeGroupName, "Density", FLOAT, N, + 1, parts, N_total, mpi_rank, offset, rho, us, UNIT_CONV_DENSITY); } /** diff --git a/src/serial_io.c b/src/serial_io.c index 3fb1a1d1b743e48be4e8e6d81413c28e8034b870..fe0b0def9e6181ba68c078b6bec14b6b9622ef4e 100644 --- a/src/serial_io.c +++ b/src/serial_io.c @@ -643,7 +643,7 @@ void write_output_serial(struct engine* e, struct UnitSystem* us, int mpi_rank, xmfFile = prepareXMFfile(); /* Write the part corresponding to this specific output */ - // writeXMFheader(xmfFile, N_total, fileName, e->time); + writeXMFheader(xmfFile, N_total[0], fileName, e->time); /* Open file */ /* message("Opening file '%s'.", fileName); */ diff --git a/src/single_io.c b/src/single_io.c index 54ace5c4e369cd6b9a02d44f8a8f03ef6cbadd5f..6f6d1d4913c0ff89e8e4aad215baa951d8a43913 100644 --- a/src/single_io.c +++ b/src/single_io.c @@ -138,6 +138,7 @@ void readArrayBackEnd(hid_t grp, char* name, enum DATA_TYPE type, int N, * @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 + * @param partTypeGroupName The name of the group containing the particles in the HDF5 file. * @param name The name of the array to write. * @param type The #DATA_TYPE of the array. * @param N The number of particles to write. @@ -153,7 +154,8 @@ void readArrayBackEnd(hid_t grp, char* name, enum DATA_TYPE type, int N, * * Calls #error() if an error occurs. */ -void writeArrayBackEnd(hid_t grp, char* fileName, FILE* xmfFile, char* name, +void writeArrayBackEnd(hid_t grp, char* fileName, FILE* xmfFile, + char* partTypeGroupName, char* name, enum DATA_TYPE type, int N, int dim, char* part_c, size_t partSize, struct UnitSystem* us, enum UnitConversionFactor convFactor) { @@ -237,7 +239,7 @@ void writeArrayBackEnd(hid_t grp, char* fileName, FILE* xmfFile, char* name, } /* Write XMF description for this data set */ - writeXMFline(xmfFile, fileName, name, N, dim, type); + writeXMFline(xmfFile, fileName, partTypeGroupName, name, N, dim, type); /* Write unit conversion factors for this data set */ conversionString(buffer, us, convFactor); @@ -281,6 +283,7 @@ void writeArrayBackEnd(hid_t grp, char* fileName, FILE* xmfFile, char* name, * @param fileName The name of the file in which the data is written * @param xmfFile The FILE used to write the XMF description * @param name The name of the array to write. + * @param partTypeGroupName The name of the group containing the particles in the HDF5 file. * @param type The #DATA_TYPE of the array. * @param N The number of particles to write. * @param dim The dimension of the data (1 for scalar, 3 for vector) @@ -294,11 +297,10 @@ void writeArrayBackEnd(hid_t grp, char* fileName, FILE* xmfFile, char* name, * @param convFactor The UnitConversionFactor for this array * */ -#define writeArray(grp, fileName, xmfFile, name, type, N, dim, part, N_total, \ - mpi_rank, offset, field, us, convFactor) \ - writeArrayBackEnd(grp, fileName, xmfFile, name, type, N, dim, \ - (char*)(&(part[0]).field), sizeof(part[0]), us, \ - convFactor) +#define writeArray(grp, fileName, xmfFile, partTypeGroupName, name, type, N, \ + dim, part, N_total, mpi_rank, offset, field, us, convFactor)\ + writeArrayBackEnd(grp, fileName, xmfFile, partTypeGroupName, name, type, N, \ + dim, (char*)(&(part[0]).field), sizeof(part[0]), us, convFactor) /* Import the right hydro definition */ #include "hydro_io.h" @@ -496,7 +498,7 @@ void write_output_single(struct engine* e, struct UnitSystem* us) { xmfFile = prepareXMFfile(); /* Write the part corresponding to this specific output */ - writeXMFheader(xmfFile, Ngas, fileName, e->time); + writeXMFoutputheader(xmfFile, fileName, e->time); /* Open file */ /* message("Opening file '%s'.", fileName); */ @@ -569,6 +571,9 @@ void write_output_single(struct engine* e, struct UnitSystem* us) { /* Don't do anything if no particle of this kind */ if (numParticles[ptype] == 0) continue; + /* Add the global information for that particle type */ + writeXMFgroupheader(xmfFile, fileName, numParticles[ptype], ptype); + /* Open the particle group in the file */ char partTypeGroupName[PARTICLE_GROUP_BUFFER_SIZE]; snprintf(partTypeGroupName, PARTICLE_GROUP_BUFFER_SIZE, "/PartType%d", @@ -585,8 +590,8 @@ void write_output_single(struct engine* e, struct UnitSystem* us) { switch (ptype) { case GAS: - hydro_write_particles(h_grp, fileName, xmfFile, Ngas, Ngas, 0, 0, parts, - us); + hydro_write_particles(h_grp, fileName, partTypeGroupName, + xmfFile, Ngas, Ngas, 0, 0, parts, us); break; case DM: @@ -600,8 +605,8 @@ void write_output_single(struct engine* e, struct UnitSystem* us) { collect_dm_gparts(gparts, Ntot, dmparts, Ndm); /* Write DM particles */ - darkmatter_write_particles(h_grp, fileName, xmfFile, Ndm, Ndm, 0, 0, - dmparts, us); + darkmatter_write_particles(h_grp, fileName, partTypeGroupName, + xmfFile, Ndm, Ndm, 0, 0, dmparts, us); /* Free temporary array */ free(dmparts); @@ -613,10 +618,13 @@ void write_output_single(struct engine* e, struct UnitSystem* us) { /* Close particle group */ H5Gclose(h_grp); + + /* Close this particle group in the XMF file as well */ + writeXMFgroupfooter(xmfFile, ptype); } /* Write LXMF file descriptor */ - writeXMFfooter(xmfFile); + writeXMFoutputfooter(xmfFile, outputCount, e->time); /* message("Done writing particles..."); */