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

Add a more generic way of dealing with named columns for subgrid models

parent 19be81f2
......@@ -65,6 +65,15 @@ The rest of this page describes all the SWIFT parameters, split by
section. A list of all the possible parameters is kept in the file
``examples/parameter_examples.yml``.
.. _Parameters_meta_data:
Meta Data
---------
The ``MetaData`` section contains basic information about the simulation. It
currently only contains one parameter: ``run_name``. This is a string of
characters describing the simulation. It is written to the snapshots' headers.
.. _Parameters_units:
Internal Unit System
......@@ -73,7 +82,7 @@ Internal Unit System
The ``InternalUnitSystem`` section describes the units used internally by the
code. This is the system of units in which all the equations are solved. All
physical constants are converted to this system and if the ICs use a different
system (see the snapshots' ref:`ICs_units_label` section of the documentation)
system (see the snapshots' :ref:`ICs_units_label` section of the documentation)
the particle quantities will be converted when read in.
The system of units is described using the value of the 5 basic units
......
......@@ -15,6 +15,24 @@ of the simulation volume.
Header
------
The header group (``/Header``) contains basic information about the simulation
and the number of particles. For compatibility reasons, the SWIFT snapshot's
header format is identical to the Gadget-2 one with small additions.
In addition to the standard quantities, the header contains a field ``Code``
that is always set to the string ``SWIFT``, which can be used to identify
SWIFT-generated snapshots and hence make use of all the extensions to the file
format described below.
The most important quantity of the header is the array ``NumPart_ThisFile``
which contains the number of particles of each type in this snapshot. This is an
array of 6 numbers; one for each of the 5 supported types and a dummy "type 3"
field only used for compatibility reasons but always containing a zero.
The ``RunName`` field contains the name of the simulation that was specified as
the ``run_name`` in the :ref:`Parameters_meta_data` section of the YAML
parameter file.
Meta-data about the code and run
--------------------------------
......@@ -105,21 +123,23 @@ Structure of the particle arrays
There are several groups that contain 'auxiliary' information, such as
``Header``. Particle data is placed in separate groups depending of the type of
the particles. The type use the naming convention of Gadget-2 (with
the OWLS and EAGLE extensions).
+---------------------+------------------------+----------------------------------------+
| HDF5 Group Name | Physical Particle Type | In code ``enum part_type`` |
+=====================+========================+========================================+
| ``/PartType0/`` | Gas | ``swift_type_gas`` |
+---------------------+------------------------+----------------------------------------+
| ``/PartType1/`` | Dark Matter | ``swift_type_dark_matter`` |
+---------------------+------------------------+----------------------------------------+
| ``/PartType2/`` | Background Dark Matter | ``swift_type_dark_matter_background`` |
+---------------------+------------------------+----------------------------------------+
| ``/PartType4/`` | Stars | ``swift_type_star`` |
+---------------------+------------------------+----------------------------------------+
| ``/PartType5/`` | Black Holes | ``swift_type_black_hole`` |
+---------------------+------------------------+----------------------------------------+
the OWLS and EAGLE extensions). A more intuitive naming convention is
given in the form of aliases within the file. The aliases are shown in
the third column of the table.
+---------------------+------------------------+-----------------------------+----------------------------------------+
| HDF5 Group Name | Physical Particle Type | HDF5 alias | In code ``enum part_type`` |
+=====================+========================+=============================+========================================+
| ``/PartType0/`` | Gas | ``/GasParticles/`` | ``swift_type_gas`` |
+---------------------+------------------------+-----------------------------+----------------------------------------+
| ``/PartType1/`` | Dark Matter | ``/DMParticles/`` | ``swift_type_dark_matter`` |
+---------------------+------------------------+-----------------------------+----------------------------------------+
| ``/PartType2/`` | Background Dark Matter | ``/DMBackgroundParticles/`` | ``swift_type_dark_matter_background`` |
+---------------------+------------------------+-----------------------------+----------------------------------------+
| ``/PartType4/`` | Stars | ``/StarsParticles/`` | ``swift_type_star`` |
+---------------------+------------------------+-----------------------------+----------------------------------------+
| ``/PartType5/`` | Black Holes | ``/BHParticles/`` | ``swift_type_black_hole`` |
+---------------------+------------------------+-----------------------------+----------------------------------------+
The last column in the table gives the ``enum`` value from ``part_type.h``
corresponding to a given entry in the files.
......@@ -158,7 +178,7 @@ we encourage users to use this meta-data directly in their automated
tools.
As an example, the fluid densities (which are written in the co-moving
frame) have the following conversion factors:
frame) have the following (non-zero) conversion factors:
* ``U_L exponent``: -3
* ``U_M exponent``: 1
......
......@@ -279,19 +279,37 @@ INLINE static int chemistry_write_bparticles(const struct bpart* bparts,
/**
* @brief Writes the current model of SPH to the file
* @param h_grp The HDF5 group in which to write
* @param h_grp_columns The HDF5 group containing named columns
*/
INLINE static void chemistry_write_flavour(hid_t h_grp) {
INLINE static void chemistry_write_flavour(hid_t h_grp, hid_t h_grp_columns) {
/* Write the chemistry model */
io_write_attribute_s(h_grp, "Chemistry Model", "EAGLE");
io_write_attribute_d(h_grp, "Chemistry element count",
chemistry_element_count);
/* Create an array of element names */
const int element_name_length = 32;
char element_names[chemistry_element_count][element_name_length];
for (int elem = 0; elem < chemistry_element_count; ++elem) {
char buffer[20];
sprintf(buffer, "Element %d", elem);
io_write_attribute_s(
h_grp, buffer,
chemistry_get_element_name((enum chemistry_element)elem));
sprintf(element_names[elem], "%s",
chemistry_get_element_name((enum chemistry_element)elem));
}
/* Add to the named columns */
hsize_t dims[1] = {chemistry_element_count};
hid_t type = H5Tcopy(H5T_C_S1);
H5Tset_size(type, element_name_length);
hid_t space = H5Screate_simple(1, dims, NULL);
hid_t dset = H5Dcreate(h_grp_columns, "ElementMassFractions", type, space,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, element_names[0]);
H5Dclose(dset);
dset = H5Dcreate(h_grp_columns, "SmoothedElementMassFractions", type, space,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dset, type, H5S_ALL, H5S_ALL, H5P_DEFAULT, element_names[0]);
H5Dclose(dset);
H5Tclose(type);
H5Sclose(space);
}
#endif
......
......@@ -112,8 +112,9 @@ INLINE static int chemistry_write_bparticles(const struct bpart* bparts,
/**
* @brief Writes the current model of SPH to the file
* @param h_grp The HDF5 group in which to write
* @param h_grp_columns The HDF5 group containing named columns
*/
INLINE static void chemistry_write_flavour(hid_t h_grp) {
INLINE static void chemistry_write_flavour(hid_t h_grp, hid_t h_grp_columns) {
io_write_attribute_s(h_grp, "Chemistry Model", "GEAR");
io_write_attribute_d(h_grp, "Chemistry element count",
......
......@@ -45,7 +45,7 @@ __attribute__((always_inline)) INLINE static const char*
chemistry_get_element_name(enum chemistry_element elem) {
static const char* chemistry_element_names[chemistry_element_count] = {};
error("Attempting to get non-existing element!");
return chemistry_element_names[elem];
}
......
......@@ -94,11 +94,12 @@ INLINE static int chemistry_write_bparticles(const struct bpart* bparts,
/**
* @brief Writes the current model of chemistry to the file
* @param h_grp The HDF5 group in which to write
* @param h_grp_columns The HDF5 group containing named columns
*/
INLINE static void chemistry_write_flavour(hid_t h_grp) {
INLINE static void chemistry_write_flavour(hid_t h_grp, hid_t h_grp_columns) {
io_write_attribute_s(h_grp, "Chemistry Model", "Quick Lyman-alpha");
io_write_attribute_d(h_grp, "Chemistry element count", 0);
io_write_attribute_s(h_grp, "Chemistry Model",
"Quick Lyman-alpha (constant primordial)");
}
#endif
......
......@@ -94,11 +94,11 @@ INLINE static int chemistry_write_bparticles(const struct bpart* bparts,
/**
* @brief Writes the current model of chemistry to the file
* @param h_grp The HDF5 group in which to write
* @param h_grp_columns The HDF5 group containing named columns
*/
INLINE static void chemistry_write_flavour(hid_t h_grp) {
INLINE static void chemistry_write_flavour(hid_t h_grp, hid_t h_grp_columns) {
io_write_attribute_s(h_grp, "Chemistry Model", "None");
io_write_attribute_d(h_grp, "Chemistry element count", 0);
}
#endif
......
......@@ -1117,10 +1117,15 @@ void prepare_file(struct engine* e, const char* baseName, long long N_total[6],
io_write_attribute(h_grp, "Redshift", DOUBLE, &e->cosmology->z, 1);
io_write_attribute(h_grp, "Scale-factor", DOUBLE, &e->cosmology->a, 1);
io_write_attribute_s(h_grp, "Code", "SWIFT");
time_t tm = time(NULL);
io_write_attribute_s(h_grp, "Snapshot date", ctime(&tm));
io_write_attribute_s(h_grp, "RunName", e->run_name);
/* Store the time at which the snapshot was written */
time_t tm = time(NULL);
struct tm* timeinfo = localtime(&tm);
char snapshot_date[64];
strftime(snapshot_date, 64, "%T %F %Z", timeinfo);
io_write_attribute_s(h_grp, "Snapshot date", snapshot_date);
/* GADGET-2 legacy values */
/* Number of particles of each type */
unsigned int numParticles[swift_type_count] = {0};
......@@ -1169,11 +1174,15 @@ void prepare_file(struct engine* e, const char* baseName, long long N_total[6],
h_grp = H5Gcreate(h_file, "/SubgridScheme", H5P_DEFAULT, H5P_DEFAULT,
H5P_DEFAULT);
if (h_grp < 0) error("Error while creating subgrid group");
hid_t h_grp_columns =
H5Gcreate(h_grp, "NamedColumns", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (h_grp_columns < 0) error("Error while creating named columns group");
entropy_floor_write_flavour(h_grp);
cooling_write_flavour(h_grp, e->cooling_func);
chemistry_write_flavour(h_grp);
chemistry_write_flavour(h_grp, h_grp_columns);
tracers_write_flavour(h_grp);
feedback_write_flavour(e->feedback_props, h_grp);
H5Gclose(h_grp_columns);
H5Gclose(h_grp);
/* Print the gravity parameters */
......@@ -1243,7 +1252,18 @@ void prepare_file(struct engine* e, const char* baseName, long long N_total[6],
h_grp = H5Gcreate(h_file, partTypeGroupName, H5P_DEFAULT, H5P_DEFAULT,
H5P_DEFAULT);
if (h_grp < 0)
error("Error while opening particle group %s.", partTypeGroupName);
error("Error while creating particle group %s.", partTypeGroupName);
/* Add an alias name for convenience */
char aliasName[PARTICLE_GROUP_BUFFER_SIZE];
snprintf(aliasName, PARTICLE_GROUP_BUFFER_SIZE, "/%sParticles",
part_type_names[ptype]);
hid_t h_err = H5Lcreate_soft(partTypeGroupName, h_grp, aliasName,
H5P_DEFAULT, H5P_DEFAULT);
if (h_err < 0) error("Error while creating alias for particle group.\n");
/* Write the number of particles as an attribute */
io_write_attribute_l(h_grp, "NumberOfParticles", N_total[ptype]);
int num_fields = 0;
struct io_props list[100];
......
......@@ -21,4 +21,4 @@
#include "part_type.h"
const char* part_type_names[swift_type_count] = {
"Gas", "DM", "DM_background", "Dummy", "Stars", "BH"};
"Gas", "DM", "DMBackground", "Dummy", "Stars", "BH"};
......@@ -982,10 +982,15 @@ void write_output_serial(struct engine* e, const char* baseName,
io_write_attribute(h_grp, "Redshift", DOUBLE, &e->cosmology->z, 1);
io_write_attribute(h_grp, "Scale-factor", DOUBLE, &e->cosmology->a, 1);
io_write_attribute_s(h_grp, "Code", "SWIFT");
time_t tm = time(NULL);
io_write_attribute_s(h_grp, "Snapshot date", ctime(&tm));
io_write_attribute_s(h_grp, "RunName", e->run_name);
/* Store the time at which the snapshot was written */
time_t tm = time(NULL);
struct tm* timeinfo = localtime(&tm);
char snapshot_date[64];
strftime(snapshot_date, 64, "%T %F %Z", timeinfo);
io_write_attribute_s(h_grp, "Snapshot date", snapshot_date);
/* GADGET-2 legacy values */
/* Number of particles of each type */
unsigned int numParticles[swift_type_count] = {0};
......@@ -1034,11 +1039,15 @@ void write_output_serial(struct engine* e, const char* baseName,
h_grp = H5Gcreate(h_file, "/SubgridScheme", H5P_DEFAULT, H5P_DEFAULT,
H5P_DEFAULT);
if (h_grp < 0) error("Error while creating subgrid group");
hid_t h_grp_columns =
H5Gcreate(h_grp, "NamedColumns", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (h_grp_columns < 0) error("Error while creating named columns group");
entropy_floor_write_flavour(h_grp);
cooling_write_flavour(h_grp, e->cooling_func);
chemistry_write_flavour(h_grp);
chemistry_write_flavour(h_grp, h_grp_columns);
tracers_write_flavour(h_grp);
feedback_write_flavour(e->feedback_props, h_grp);
H5Gclose(h_grp_columns);
H5Gclose(h_grp);
/* Print the gravity parameters */
......@@ -1139,6 +1148,17 @@ void write_output_serial(struct engine* e, const char* baseName,
/* Close particle group */
H5Gclose(h_grp);
/* Add an alias name for convenience */
char aliasName[PARTICLE_GROUP_BUFFER_SIZE];
snprintf(aliasName, PARTICLE_GROUP_BUFFER_SIZE, "/%sParticles",
part_type_names[ptype]);
hid_t h_err = H5Lcreate_soft(partTypeGroupName, h_grp, aliasName,
H5P_DEFAULT, H5P_DEFAULT);
if (h_err < 0) error("Error while creating alias for particle group.\n");
/* Write the number of particles as an attribute */
io_write_attribute_l(h_grp, "NumberOfParticles", N_total[ptype]);
}
/* Close file */
......
......@@ -827,10 +827,15 @@ void write_output_single(struct engine* e, const char* baseName,
io_write_attribute(h_grp, "Redshift", DOUBLE, &e->cosmology->z, 1);
io_write_attribute(h_grp, "Scale-factor", DOUBLE, &e->cosmology->a, 1);
io_write_attribute_s(h_grp, "Code", "SWIFT");
time_t tm = time(NULL);
io_write_attribute_s(h_grp, "Snapshot date", ctime(&tm));
io_write_attribute_s(h_grp, "RunName", e->run_name);
/* Store the time at which the snapshot was written */
time_t tm = time(NULL);
struct tm* timeinfo = localtime(&tm);
char snapshot_date[64];
strftime(snapshot_date, 64, "%T %F %Z", timeinfo);
io_write_attribute_s(h_grp, "Snapshot date", snapshot_date);
/* GADGET-2 legacy values */
/* Number of particles of each type */
unsigned int numParticles[swift_type_count] = {0};
......@@ -879,11 +884,15 @@ void write_output_single(struct engine* e, const char* baseName,
h_grp = H5Gcreate(h_file, "/SubgridScheme", H5P_DEFAULT, H5P_DEFAULT,
H5P_DEFAULT);
if (h_grp < 0) error("Error while creating subgrid group");
hid_t h_grp_columns =
H5Gcreate(h_grp, "NamedColumns", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
if (h_grp_columns < 0) error("Error while creating named columns group");
entropy_floor_write_flavour(h_grp);
cooling_write_flavour(h_grp, e->cooling_func);
chemistry_write_flavour(h_grp);
chemistry_write_flavour(h_grp, h_grp_columns);
tracers_write_flavour(h_grp);
feedback_write_flavour(e->feedback_props, h_grp);
H5Gclose(h_grp_columns);
H5Gclose(h_grp);
/* Print the gravity parameters */
......@@ -998,6 +1007,17 @@ void write_output_single(struct engine* e, const char* baseName,
H5P_DEFAULT);
if (h_grp < 0) error("Error while creating particle group.\n");
/* Add an alias name for convenience */
char aliasName[PARTICLE_GROUP_BUFFER_SIZE];
snprintf(aliasName, PARTICLE_GROUP_BUFFER_SIZE, "/%sParticles",
part_type_names[ptype]);
hid_t h_err = H5Lcreate_soft(partTypeGroupName, h_grp, aliasName,
H5P_DEFAULT, H5P_DEFAULT);
if (h_err < 0) error("Error while creating alias for particle group.\n");
/* Write the number of particles as an attribute */
io_write_attribute_l(h_grp, "NumberOfParticles", numParticles[ptype]);
int num_fields = 0;
struct io_props list[100];
size_t N = 0;
......
......@@ -37,7 +37,7 @@
__attribute__((always_inline)) INLINE static void tracers_write_flavour(
hid_t h_grp) {
io_write_attribute_s(h_grp, "Tracers", "none");
io_write_attribute_s(h_grp, "Tracers", "None");
}
#endif
......
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