Commit 65010a5f authored by Matthieu Schaller's avatar Matthieu Schaller
Browse files

Added support for multiple particle types in XMF

parent 34e76452
......@@ -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");
}
......
......@@ -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);
......
......@@ -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);
}
......@@ -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);
}
/**
......
......@@ -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); */
......
......@@ -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..."); */
......
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