diff --git a/configure.ac b/configure.ac index d119cfa3a99c1c85456056eab5d73b334ec86d15..84c4eb3c6fb9e3faf8ba108df0e26992dd581812 100644 --- a/configure.ac +++ b/configure.ac @@ -2388,6 +2388,27 @@ AM_CONDITIONAL([HAVE_SPHENIX], [test "$with_hydro" = "sphenix"]) # check if using GADGET2 SPH AM_CONDITIONAL([HAVE_GADGET2], [test "$with_hydro" = "gadget2"]) +# check if using none chemistry +AM_CONDITIONAL([HAVE_CHEMISTRY_NONE], [test "$with_chemistry" = "none"]) + +# check if using GEAR chemistry +AM_CONDITIONAL([HAVE_CHEMISTRY_GEAR], [test "${with_chemistry:0:5}" = "GEAR_"]) + +# check if using default stars +AM_CONDITIONAL([HAVE_STARS_DEFAULT], [test "$with_stars" = "none"]) + +# check if using GEAR stars +AM_CONDITIONAL([HAVE_STARS_GEAR], [test "$with_stars" = "GEAR"]) + +# check if using default star formation +AM_CONDITIONAL([HAVE_STAR_FORMATION_DEFAULT], [test "$with_star_formation" = "none"]) + +# check if using GEAR star formation +AM_CONDITIONAL([HAVE_STAR_FORMATION_GEAR], [test "$with_star_formation" = "GEAR"]) + +# check if using multi softening gravity +AM_CONDITIONAL([HAVE_GRAVITY_MULTISOFTENING], [test "$with_gravity" = "with-multi-softening"]) + # Handle .in files. AC_CONFIG_FILES([Makefile src/Makefile examples/Makefile examples/Cooling/CoolingRates/Makefile doc/Makefile doc/Doxyfile tests/Makefile]) AC_CONFIG_FILES([argparse/Makefile tools/Makefile logger/Makefile logger/tests/Makefile]) diff --git a/doc/RTD/source/AnalysisTools/index.rst b/doc/RTD/source/AnalysisTools/index.rst index e908b378350c208635335728de4f8accc8024cfa..bf827d1b4a6a74f6171aef733627e8584fa50929 100644 --- a/doc/RTD/source/AnalysisTools/index.rst +++ b/doc/RTD/source/AnalysisTools/index.rst @@ -10,7 +10,7 @@ Analysis Tools Task dependencies ----------------- -At the beginning of each simulation the file ``dependency_graph.csv`` is generated and can be transformed into a ``dot`` and a ``png`` file with the script ``tools/plot_task_dependencies.py``. +At the beginning of each simulation the file ``dependency_graph_0.csv`` is generated and can be transformed into a ``dot`` and a ``png`` file with the script ``tools/plot_task_dependencies.py``. It requires the ``dot`` package that is available in the library graphviz. This script has also the possibility to generate a list of function calls for each task with the option ``--with-calls`` (this list may be incomplete) and to describe at which level each task are run ``--with-levels`` (a larger simulation will provide more accurate levels). You can convert the ``dot`` file into a ``png`` with the following command @@ -19,6 +19,24 @@ If you wish to have more dependency graphs, you can use the parameter ``Schedule While the initial graph is showing all the tasks/dependencies, the next ones are only showing the active tasks/dependencies. + +Task levels +----------------- + +At the beginning of each simulation the file ``task_level_0.txt`` is generated. +It contains the counts of all tasks at all levels (depths) in the tree. +The depths and counts of the tasks can be plotted with the script ``tools/plot_task_levels.py``. +It will display the individual tasks at the x-axis, the number of each task at a given level on the y-axis, and the level is shown as the colour of the plotted point. +Additionally, the script can write out in brackets next to each tasks's name on the x-axis on how many different levels the task exists using the ``--count`` flag. +Finally, in some cases the counts for different levels of a task may be very close to each other and overlap on the plot, making them barely visible. +This can be alleviated by using the ``--displace`` flag: +It will displace the plot points w.r.t. the y-axis in an attempt to make them better visible, however the counts won't be exact in that case. +If you wish to have more task level plots, you can use the parameter ``Scheduler:task_level_output_frequency``. +It defines how many steps are done in between two task level output dumps. + + + + Cell graph ---------- diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index 5eec165ede647f7ccb7a69f41bc1ab86ead122e8..8933395fa6f28778beb6b00ff110c07c6950c4c0 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -134,6 +134,7 @@ Scheduler: engine_max_sparts_per_ghost: 1000 # (Optional) Maximum number of sparts per ghost. engine_max_parts_per_cooling: 10000 # (Optional) Maximum number of parts per cooling task. dependency_graph_frequency: 0 # (Optional) Dumping frequency of the dependency graph. By default, writes only at the first step. + task_level_output_frequency: 0 # (Optional) Dumping frequency of the task level data. By default, writes only at the first step. # Parameters governing the time integration (Set dt_min and dt_max to the same value for a fixed time-step run.) TimeIntegration: diff --git a/logger/examples/create_snapshot.py b/logger/examples/create_snapshot.py new file mode 100644 index 0000000000000000000000000000000000000000..79d42202e5a43b819b8c4c0d329cef769069015c --- /dev/null +++ b/logger/examples/create_snapshot.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +""" +Read a logger file by using an index file and then write a snapshot. +Example: python3 create_snapshot -t 0.1 -o out.hdf5 ../../examples/SedovBlast_3D/index_*dump +""" +import sys +import h5py +import numpy as np +from glob import glob +import argparse +sys.path.append("../.libs/") + +import liblogger as logger + + +def parse_arguments(): + parser = argparse.ArgumentParser( + description='Read a logfile and plots some basic properties') + + default_files = "../../examples/HydroTests/SedovBlast_3D/index_*dump" + default_files = glob(default_files) + + parser.add_argument("-o", '--output', dest='out', + type=str, default="out.hdf5", + help='Output filename') + parser.add_argument("-t", '--time', dest='time', + type=float, default=0.01, + help='Simulation time') + parser.add_argument('files', metavar='filenames', type=str, nargs="*", + help='The filenames of the logfiles') + args = parser.parse_args() + if len(args.files) == 0: + args.files = default_files + return args + + +def write_particle_type(snap, part_type, args): + """ + Write a particle type inside an HDF5 file. + + Parameters + ---------- + + snap: h5py.File + The output file. + + part_type: int + The particle type to write + + args: ArgumentParser + The argument parser + + Returns + ------- + + npart: int + The number of particles of the given type. + """ + fields = None + fields_name = None + + # Read all the fields + for f in args.files: + if f.endswith(".dump"): + filename = f[:-5] + else: + raise Exception("It seems that you are not providing a logfile (.dump)") + + # Open the logger + with logger.Reader(filename, verbose=0) as reader: + + # Get the list of fields + if fields_name is None: + fields_name = reader.get_list_fields(part_type) + + # Abort if only requesting a type not implemented + if "SpecialFlags" in fields_name: + print("Part type %i not implemented, skipping it" % part_type) + continue + + # Read the fields + fields_tmp = reader.get_particle_data(fields_name, args.time, part_type) + if fields is None: + fields = fields_tmp + else: + for i, field in enumerate(fields): + fields[i] = np.append(fields[i], fields_tmp[i], axis=0) + + # Do we have this particle type? + if fields is None or fields[0].shape[0] == 0: + return 0 + + # Get the number of particles + npart = fields[0].shape[0] + + # Create the group + name = "PartType%i" % part_type + grp = snap.create_group(name) + + # Save the data + for i, field in enumerate(fields_name): + grp.create_dataset(field, data=fields[i]) + + return npart + + +if __name__ == "__main__": + args = parse_arguments() + print("Output: %s" % args.out) + print("basename: %s" % args.files) + print("time: %g" % args.time) + + # read the logger + n_types = 6 + + # Create a snapshot + with h5py.File(args.out, "w") as snap: + npart = np.zeros(n_types) + for part_type in range(n_types): + npart[part_type] = write_particle_type(snap, part_type, args) + + + # Write the header + grp = snap.create_group("Header") + grp.attrs["NumPart_Total"] = npart + grp.attrs["NumPart_Total_HighWord"] = [0] * n_types + grp.attrs["NumPart_ThisFile"] = npart + grp.attrs["Time"] = args.time + grp.attrs["NumFilesPerSnapshot"] = 1 + grp.attrs["MassTable"] = [0.0] * n_types + diff --git a/logger/examples/reader_example.py b/logger/examples/reader_example.py index e3518cf61914ba6916075433c90b1f0877f0e4f8..5c2ef10602b6eac20ba71d4a9f137446ed9d2004 100644 --- a/logger/examples/reader_example.py +++ b/logger/examples/reader_example.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """ Read a logger file by using an index file. -Example: ./reader_example.py ../../examples/SedovBlast_3D/index 0.1 +Example: ./reader_example.py -t 0.1 ../../examples/SedovBlast_3D/index_*dump """ import sys import numpy as np diff --git a/src/Makefile.am b/src/Makefile.am index b9d9ff5cf46a568b538321687ec6844a198aab04..ad1a3b8c331730442f59bae1f4b53c9649fc84a7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,8 +62,8 @@ include_HEADERS += black_holes.h black_holes_io.h black_holes_properties.h black include_HEADERS += feedback.h feedback_struct.h feedback_properties.h include_HEADERS += space_unique_id.h line_of_sight.h io_compression.h include_HEADERS += rays.h rays_struct.h -include_HEADERS += logger_history.h include_HEADERS += particle_splitting.h particle_splitting_struct.h +include_HEADERS += logger_history.h chemistry_logger.h star_formation_particle_logger.h # source files for EAGLE cooling QLA_COOLING_SOURCES = @@ -102,6 +102,48 @@ GEAR_FEEDBACK_SOURCES += feedback/GEAR/stellar_evolution.c feedback/GEAR/feedbac feedback/GEAR/initial_mass_function.c feedback/GEAR/supernovae_ia.c feedback/GEAR/supernovae_ii.c endif +# source files for the logger (chemistry) +CHEMISTRY_LOGGER = +if HAVE_CHEMISTRY_NONE +CHEMISTRY_LOGGER += chemistry/none/chemistry_logger.c +endif +if HAVE_CHEMISTRY_GEAR +CHEMISTRY_LOGGER += chemistry/GEAR/chemistry_logger.c +endif + +# source files for the logger (hydro) +HYDRO_LOGGER = +if HAVE_GADGET2 +HYDRO_LOGGER += hydro/Gadget2/hydro_logger.c +endif +if HAVE_SPHENIX +HYDRO_LOGGER += hydro/SPHENIX/hydro_logger.c +endif + +# source files for the logger (stars) +STARS_LOGGER = +if HAVE_STARS_DEFAULT +STARS_LOGGER += stars/Default/stars_logger.c +endif +if HAVE_STARS_GEAR +STARS_LOGGER += stars/GEAR/stars_logger.c +endif + +# source files for the logger (stars) +STAR_FORMATION_LOGGER = +if HAVE_STAR_FORMATION_DEFAULT +STAR_FORMATION_LOGGER += star_formation/none/star_formation_particle_logger.c +endif +if HAVE_STAR_FORMATION_GEAR +STAR_FORMATION_LOGGER += star_formation/GEAR/star_formation_particle_logger.c +endif + +# source files for the logger (gravity) +GRAVITY_LOGGER = +if HAVE_GRAVITY_MULTISOFTENING +GRAVITY_LOGGER += gravity/MultiSoftening/gravity_logger.c +endif + # Common source files AM_SOURCES = space.c space_rebuild.c space_regrid.c space_unique_id.c AM_SOURCES += space_sort.c space_split.c space_extras.c space_first_init.c space_init.c @@ -133,6 +175,8 @@ AM_SOURCES += $(QLA_COOLING_SOURCES) AM_SOURCES += $(EAGLE_COOLING_SOURCES) $(EAGLE_FEEDBACK_SOURCES) AM_SOURCES += $(GRACKLE_COOLING_SOURCES) $(GEAR_FEEDBACK_SOURCES) AM_SOURCES += $(COLIBRE_COOLING_SOURCES) +AM_SOURCES += $(CHEMISTRY_LOGGER) $(HYDRO_LOGGER) $(STARS_LOGGER) $(GRAVITY_LOGGER) +AM_SOURCES += $(STAR_FORMATION_LOGGER) # Include files for distribution, not installation. nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h inline.h kernel_hydro.h kernel_gravity.h @@ -241,7 +285,7 @@ nobase_noinst_HEADERS += stars/Default/stars_debug.h stars/Default/stars_part.h nobase_noinst_HEADERS += stars/EAGLE/stars.h stars/EAGLE/stars_iact.h stars/EAGLE/stars_io.h nobase_noinst_HEADERS += stars/EAGLE/stars_debug.h stars/EAGLE/stars_part.h nobase_noinst_HEADERS += stars/GEAR/stars.h stars/GEAR/stars_iact.h stars/GEAR/stars_io.h -nobase_noinst_HEADERS += stars/GEAR/stars_debug.h stars/GEAR/stars_part.h +nobase_noinst_HEADERS += stars/GEAR/stars_debug.h stars/GEAR/stars_logger.h stars/GEAR/stars_part.h nobase_noinst_HEADERS += potential/none/potential.h potential/point_mass/potential.h nobase_noinst_HEADERS += potential/isothermal/potential.h potential/disc_patch/potential.h nobase_noinst_HEADERS += potential/sine_wave/potential.h potential/constant/potential.h @@ -249,13 +293,15 @@ nobase_noinst_HEADERS += potential/hernquist/potential.h potential/nfw/potential nobase_noinst_HEADERS += potential/nfw_mn/potential.h potential/point_mass_softened/potential.h nobase_noinst_HEADERS += potential/point_mass_ring/potential.h nobase_noinst_HEADERS += star_formation/none/star_formation.h star_formation/none/star_formation_struct.h -nobase_noinst_HEADERS += star_formation/none/star_formation_io.h star_formation/none/star_formation_iact.h +nobase_noinst_HEADERS += star_formation/none/star_formation_io.h star_formation/none/star_formation_iact.h +nobase_noinst_HEADERS += star_formation/none/star_formation_particle_logger.h nobase_noinst_HEADERS += star_formation/QLA/star_formation.h star_formation/QLA/star_formation_struct.h nobase_noinst_HEADERS += star_formation/QLA/star_formation_io.h star_formation/QLA/star_formation_iact.h nobase_noinst_HEADERS += star_formation/EAGLE/star_formation.h star_formation/EAGLE/star_formation_struct.h nobase_noinst_HEADERS += star_formation/EAGLE/star_formation_io.h star_formation/EAGLE/star_formation_iact.h nobase_noinst_HEADERS += star_formation/GEAR/star_formation.h star_formation/GEAR/star_formation_struct.h nobase_noinst_HEADERS += star_formation/GEAR/star_formation_io.h star_formation/GEAR/star_formation_iact.h +nobase_noinst_HEADERS += star_formation/GEAR/star_formation_particle_logger.h nobase_noinst_HEADERS += star_formation/EAGLE/star_formation_logger.h star_formation/EAGLE/star_formation_logger_struct.h nobase_noinst_HEADERS += star_formation/GEAR/star_formation_logger.h star_formation/GEAR/star_formation_logger_struct.h nobase_noinst_HEADERS += star_formation/none/star_formation_logger.h star_formation/none/star_formation_logger_struct.h @@ -279,10 +325,12 @@ nobase_noinst_HEADERS += cooling/COLIBRE/cooling_tables.h cooling/COLIBRE/coolin nobase_noinst_HEADERS += cooling/COLIBRE/cooling_properties.h nobase_noinst_HEADERS += chemistry/none/chemistry.h nobase_noinst_HEADERS += chemistry/none/chemistry_io.h +nobase_noinst_HEADERS += chemistry/none/chemistry_logger.h nobase_noinst_HEADERS += chemistry/none/chemistry_struct.h nobase_noinst_HEADERS += chemistry/none/chemistry_iact.h nobase_noinst_HEADERS += chemistry/GEAR/chemistry.h nobase_noinst_HEADERS += chemistry/GEAR/chemistry_io.h +nobase_noinst_HEADERS += chemistry/GEAR/chemistry_logger.h nobase_noinst_HEADERS += chemistry/GEAR/chemistry_struct.h nobase_noinst_HEADERS += chemistry/GEAR/chemistry_iact.h nobase_noinst_HEADERS += chemistry/GEAR_DIFFUSION/chemistry.h diff --git a/src/chemistry/GEAR/chemistry_logger.c b/src/chemistry/GEAR/chemistry_logger.c new file mode 100644 index 0000000000000000000000000000000000000000..58b7fa3fc1627987e1097a34fe2654075487a72e --- /dev/null +++ b/src/chemistry/GEAR/chemistry_logger.c @@ -0,0 +1,35 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +#include "../config.h" + +#ifdef WITH_LOGGER + +#include "chemistry_logger.h" + +const char + *chemistry_logger_field_names_part[chemistry_logger_field_part_count] = { + "ChemistryHydro", +}; +const char + *chemistry_logger_field_names_spart[chemistry_logger_field_spart_count] = { + "MetalMassFractions", +}; + +#endif // WITH_LOGGER diff --git a/src/chemistry/GEAR/chemistry_logger.h b/src/chemistry/GEAR/chemistry_logger.h new file mode 100644 index 0000000000000000000000000000000000000000..4c113a195d2f01ced0dea2ebc2cb408ad69b3179 --- /dev/null +++ b/src/chemistry/GEAR/chemistry_logger.h @@ -0,0 +1,209 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_CHEMISTRY_NONE_CHEMISTRY_LOGGER_H +#define SWIFT_CHEMISTRY_NONE_CHEMISTRY_LOGGER_H + +#include "hydro.h" +#include "logger_io.h" + +#ifdef WITH_LOGGER + +/* + * List of all possible mask. + * Outside the module, only chemistry_logger_field_count is used. + */ +// Here I am only using a single flag in order to free some flags to the other +// modules. +enum chemistry_logger_fields_part { + chemistry_logger_field_part_all = 0, + chemistry_logger_field_part_count, +}; +enum chemistry_logger_fields_spart { + chemistry_logger_field_spart_metal_mass_fractions = 0, + chemistry_logger_field_spart_count, +}; + +/* Name of each possible mask. */ +extern const char + *chemistry_logger_field_names_part[chemistry_logger_field_part_count]; +extern const char + *chemistry_logger_field_names_spart[chemistry_logger_field_spart_count]; + +/** + * @brief Initialize the logger for the #part. + * + * WARNING: The order should be the same in all the functions and + * #chemistry_logger_fields_part! + * + * @param mask_data Data for each type of mask. + * + * @return Number of masks used. + */ +INLINE static int chemistry_logger_writer_populate_mask_data_part( + struct mask_data *mask_data) { + + /* We store the metal mass fraction and the smoothed one. */ + mask_data[chemistry_logger_field_part_all] = logger_create_mask_entry( + chemistry_logger_field_names_part[chemistry_logger_field_part_all], + 2 * GEAR_CHEMISTRY_ELEMENT_COUNT * sizeof(double)); + return chemistry_logger_field_part_count; +} + +/** + * @brief Initialize the logger for the #spart. + * + * WARNING: The order should be the same in all the functions and + * #chemistry_logger_fields_spart! + * + * @param mask_data Data for each type of mask. + * + * @return Number of masks used. + */ +INLINE static int chemistry_logger_writer_populate_mask_data_spart( + struct mask_data *mask_data) { + /* We store the metal mass fraction. */ + mask_data[chemistry_logger_field_spart_metal_mass_fractions] = + logger_create_mask_entry( + chemistry_logger_field_names_spart + [chemistry_logger_field_spart_metal_mass_fractions], + GEAR_CHEMISTRY_ELEMENT_COUNT * sizeof(double)); + + return chemistry_logger_field_spart_count; +} + +/** + * @brief Generates the mask and compute the size of the record for the #part. + * + * WARNING: The order should be the same in all the functions and + * #chemistry_logger_fields_part! + * + * @param masks The list of masks (same order than in + * #chemistry_logger_writer_populate_mask_data_part). + * @param part The #part that will be written. + * @param xpart The #xpart that will be written. + * @param write_all Are we forcing to write all the fields? + * + * @param buffer_size (out) The requested size for the buffer. + * @param mask (out) The mask that will be written. + */ +INLINE static void chemistry_logger_compute_size_and_mask_part( + const struct mask_data *masks, const struct part *part, + const struct xpart *xpart, const int write_all, size_t *buffer_size, + unsigned int *mask) { + /* Add the chemistry. */ + *mask |= logger_add_field_to_mask(masks[chemistry_logger_field_part_all], + buffer_size); +} + +/** + * @brief Generates the mask and compute the size of the record for the #spart. + * + * WARNING: The order should be the same in all the functions and + * #chemistry_logger_fields_spart! + * + * @param masks The list of masks (same order than in + * #chemistry_logger_writer_populate_mask_data_spart). + * @param spart The #spart that will be written. + * @param write_all Are we forcing to write all the fields? + * + * @param buffer_size (out) The requested size for the buffer. + * @param mask (out) The mask that will be written. + */ +INLINE static void chemistry_logger_compute_size_and_mask_spart( + const struct mask_data *masks, const struct spart *spart, + const int write_all, size_t *buffer_size, unsigned int *mask) { + + /* Add the chemistry. */ + *mask |= logger_add_field_to_mask( + masks[chemistry_logger_field_spart_metal_mass_fractions], buffer_size); +} + +/** + * @brief Write a #part to the logger. + * + * WARNING: The order should be the same in all the functions and + * #hydro_logger_fields_part! + * + * @param masks The list of masks (same order than in + * #chemistry_logger_writer_populate_mask_data_part). + * @param p The #part to write. + * @param xp The #xpart to write. + * @param mask The mask to use for this record. + * @param buff The buffer where to write the particle. + * + * @return The buffer after the data. + */ +INLINE static char *chemistry_logger_write_particle( + const struct mask_data *mask_data, const struct part *p, + const struct xpart *xp, unsigned int *mask, char *buff) { + + /* Write the chemistry. */ + if (logger_should_write_field(mask_data[chemistry_logger_field_part_all], + mask)) { + + /* Write the smoothed metal mass fraction */ + memcpy(buff, p->chemistry_data.smoothed_metal_mass_fraction, + GEAR_CHEMISTRY_ELEMENT_COUNT * sizeof(double)); + buff += GEAR_CHEMISTRY_ELEMENT_COUNT * sizeof(double); + + /* Write the metal mass */ + double *frac = (double *)buff; + const float m = hydro_get_mass(p); + for (int i = 0; i < GEAR_CHEMISTRY_ELEMENT_COUNT; i++) { + *frac = p->chemistry_data.metal_mass[i] / m; + frac += 1; + } + } + + return buff; +} + +/** + * @brief Write a #spart to the logger. + * + * WARNING: The order should be the same in all the functions and + * #hydro_logger_fields_spart! + * + * @param masks The list of masks (same order than in + * #chemistry_logger_writer_populate_mask_data_spart). + * @param sp The #spart to write. + * @param mask The mask to use for this record. + * @param buff The buffer where to write the particle. + * + * @return The buffer after the data. + */ +INLINE static char *chemistry_logger_write_sparticle( + const struct mask_data *mask_data, const struct spart *sp, + unsigned int *mask, char *buff) { + + /* Write the metal mass fraction. */ + if (logger_should_write_field( + mask_data[chemistry_logger_field_spart_metal_mass_fractions], mask)) { + + /* Write the metal mass fraction */ + memcpy(buff, sp->chemistry_data.metal_mass_fraction, + GEAR_CHEMISTRY_ELEMENT_COUNT * sizeof(double)); + buff += GEAR_CHEMISTRY_ELEMENT_COUNT * sizeof(double); + } + + return buff; +} + +#endif // WITH_LOGGER +#endif // SWIFT_CHEMISTRY_NONE_CHEMISTRY_LOGGER_H diff --git a/src/chemistry/none/chemistry_logger.c b/src/chemistry/none/chemistry_logger.c new file mode 100644 index 0000000000000000000000000000000000000000..707273d4d4a43f7c0b5bda5057e1b189c7c41a38 --- /dev/null +++ b/src/chemistry/none/chemistry_logger.c @@ -0,0 +1,31 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +#include "../config.h" + +#ifdef WITH_LOGGER + +#include "chemistry_logger.h" + +const char + *chemistry_logger_field_names_part[chemistry_logger_field_part_count] = {}; +const char * + chemistry_logger_field_names_spart[chemistry_logger_field_spart_count] = {}; + +#endif // WITH_LOGGER diff --git a/src/chemistry/none/chemistry_logger.h b/src/chemistry/none/chemistry_logger.h new file mode 100644 index 0000000000000000000000000000000000000000..caf005d29d3055f3eb7cd1ef9c7ff877fc94b11e --- /dev/null +++ b/src/chemistry/none/chemistry_logger.h @@ -0,0 +1,153 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_CHEMISTRY_NONE_CHEMISTRY_LOGGER_H +#define SWIFT_CHEMISTRY_NONE_CHEMISTRY_LOGGER_H + +#include "logger_io.h" + +#ifdef WITH_LOGGER + +/* + * List of all possible mask. + * Outside the module, only chemistry_logger_field_count is used. + */ +enum chemistry_logger_fields_part { + chemistry_logger_field_part_count = 0, +}; +enum chemistry_logger_fields_spart { + chemistry_logger_field_spart_count = 0, +}; + +/* Name of each possible mask. */ +extern const char + *chemistry_logger_field_names_part[chemistry_logger_field_part_count]; +extern const char + *chemistry_logger_field_names_spart[chemistry_logger_field_spart_count]; + +/** + * @brief Initialize the logger for the #part. + * + * WARNING: The order should be the same in all the functions and + * #chemistry_logger_fields_part! + * + * @param mask_data Data for each type of mask. + * + * @return Number of masks used. + */ +INLINE static int chemistry_logger_writer_populate_mask_data_part( + struct mask_data *mask_data) { + return chemistry_logger_field_part_count; +} + +/** + * @brief Initialize the logger for the #spart. + * + * WARNING: The order should be the same in all the functions and + * #chemistry_logger_fields_spart! + * + * @param mask_data Data for each type of mask. + * + * @return Number of masks used. + */ +INLINE static int chemistry_logger_writer_populate_mask_data_spart( + struct mask_data *mask_data) { + return chemistry_logger_field_spart_count; +} + +/** + * @brief Generates the mask and compute the size of the record for the #part. + * + * WARNING: The order should be the same in all the functions and + * #chemistry_logger_fields_part! + * + * @param masks The list of masks (same order than in + * #chemistry_logger_writer_populate_mask_data_part). + * @param part The #part that will be written. + * @param xpart The #xpart that will be written. + * @param write_all Are we forcing to write all the fields? + * + * @param buffer_size (out) The requested size for the buffer. + * @param mask (out) The mask that will be written. + */ +INLINE static void chemistry_logger_compute_size_and_mask_part( + const struct mask_data *masks, const struct part *part, + const struct xpart *xpart, const int write_all, size_t *buffer_size, + unsigned int *mask) {} + +/** + * @brief Generates the mask and compute the size of the record for the #spart. + * + * WARNING: The order should be the same in all the functions and + * #chemistry_logger_fields_spart! + * + * @param masks The list of masks (same order than in + * #chemistry_logger_writer_populate_mask_data_spart). + * @param spart The #spart that will be written. + * @param write_all Are we forcing to write all the fields? + * + * @param buffer_size (out) The requested size for the buffer. + * @param mask (out) The mask that will be written. + */ +INLINE static void chemistry_logger_compute_size_and_mask_spart( + const struct mask_data *masks, const struct spart *spart, + const int write_all, size_t *buffer_size, unsigned int *mask) {} + +/** + * @brief Write a #part to the logger. + * + * WARNING: The order should be the same in all the functions and + * #hydro_logger_fields_part! + * + * @param masks The list of masks (same order than in + * #chemistry_logger_writer_populate_mask_data_part). + * @param p The #part to write. + * @param xp The #xpart to write. + * @param mask The mask to use for this record. + * @param buff The buffer where to write the particle. + * + * @return The buffer after the data. + */ +INLINE static char *chemistry_logger_write_particle( + const struct mask_data *mask_data, const struct part *p, + const struct xpart *xp, unsigned int *mask, char *buff) { + return buff; +} + +/** + * @brief Write a #spart to the logger. + * + * WARNING: The order should be the same in all the functions and + * #hydro_logger_fields_spart! + * + * @param masks The list of masks (same order than in + * #chemistry_logger_writer_populate_mask_data_spart). + * @param sp The #spart to write. + * @param mask The mask to use for this record. + * @param buff The buffer where to write the particle. + * + * @return The buffer after the data. + */ +INLINE static char *chemistry_logger_write_sparticle( + const struct mask_data *mask_data, const struct spart *sp, + unsigned int *mask, char *buff) { + return buff; +} + +#endif // WITH_LOGGER +#endif // SWIFT_CHEMISTRY_NONE_CHEMISTRY_LOGGER_H diff --git a/src/chemistry_logger.h b/src/chemistry_logger.h new file mode 100644 index 0000000000000000000000000000000000000000..6d17216391d2ec42b8613e635e9525ba7b2fb8a1 --- /dev/null +++ b/src/chemistry_logger.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_CHEMISTRY_LOGGER_H +#define SWIFT_CHEMISTRY_LOGGER_H + +/* Config parameters. */ +#include "../config.h" + +/* Local includes */ +#include "align.h" +#include "logger.h" +#include "part_type.h" +#include "timeline.h" + +/* Import the right function */ +#if defined(CHEMISTRY_NONE) +#include "./chemistry/none/chemistry_logger.h" +#elif defined(CHEMISTRY_GEAR) +#include "./chemistry/GEAR/chemistry_logger.h" +#elif defined(CHEMISTRY_GEAR_DIFFUSION) +#error TODO +#elif defined(CHEMISTRY_QLA) +#error TODO +#elif defined(CHEMISTRY_EAGLE) +#error TODO +#else +#error "Invalid choice of chemistry function." +#endif + +#endif /* SWIFT_CHEMISTRY_LOGGER_H */ diff --git a/src/engine.c b/src/engine.c index 2a0492ee2c55abd0d572b9cce100dd3a84c20ac7..a448bdfa49df0ecf103d9d406b0922111154137d 100644 --- a/src/engine.c +++ b/src/engine.c @@ -71,6 +71,7 @@ #include "hydro.h" #include "line_of_sight.h" #include "logger.h" +#include "logger_io.h" #include "map.h" #include "memuse.h" #include "minmax.h" @@ -1824,7 +1825,7 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs, #endif scheduler_write_dependencies(&e->sched, e->verbose, e->step); - if (e->nodeID == 0) scheduler_write_task_level(&e->sched); + if (e->nodeID == 0) scheduler_write_task_level(&e->sched, e->step); /* Run the 0th time-step */ TIMER_TIC2; @@ -2242,6 +2243,11 @@ void engine_step(struct engine *e) { e->step % e->sched.frequency_dependency == 0) scheduler_write_dependencies(&e->sched, e->verbose, e->step); + /* Write the task levels */ + if (e->sched.frequency_task_levels != 0 && + e->step % e->sched.frequency_task_levels == 0) + scheduler_write_task_level(&e->sched, e->step); + /* Start all the tasks. */ TIMER_TIC; engine_launch(e, "tasks"); diff --git a/src/engine_config.c b/src/engine_config.c index 02257355a702c9a5c2982bba74ac6858d3db3ac2..99e7b32a978f7920713f8f67484190c70bed5e55 100644 --- a/src/engine_config.c +++ b/src/engine_config.c @@ -193,6 +193,13 @@ void engine_config(int restart, int fof, struct engine *e, error("Scheduler:dependency_graph_frequency should be >= 0"); } + /* Get the frequency of the task level dumping */ + e->sched.frequency_task_levels = parser_get_opt_param_int( + params, "Scheduler:task_level_output_frequency", 0); + if (e->sched.frequency_task_levels < 0) { + error("Scheduler:task_level_output_frequency should be >= 0"); + } + /* Deal with affinity. For now, just figure out the number of cores. */ #if defined(HAVE_SETAFFINITY) const int nr_cores = sysconf(_SC_NPROCESSORS_ONLN); diff --git a/src/feedback/GEAR/feedback.c b/src/feedback/GEAR/feedback.c index 6a8d15c4c4b6583bc7e14c6cf1868a11c33e8fa9..a895481c8cb6df8d7c122cc13279ecea2ac0b6a7 100644 --- a/src/feedback/GEAR/feedback.c +++ b/src/feedback/GEAR/feedback.c @@ -102,18 +102,18 @@ void feedback_update_part(struct part* restrict p, struct xpart* restrict xp, * @param time_base The time base. * @param time The current time (in double) */ -void compute_time(struct spart* sp, const struct engine* e, - const int with_cosmology, const struct cosmology* cosmo, - double* star_age_beg_of_step, double* dt_enrichment, - integertime_t* ti_begin_star, const integertime_t ti_current, - const double time_base, const double time) { +void compute_time(struct spart* sp, const int with_cosmology, + const struct cosmology* cosmo, double* star_age_beg_of_step, + double* dt_enrichment, integertime_t* ti_begin_star, + const integertime_t ti_current, const double time_base, + const double time) { const integertime_t ti_step = get_integer_timestep(sp->time_bin); *ti_begin_star = get_integer_time_begin(ti_current, sp->time_bin); /* Get particle time-step */ double dt_star; if (with_cosmology) { - dt_star = cosmology_get_delta_time(cosmology, *ti_begin_star, + dt_star = cosmology_get_delta_time(cosmo, *ti_begin_star, *ti_begin_star + ti_step); } else { dt_star = get_timestep(sp->time_bin, time_base); @@ -163,7 +163,7 @@ void feedback_will_do_feedback( double star_age_beg_step = 0; double dt_enrichment = 0; integertime_t ti_begin = 0; - compute_time(sp, e, with_cosmology, cosmo, &star_age_beg_step, &dt_enrichment, + compute_time(sp, with_cosmology, cosmo, &star_age_beg_step, &dt_enrichment, &ti_begin, ti_current, time_base, time); /* Zero the energy of supernovae */ diff --git a/src/gravity/MultiSoftening/gravity_logger.c b/src/gravity/MultiSoftening/gravity_logger.c new file mode 100644 index 0000000000000000000000000000000000000000..2622c747ee0d10b8b626acdfb85313e4ed49adfe --- /dev/null +++ b/src/gravity/MultiSoftening/gravity_logger.c @@ -0,0 +1,30 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +#include "../config.h" + +#ifdef WITH_LOGGER + +#include "gravity_logger.h" + +const char *gravity_logger_field_names[gravity_logger_field_count] = { + "Coordinates", "Velocities", "Accelerations", "Masses", "ParticleIDs", +}; + +#endif // WITH_LOGGER diff --git a/src/gravity/MultiSoftening/gravity_logger.h b/src/gravity/MultiSoftening/gravity_logger.h index f342e9ccc61a8310f3f39c2c5350518d1c6a5f93..0923e6127c52ec141f26c04649a33187cc47ecd5 100644 --- a/src/gravity/MultiSoftening/gravity_logger.h +++ b/src/gravity/MultiSoftening/gravity_logger.h @@ -38,9 +38,7 @@ enum gravity_logger_fields { }; /* Name of each possible mask. */ -static const char *gravity_logger_field_names[gravity_logger_field_count] = { - "Coordinates", "Velocities", "Accelerations", "Masses", "ParticleIDs", -}; +extern const char *gravity_logger_field_names[gravity_logger_field_count]; /** * @brief Initialize the logger. diff --git a/src/hydro/Gadget2/hydro_logger.c b/src/hydro/Gadget2/hydro_logger.c new file mode 100644 index 0000000000000000000000000000000000000000..236e9cd3b592824444b33c6fd3d0dcd5cda2d350 --- /dev/null +++ b/src/hydro/Gadget2/hydro_logger.c @@ -0,0 +1,30 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +#include "../config.h" + +#ifdef WITH_LOGGER + +#include "hydro_logger.h" + +const char *hydro_logger_field_names[hydro_logger_field_count] = { + "Coordinates", "Velocities", "Accelerations", "Masses", + "SmoothingLengths", "Entropies", "ParticleIDs", "Densities"}; + +#endif diff --git a/src/hydro/Gadget2/hydro_logger.h b/src/hydro/Gadget2/hydro_logger.h index 907259cb699e86f7646966349ccd1d0bbcd5cd2b..6632e21b6e660228c1f2647d3bc62167374f5f8e 100644 --- a/src/hydro/Gadget2/hydro_logger.h +++ b/src/hydro/Gadget2/hydro_logger.h @@ -41,9 +41,7 @@ enum hydro_logger_fields { }; /* Name of each possible mask. */ -static const char *hydro_logger_field_names[hydro_logger_field_count] = { - "Coordinates", "Velocities", "Accelerations", "Masses", - "SmoothingLengths", "Entropies", "ParticleIDs", "Densities"}; +extern const char *hydro_logger_field_names[hydro_logger_field_count]; /** * @brief Initialize the logger. diff --git a/src/hydro/SPHENIX/hydro_logger.c b/src/hydro/SPHENIX/hydro_logger.c new file mode 100644 index 0000000000000000000000000000000000000000..682585a469afe08c4cc53cf291a4418efc51f4cf --- /dev/null +++ b/src/hydro/SPHENIX/hydro_logger.c @@ -0,0 +1,38 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +#include "../config.h" + +#ifdef WITH_LOGGER + +/* Include the particles */ +#include "align.h" +#include "hydro_part.h" + +/* Include the header */ +#include "hydro_logger.h" + +const char *hydro_logger_field_names[hydro_logger_field_count] = { + "Coordinates", "Velocities", "Accelerations", + "Masses", "SmoothingLengths", "InternalEnergies", + "ParticleIDs", "Densities", "Entropies", + "Pressures", "ViscosityDiffusion", "VelocityDivergences", +}; + +#endif // WITH_LOGGER diff --git a/src/hydro/SPHENIX/hydro_logger.h b/src/hydro/SPHENIX/hydro_logger.h index 44f9274e6a6a352aea789d3eaab2f24fc86825b5..d31493d16286d1b8e20782dca491590fcee0948a 100644 --- a/src/hydro/SPHENIX/hydro_logger.h +++ b/src/hydro/SPHENIX/hydro_logger.h @@ -19,6 +19,7 @@ #ifndef SWIFT_SPHENIX_HYDRO_LOGGER_H #define SWIFT_SPHENIX_HYDRO_LOGGER_H +/* Other Includes */ #include "hydro.h" #include "logger_io.h" @@ -45,12 +46,7 @@ enum hydro_logger_fields { }; /* Name of each possible mask. */ -static const char *hydro_logger_field_names[hydro_logger_field_count] = { - "Coordinates", "Velocities", "Accelerations", - "Masses", "SmoothingLengths", "InternalEnergies", - "ParticleIDs", "Densities", "Entropies", - "Pressures", "ViscosityDiffusion", "VelocityDivergences", -}; +extern const char *hydro_logger_field_names[hydro_logger_field_count]; /** * @brief Initialize the logger. diff --git a/src/logger.c b/src/logger.c index f9c0b407ac3e5d521f092bb213b17ddbfc74b3d1..a7cef1c47ef47b4083afbdf8b6bc59f5cc6c9cf1 100644 --- a/src/logger.c +++ b/src/logger.c @@ -40,11 +40,13 @@ /* Local headers. */ #include "active.h" #include "atomic.h" +#include "chemistry_logger.h" #include "dump.h" #include "engine.h" #include "error.h" #include "gravity_logger.h" #include "hydro_logger.h" +#include "star_formation_particle_logger.h" #include "stars_logger.h" #include "units.h" @@ -216,6 +218,8 @@ void logger_copy_part_fields(const struct logger_writer *log, /* Write the hydro fields */ buff = hydro_logger_write_particle(log->mask_data_pointers.hydro, p, xp, &mask, buff); + buff = chemistry_logger_write_particle(log->mask_data_pointers.chemistry_part, + p, xp, &mask, buff); #ifdef SWIFT_DEBUG_CHECKS if (mask) { @@ -282,6 +286,9 @@ void logger_log_parts(struct logger_writer *log, const struct part *p, size_t size = 0; hydro_logger_compute_size_and_mask(log->mask_data_pointers.hydro, &p[i], &xp[i], log_all_fields, &size, &mask); + chemistry_logger_compute_size_and_mask_part( + log->mask_data_pointers.chemistry_part, &p[i], &xp[i], log_all_fields, + &size, &mask); if (flag != 0) { size += size_special_flag; } @@ -300,6 +307,9 @@ void logger_log_parts(struct logger_writer *log, const struct part *p, unsigned int mask = 0; hydro_logger_compute_size_and_mask(log->mask_data_pointers.hydro, &p[i], &xp[i], log_all_fields, &size, &mask); + chemistry_logger_compute_size_and_mask_part( + log->mask_data_pointers.chemistry_part, &p[i], &xp[i], log_all_fields, + &size, &mask); size += logger_header_bytes; /* Add the special flag. */ @@ -373,6 +383,10 @@ void logger_copy_spart_fields(const struct logger_writer *log, /* Write the stellar fields */ buff = stars_logger_write_particle(log->mask_data_pointers.stars, sp, &mask, buff); + buff = chemistry_logger_write_sparticle( + log->mask_data_pointers.chemistry_spart, sp, &mask, buff); + buff = star_formation_logger_write_sparticle( + log->mask_data_pointers.star_formation, sp, &mask, buff); #ifdef SWIFT_DEBUG_CHECKS if (mask) { error("Requested logging of values not present in sparts. %u", mask); @@ -432,6 +446,12 @@ void logger_log_sparts(struct logger_writer *log, struct spart *sp, int count, size_t size = 0; stars_logger_compute_size_and_mask(log->mask_data_pointers.stars, &sp[i], log_all_fields, &size, &mask); + chemistry_logger_compute_size_and_mask_spart( + log->mask_data_pointers.chemistry_spart, &sp[i], log_all_fields, + &size, &mask); + star_formation_logger_compute_size_and_mask( + log->mask_data_pointers.star_formation, &sp[i], log_all_fields, &size, + &mask); if (flag != 0) { size += size_special_flag; } @@ -449,6 +469,12 @@ void logger_log_sparts(struct logger_writer *log, struct spart *sp, int count, unsigned int mask = 0; stars_logger_compute_size_and_mask(log->mask_data_pointers.stars, &sp[i], log_all_fields, &size, &mask); + chemistry_logger_compute_size_and_mask_spart( + log->mask_data_pointers.chemistry_spart, &sp[i], log_all_fields, &size, + &mask); + star_formation_logger_compute_size_and_mask( + log->mask_data_pointers.star_formation, &sp[i], log_all_fields, &size, + &mask); size += logger_header_bytes; /* Add the special flag. */ @@ -730,7 +756,10 @@ void logger_get_dump_name(struct logger_writer *log, char *filename) { void logger_init_masks(struct logger_writer *log, const struct engine *e) { /* Set the pointers to 0 */ log->mask_data_pointers.hydro = NULL; + log->mask_data_pointers.chemistry_part = NULL; + log->mask_data_pointers.chemistry_spart = NULL; log->mask_data_pointers.stars = NULL; + log->mask_data_pointers.star_formation = NULL; log->mask_data_pointers.gravity = NULL; struct mask_data list[100]; @@ -754,7 +783,7 @@ void logger_init_masks(struct logger_writer *log, const struct engine *e) { list[num_fields].type = mask_type_timestep; // flag it as timestamp num_fields += 1; - // TODO add chemistry, cooling, ... + xpart + spart + // TODO add cooling, ... + xpart + spart /* Get all the fields that need to be written for the hydro. */ struct mask_data *tmp = &list[num_fields]; @@ -770,6 +799,20 @@ void logger_init_masks(struct logger_writer *log, const struct engine *e) { } num_fields += tmp_num_fields; + /* Get all the fields that need to be written for the chemistry (part). */ + tmp = &list[num_fields]; + + /* Set the mask_data_pointers */ + log->mask_data_pointers.chemistry_part = tmp; + + /* Set the masks */ + tmp_num_fields = chemistry_logger_writer_populate_mask_data_part(tmp); + /* Set the particle type */ + for (int i = 0; i < tmp_num_fields; i++) { + tmp[i].type = mask_type_gas; + } + num_fields += tmp_num_fields; + /* Get all the fields that need to be written for the stars. */ tmp = &list[num_fields]; @@ -784,6 +827,34 @@ void logger_init_masks(struct logger_writer *log, const struct engine *e) { } num_fields += tmp_num_fields; + /* Get all the fields that need to be written for the chemistry (spart). */ + tmp = &list[num_fields]; + + /* Set the mask_data_pointers */ + log->mask_data_pointers.chemistry_spart = tmp; + + /* Set the masks */ + tmp_num_fields = chemistry_logger_writer_populate_mask_data_spart(tmp); + /* Set the particle type */ + for (int i = 0; i < tmp_num_fields; i++) { + tmp[i].type = mask_type_stars; + } + num_fields += tmp_num_fields; + + /* Get all the fields that need to be written for the star_formation. */ + tmp = &list[num_fields]; + + /* Set the mask_data_pointers */ + log->mask_data_pointers.star_formation = tmp; + + /* Set the masks */ + tmp_num_fields = star_formation_logger_writer_populate_mask_data(tmp); + /* Set the particle type */ + for (int i = 0; i < tmp_num_fields; i++) { + tmp[i].type = mask_type_stars; + } + num_fields += tmp_num_fields; + /* Get all the fields that need to be written for the gravity. */ tmp = &list[num_fields]; @@ -852,10 +923,23 @@ void logger_init_masks(struct logger_writer *log, const struct engine *e) { log->mask_data_pointers.hydro = log->logger_mask_data + (log->mask_data_pointers.hydro - list); } + if (log->mask_data_pointers.chemistry_part != NULL) { + log->mask_data_pointers.chemistry_part = + log->logger_mask_data + (log->mask_data_pointers.chemistry_part - list); + } if (log->mask_data_pointers.stars != NULL) { log->mask_data_pointers.stars = log->logger_mask_data + (log->mask_data_pointers.stars - list); } + if (log->mask_data_pointers.chemistry_spart != NULL) { + log->mask_data_pointers.chemistry_spart = + log->logger_mask_data + + (log->mask_data_pointers.chemistry_spart - list); + } + if (log->mask_data_pointers.star_formation != NULL) { + log->mask_data_pointers.star_formation = + log->logger_mask_data + (log->mask_data_pointers.star_formation - list); + } if (log->mask_data_pointers.gravity != NULL) { log->mask_data_pointers.gravity = log->logger_mask_data + (log->mask_data_pointers.gravity - list); @@ -866,6 +950,9 @@ void logger_init_masks(struct logger_writer *log, const struct engine *e) { for (int i = 0; i < hydro_logger_field_count; i++) { log->max_size_record_part += log->mask_data_pointers.hydro[i].size; } + for (int i = 0; i < chemistry_logger_field_part_count; i++) { + log->max_size_record_part += log->mask_data_pointers.chemistry_part[i].size; + } log->max_size_record_gpart = 0; for (int i = 0; i < gravity_logger_field_count; i++) { @@ -876,6 +963,14 @@ void logger_init_masks(struct logger_writer *log, const struct engine *e) { for (int i = 0; i < stars_logger_field_count; i++) { log->max_size_record_spart += log->mask_data_pointers.stars[i].size; } + for (int i = 0; i < chemistry_logger_field_spart_count; i++) { + log->max_size_record_spart += + log->mask_data_pointers.chemistry_spart[i].size; + } + for (int i = 0; i < star_formation_logger_field_count; i++) { + log->max_size_record_spart += + log->mask_data_pointers.star_formation[i].size; + } /* Set the counter */ log->logger_count_mask = num_fields; @@ -1275,12 +1370,21 @@ void logger_struct_restore(struct logger_writer *log, FILE *stream) { log->mask_data_pointers.hydro = log->logger_mask_data + (log->mask_data_pointers.hydro - old_logger_mask_data); + log->mask_data_pointers.chemistry_part = + log->logger_mask_data + + (log->mask_data_pointers.chemistry_part - old_logger_mask_data); log->mask_data_pointers.gravity = log->logger_mask_data + (log->mask_data_pointers.gravity - old_logger_mask_data); log->mask_data_pointers.stars = log->logger_mask_data + (log->mask_data_pointers.stars - old_logger_mask_data); + log->mask_data_pointers.chemistry_spart = + log->logger_mask_data + + (log->mask_data_pointers.chemistry_spart - old_logger_mask_data); + log->mask_data_pointers.star_formation = + log->logger_mask_data + + (log->mask_data_pointers.star_formation - old_logger_mask_data); /* Restart the dump file. */ char logger_name_file[PARSER_MAX_LINE_SIZE]; diff --git a/src/logger.h b/src/logger.h index 646fc901842176882761292d88fa000a01553fad..dd0b988b9c1dee3661ec13d1d5157eced39a76f7 100644 --- a/src/logger.h +++ b/src/logger.h @@ -39,8 +39,8 @@ struct gpart; struct part; struct engine; -#define logger_major_version 0 -#define logger_minor_version 5 +#define logger_major_version 1 +#define logger_minor_version 0 /* Size of the strings. */ #define logger_string_length 200 @@ -151,11 +151,20 @@ struct logger_writer { /* pointer for the hydro */ struct mask_data *hydro; + /* pointer for the chemistry */ + struct mask_data *chemistry_part; + + /* pointer for the chemistry */ + struct mask_data *chemistry_spart; + /* pointer for the gravity */ struct mask_data *gravity; /* pointer for the stars */ struct mask_data *stars; + + /* pointer for the star formation */ + struct mask_data *star_formation; } mask_data_pointers; /* Number of elements in logger_mask_data. */ diff --git a/src/logger_history.c b/src/logger_history.c index f75686e748e81f1783b87dc7173b11396a7787d7..f0034f8dd1cae0a3bcbed61f7334661354b56d69 100644 --- a/src/logger_history.c +++ b/src/logger_history.c @@ -41,7 +41,7 @@ void logger_history_init(struct logger_history *hist) { /* Set the counters to their initial value */ hist->size = 0; hist->capacity = LOGGER_HISTORY_INIT_SIZE; - lock_init(hist->lock); + lock_init(&hist->lock); hist->data = (struct logger_index_data *)swift_malloc( "logger_history", @@ -74,7 +74,7 @@ void logger_history_free(struct logger_history *hist) { /* Set the counters to 0 */ hist->size = 0; hist->capacity = 0; - lock_destroy(hist->lock); + if (lock_destroy(&hist->lock) != 0) error("Error destroying lock"); /* Free the memory */ if (hist->data != NULL) { @@ -102,7 +102,7 @@ void logger_history_log(struct logger_history *hist, const long long id, const struct logger_index_data data = {id, last_offset}; /* Lock the history */ - lock_lock(hist->lock); + lock_lock(&hist->lock); /* Check if enough space is left */ if (hist->size == hist->capacity) { @@ -130,7 +130,8 @@ void logger_history_log(struct logger_history *hist, const long long id, hist->size += 1; /* Unlock the history. */ - lock_unlock(hist->lock); + if (lock_unlock(&hist->lock) != 0) + error("Impossible to unlock logger history."); } /** diff --git a/src/logger_history.h b/src/logger_history.h index 05df5044c89cd081137dfba71a094a58b2aa778f..43ab36583975b6828cc496542a7b242aa9fcafea 100644 --- a/src/logger_history.h +++ b/src/logger_history.h @@ -26,6 +26,7 @@ /* Local include */ #include "error.h" +#include "lock.h" #include "part_type.h" #if defined(WITH_LOGGER) diff --git a/src/scheduler.c b/src/scheduler.c index bb0c43bb3cb173dc91b8d238ded879787bf3d0a1..f107c653fc1beb7ae6710c5c3f4d9a6c3824b4a1 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -369,7 +369,7 @@ void task_dependency_sum(void *in_p, void *out_p, int *len, /** * @brief Write a csv file with the task dependencies. * - * Run plot_task_dependencies.sh for an example of how to use it + * Run plot_task_dependencies.py for an example of how to use it * to generate the figure. * * @param s The #scheduler we are working in. @@ -2489,9 +2489,16 @@ void scheduler_free_tasks(struct scheduler *s) { } /** - * @brief write down each task level + * @brief write down the levels and the number of tasks at that level. + * + * Run plot_task_level.py for an example of how to use it + * to generate the figure. + * + * @param s The #scheduler we are working in. + * @param step The current step number. */ -void scheduler_write_task_level(const struct scheduler *s) { +void scheduler_write_task_level(const struct scheduler *s, int step) { + /* init */ const int max_depth = 30; const struct task *tasks = s->tasks; @@ -2519,8 +2526,18 @@ void scheduler_write_task_level(const struct scheduler *s) { } } + /* Generate filename */ + char filename[200] = "task_level_\0"; +#ifdef WITH_MPI + char rankstr[6]; + sprintf(rankstr, "%04d_", s->nodeID); + strcat(filename, rankstr); +#endif + char stepstr[100]; + sprintf(stepstr, "%d.txt", step); + strcat(filename, stepstr); + /* Open file */ - char filename[200] = "task_level.txt"; FILE *f = fopen(filename, "w"); if (f == NULL) error("Error opening task level file."); diff --git a/src/scheduler.h b/src/scheduler.h index 13c7395d26c85bfe166a678f56f7fd6370f4d4ca..d7fc9ad38a6c68afa8b72097e73bd207831683e1 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -114,6 +114,9 @@ struct scheduler { /* Frequency of the dependency graph dumping. */ int frequency_dependency; + + /* Frequency of the task levels dumping. */ + int frequency_task_levels; }; /* Inlined functions (for speed). */ @@ -207,7 +210,7 @@ void scheduler_print_tasks(const struct scheduler *s, const char *fileName); void scheduler_clean(struct scheduler *s); void scheduler_free_tasks(struct scheduler *s); void scheduler_write_dependencies(struct scheduler *s, int verbose, int step); -void scheduler_write_task_level(const struct scheduler *s); +void scheduler_write_task_level(const struct scheduler *s, int step); void scheduler_dump_queues(struct engine *e); void scheduler_report_task_times(const struct scheduler *s, const int nr_threads); diff --git a/src/space.c b/src/space.c index 1b60d924742df427f57a9df8350deae953b41e54..67c3494dd892f864910e7d7bca0eeb1c18a45018 100644 --- a/src/space.c +++ b/src/space.c @@ -1071,6 +1071,17 @@ void space_init(struct space *s, struct swift_params *params, s->sum_bpart_vel_norm = 0.f; s->nr_queues = 1; /* Temporary value until engine construction */ + /* do a quick check that the box size has valid values */ +#if defined HYDRO_DIMENSION_1D + if (dim[0] <= 0.) error("Invalid box size: [%f]", dim[0]); +#elif defined HYDRO_DIMENSION_2D + if (dim[0] <= 0. || dim[1] <= 0.) + error("Invalid box size: [%f, %f]", dim[0], dim[1]); +#else + if (dim[0] <= 0. || dim[1] <= 0. || dim[2] <= 0.) + error("Invalid box size: [%f, %f, %f]", dim[0], dim[1], dim[2]); +#endif + /* Initiate some basic randomness */ srand(42); diff --git a/src/star_formation/GEAR/star_formation_particle_logger.c b/src/star_formation/GEAR/star_formation_particle_logger.c new file mode 100644 index 0000000000000000000000000000000000000000..506d7004b7b0bf9ca9582712c3ee38ff02cc76a3 --- /dev/null +++ b/src/star_formation/GEAR/star_formation_particle_logger.c @@ -0,0 +1,32 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +#include "../config.h" + +#ifdef WITH_LOGGER + +#include "star_formation_particle_logger.h" + +/* Name of each possible mask. */ +const char + *star_formation_logger_field_names[star_formation_logger_field_count] = { + "StarFormation", +}; + +#endif // WITH_LOGGER diff --git a/src/star_formation/GEAR/star_formation_particle_logger.h b/src/star_formation/GEAR/star_formation_particle_logger.h new file mode 100644 index 0000000000000000000000000000000000000000..938d6cbbdffa7398f3863251944a14fc186669b1 --- /dev/null +++ b/src/star_formation/GEAR/star_formation_particle_logger.h @@ -0,0 +1,118 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_STAR_FORMATION_GEAR_STAR_FORMATION_PARTICLE_LOGGER_H +#define SWIFT_STAR_FORMATION_GEAR_STAR_FORMATION_PARTICLE_LOGGER_H + +#include "logger_io.h" + +#ifdef WITH_LOGGER + +/* + * List of all possible mask. + * Outside the module, only star_formation_logger_field_count is used. + */ +enum star_formation_logger_fields_spart { + star_formation_logger_field_all = 0, + star_formation_logger_field_count, +}; + +/* Name of each possible mask. */ +extern const char + *star_formation_logger_field_names[star_formation_logger_field_count]; + +/** + * @brief Initialize the logger for the #spart. + * + * WARNING: The order should be the same in all the functions and + * #star_formation_logger_fields_spart! + * + * @param mask_data Data for each type of mask. + * + * @return Number of masks used. + */ +INLINE static int star_formation_logger_writer_populate_mask_data( + struct mask_data *mask_data) { + /* We store the birth density, mass and progenitor id. */ + mask_data[star_formation_logger_field_all] = logger_create_mask_entry( + star_formation_logger_field_names[star_formation_logger_field_all], + 2 * sizeof(float) + sizeof(long long)); + + return star_formation_logger_field_count; +} + +/** + * @brief Generates the mask and compute the size of the record for the #spart. + * + * WARNING: The order should be the same in all the functions and + * #star_formation_logger_fields_spart! + * + * @param masks The list of masks (same order than in + * #star_formation_logger_writer_populate_mask_data_spart). + * @param spart The #spart that will be written. + * @param write_all Are we forcing to write all the fields? + * + * @param buffer_size (out) The requested size for the buffer. + * @param mask (out) The mask that will be written. + */ +INLINE static void star_formation_logger_compute_size_and_mask( + const struct mask_data *masks, const struct spart *spart, + const int write_all, size_t *buffer_size, unsigned int *mask) { + /* Add the star formation. */ + *mask |= logger_add_field_to_mask(masks[star_formation_logger_field_all], + buffer_size); +} + +/** + * @brief Write a #spart to the logger. + * + * WARNING: The order should be the same in all the functions and + * #hydro_logger_fields_spart! + * + * @param masks The list of masks (same order than in + * #star_formation_logger_writer_populate_mask_data_spart). + * @param sp The #spart to write. + * @param mask The mask to use for this record. + * @param buff The buffer where to write the particle. + * + * @return The buffer after the data. + */ +INLINE static char *star_formation_logger_write_sparticle( + const struct mask_data *mask_data, const struct spart *sp, + unsigned int *mask, char *buff) { + /* Write the star formation. */ + if (logger_should_write_field(mask_data[star_formation_logger_field_all], + mask)) { + + /* Write the birth density */ + memcpy(buff, &sp->sf_data.birth_density, sizeof(float)); + buff += sizeof(float); + + /* Write the birth mass */ + memcpy(buff, &sp->sf_data.birth_mass, sizeof(float)); + buff += sizeof(float); + + /* Write the progenitor id */ + memcpy(buff, &sp->sf_data.progenitor_id, sizeof(long long)); + buff += sizeof(long long); + } + return buff; +} + +#endif // WITH_LOGGER +#endif // SWIFT_STAR_FORMATION_NONE_STAR_FORMATION_PARTICLE_LOGGER_H diff --git a/src/star_formation/none/star_formation_particle_logger.c b/src/star_formation/none/star_formation_particle_logger.c new file mode 100644 index 0000000000000000000000000000000000000000..a48f7d9e9a0989c0f6a92b1bd6ae42c45a2192e8 --- /dev/null +++ b/src/star_formation/none/star_formation_particle_logger.c @@ -0,0 +1,29 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +#include "../config.h" + +#ifdef WITH_LOGGER + +#include "star_formation_particle_logger.h" + +const char + *star_formation_logger_field_names[star_formation_logger_field_count] = {}; + +#endif // WITH_LOGGER diff --git a/src/star_formation/none/star_formation_particle_logger.h b/src/star_formation/none/star_formation_particle_logger.h new file mode 100644 index 0000000000000000000000000000000000000000..b69df66d3d33a4dbf290cce1fd14af841ecbd2ed --- /dev/null +++ b/src/star_formation/none/star_formation_particle_logger.h @@ -0,0 +1,92 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_STAR_FORMATION_NONE_STAR_FORMATION_PARTICLE_LOGGER_H +#define SWIFT_STAR_FORMATION_NONE_STAR_FORMATION_PARTICLE_LOGGER_H + +#include "logger_io.h" + +#ifdef WITH_LOGGER + +/* + * List of all possible mask. + * Outside the module, only star_formation_logger_field_count is used. + */ +enum star_formation_logger_fields_spart { + star_formation_logger_field_count = 0, +}; + +/* Name of each possible mask. */ +extern const char + *star_formation_logger_field_names[star_formation_logger_field_count]; + +/** + * @brief Initialize the logger for the #spart. + * + * WARNING: The order should be the same in all the functions and + * #star_formation_logger_fields_spart! + * + * @param mask_data Data for each type of mask. + * + * @return Number of masks used. + */ +INLINE static int star_formation_logger_writer_populate_mask_data( + struct mask_data *mask_data) { + return star_formation_logger_field_count; +} + +/** + * @brief Generates the mask and compute the size of the record for the #spart. + * + * WARNING: The order should be the same in all the functions and + * #star_formation_logger_fields_spart! + * + * @param masks The list of masks (same order than in + * #star_formation_logger_writer_populate_mask_data_spart). + * @param spart The #spart that will be written. + * @param write_all Are we forcing to write all the fields? + * + * @param buffer_size (out) The requested size for the buffer. + * @param mask (out) The mask that will be written. + */ +INLINE static void star_formation_logger_compute_size_and_mask( + const struct mask_data *masks, const struct spart *spart, + const int write_all, size_t *buffer_size, unsigned int *mask) {} + +/** + * @brief Write a #spart to the logger. + * + * WARNING: The order should be the same in all the functions and + * #hydro_logger_fields_spart! + * + * @param masks The list of masks (same order than in + * #star_formation_logger_writer_populate_mask_data_spart). + * @param sp The #spart to write. + * @param mask The mask to use for this record. + * @param buff The buffer where to write the particle. + * + * @return The buffer after the data. + */ +INLINE static char *star_formation_logger_write_sparticle( + const struct mask_data *mask_data, const struct spart *sp, + unsigned int *mask, char *buff) { + return buff; +} + +#endif // WITH_LOGGER +#endif // SWIFT_STAR_FORMATION_NONE_STAR_FORMATION_PARTICLE_LOGGER_H diff --git a/src/star_formation_particle_logger.h b/src/star_formation_particle_logger.h new file mode 100644 index 0000000000000000000000000000000000000000..a3ced362d0c1e3700ad98ba8afc93c06428931f2 --- /dev/null +++ b/src/star_formation_particle_logger.h @@ -0,0 +1,44 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_STAR_FORMATION_PARTICLE_LOGGER_H +#define SWIFT_STAR_FORMATION_PARTICLE_LOGGER_H + +/* Config parameters. */ +#include "../config.h" + +/* Local includes */ +#include "align.h" +#include "logger.h" +#include "part_type.h" +#include "timeline.h" + +/* Import the right function */ +#if defined(STAR_FORMATION_NONE) +#include "./star_formation/none/star_formation_particle_logger.h" +#elif defined(STAR_FORMATION_QLA) +#error TODO +#elif defined(STAR_FORMATION_EAGLE) +#error TODO +#elif defined(STAR_FORMATION_GEAR) +#include "./star_formation/GEAR/star_formation_particle_logger.h" +#else +#error "Invalid choice of star formation law" +#endif + +#endif /* SWIFT_STAR_FORMATION_PARTICLE_LOGGER_H */ diff --git a/src/stars/Default/stars_logger.c b/src/stars/Default/stars_logger.c new file mode 100644 index 0000000000000000000000000000000000000000..f84360e740be2697e1861f26823f7b1ee36d63c4 --- /dev/null +++ b/src/stars/Default/stars_logger.c @@ -0,0 +1,31 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +#include "../config.h" + +#ifdef WITH_LOGGER + +#include "stars_logger.h" + +const char *stars_logger_field_names[stars_logger_field_count] = { + "Coordinates", "Velocities", "Accelerations", + "Masses", "SmoothingLengths", "ParticleIDs", +}; + +#endif // WITH_LOGGER diff --git a/src/stars/Default/stars_logger.h b/src/stars/Default/stars_logger.h index 2637cef126fa2ce4b8980b7f22265c80c463f7be..ebc7c7d13e9dd6de1999fffff75fa5b53dcd7bd9 100644 --- a/src/stars/Default/stars_logger.h +++ b/src/stars/Default/stars_logger.h @@ -38,10 +38,7 @@ enum stars_logger_fields { }; /* Name of each possible mask. */ -static const char *stars_logger_field_names[stars_logger_field_count] = { - "Coordinates", "Velocities", "Accelerations", - "Masses", "SmoothingLengths", "ParticleIDs", -}; +extern const char *stars_logger_field_names[stars_logger_field_count]; /** * @brief Initialize the logger. diff --git a/src/stars/GEAR/stars_logger.c b/src/stars/GEAR/stars_logger.c new file mode 100644 index 0000000000000000000000000000000000000000..e12875bd3582f1fbe915355f039acbd8b4250448 --- /dev/null +++ b/src/stars/GEAR/stars_logger.c @@ -0,0 +1,31 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +#include "../config.h" + +#ifdef WITH_LOGGER + +#include "stars_logger.h" + +const char *stars_logger_field_names[stars_logger_field_count] = { + "Coordinates", "Velocities", "Accelerations", "Masses", + "SmoothingLengths", "ParticleIDs", "BirthScaleFactors", +}; + +#endif // WITH_LOGGER diff --git a/src/stars/GEAR/stars_logger.h b/src/stars/GEAR/stars_logger.h new file mode 100644 index 0000000000000000000000000000000000000000..365505c50c9278a1efec3f248231f97c14d971d5 --- /dev/null +++ b/src/stars/GEAR/stars_logger.h @@ -0,0 +1,203 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_DEFAULT_STARS_LOGGER_H +#define SWIFT_DEFAULT_STARS_LOGGER_H + +#ifdef WITH_LOGGER + +#include "logger_io.h" + +/* + * List of all possible mask. + * Outside the module, only stars_logger_field_count is used. + */ +enum stars_logger_fields { + stars_logger_field_coordinates = 0, + stars_logger_field_velocities, + stars_logger_field_accelerations, + stars_logger_field_masses, + stars_logger_field_smoothing_lengths, + stars_logger_field_particle_ids, + stars_logger_field_birth_scale_factors, + stars_logger_field_count, +}; + +/* Name of each possible mask. */ +extern const char *stars_logger_field_names[stars_logger_field_count]; + +/** + * @brief Initialize the logger. + * + * WARNING: The order should be the same in all the functions and + * #stars_logger_fields! + * + * @param mask_data Data for each type of mask. + * + * @return Number of masks used. + */ +INLINE static int stars_logger_writer_populate_mask_data( + struct mask_data *mask_data) { + mask_data[stars_logger_field_coordinates] = logger_create_mask_entry( + stars_logger_field_names[stars_logger_field_coordinates], + 3 * sizeof(double)); + + mask_data[stars_logger_field_velocities] = logger_create_mask_entry( + stars_logger_field_names[stars_logger_field_velocities], + 3 * sizeof(float)); + + mask_data[stars_logger_field_accelerations] = logger_create_mask_entry( + stars_logger_field_names[stars_logger_field_accelerations], + 3 * sizeof(float)); + + mask_data[stars_logger_field_masses] = logger_create_mask_entry( + stars_logger_field_names[stars_logger_field_masses], sizeof(float)); + + mask_data[stars_logger_field_smoothing_lengths] = logger_create_mask_entry( + stars_logger_field_names[stars_logger_field_smoothing_lengths], + sizeof(float)); + + mask_data[stars_logger_field_particle_ids] = logger_create_mask_entry( + stars_logger_field_names[stars_logger_field_particle_ids], + sizeof(long long)); + + mask_data[stars_logger_field_birth_scale_factors] = logger_create_mask_entry( + stars_logger_field_names[stars_logger_field_birth_scale_factors], + sizeof(float)); + + return stars_logger_field_count; +} + +/** + * @brief Generates the mask and compute the size of the record. + * + * WARNING: The order should be the same in all the functions and + * #stars_logger_fields! + * + * @param masks The list of masks (same order than in #stars_logger_init). + * @param part The #spart that will be written. + * @param write_all Are we forcing to write all the fields? + * + * @param buffer_size (out) The requested size for the buffer. + * @param mask (out) The mask that will be written. + */ +INLINE static void stars_logger_compute_size_and_mask( + const struct mask_data *masks, const struct spart *part, + const int write_all, size_t *buffer_size, unsigned int *mask) { + + /* Here you can decide your own writing logic */ + + /* Add the coordinates. */ + *mask |= logger_add_field_to_mask(masks[stars_logger_field_coordinates], + buffer_size); + + /* Add the velocities. */ + *mask |= logger_add_field_to_mask(masks[stars_logger_field_velocities], + buffer_size); + + /* Add the accelerations. */ + *mask |= logger_add_field_to_mask(masks[stars_logger_field_accelerations], + buffer_size); + + /* Add the masses. */ + *mask |= + logger_add_field_to_mask(masks[stars_logger_field_masses], buffer_size); + + /* Add the smoothing lengths. */ + *mask |= logger_add_field_to_mask(masks[stars_logger_field_smoothing_lengths], + buffer_size); + + /* Add the ID. */ + *mask |= logger_add_field_to_mask(masks[stars_logger_field_particle_ids], + buffer_size); + + /* Add the birth scale factor. */ + *mask |= logger_add_field_to_mask( + masks[stars_logger_field_birth_scale_factors], buffer_size); +} + +/** + * @brief Write a particle to the logger. + * + * WARNING: The order should be the same in all the functions and + * #stars_logger_fields! + * + * @param masks The list of masks (same order than in #stars_logger_init). + * @param p The #spart to write. + * @param mask The mask to use for this record. + * @param buff The buffer where to write the particle. + * + * @return The buffer after the data. + */ +INLINE static char *stars_logger_write_particle( + const struct mask_data *mask_data, const struct spart *p, + unsigned int *mask, char *buff) { + + /* Write the coordinate. */ + if (logger_should_write_field(mask_data[stars_logger_field_coordinates], + mask)) { + memcpy(buff, p->x, 3 * sizeof(double)); + buff += 3 * sizeof(double); + } + + /* Write the velocity. */ + if (logger_should_write_field(mask_data[stars_logger_field_velocities], + mask)) { + memcpy(buff, p->v, 3 * sizeof(float)); + buff += 3 * sizeof(float); + } + + /* Write the acceleration. */ + if (logger_should_write_field(mask_data[stars_logger_field_accelerations], + mask)) { + memcpy(buff, p->gpart->a_grav, 3 * sizeof(float)); + buff += 3 * sizeof(float); + } + + /* Write the mass. */ + if (logger_should_write_field(mask_data[stars_logger_field_masses], mask)) { + memcpy(buff, &p->mass, sizeof(float)); + buff += sizeof(float); + } + + /* Write the smoothing length. */ + if (logger_should_write_field(mask_data[stars_logger_field_smoothing_lengths], + mask)) { + memcpy(buff, &p->h, sizeof(float)); + buff += sizeof(float); + } + + /* Write the Id. */ + if (logger_should_write_field(mask_data[stars_logger_field_particle_ids], + mask)) { + memcpy(buff, &p->id, sizeof(long long)); + buff += sizeof(long long); + } + + /* Write the birth scale factor. */ + if (logger_should_write_field( + mask_data[stars_logger_field_birth_scale_factors], mask)) { + memcpy(buff, &p->birth_scale_factor, sizeof(float)); + buff += sizeof(float); + } + + return buff; +} + +#endif // WITH_LOGGER +#endif // SWIFT_DEFAULT_STARS_LOGGER_H diff --git a/src/stars/GEAR/stars_part.h b/src/stars/GEAR/stars_part.h index 5f5019d643df9d849aa1d50c627b236412a50fcc..ca3e56419c08a622bb97ff0ee06183772bd2bb41 100644 --- a/src/stars/GEAR/stars_part.h +++ b/src/stars/GEAR/stars_part.h @@ -96,6 +96,11 @@ struct spart { /*! Splitting structure */ struct particle_splitting_data split_data; +#ifdef WITH_LOGGER + /* Additional data for the particle logger */ + struct logger_part_data logger_data; +#endif + /*! Radiative Transfer data */ struct rt_spart_data rt_data; diff --git a/src/stars_logger.h b/src/stars_logger.h index 972c648ff95df5f811514465e97890c3c728bd10..a3d1dbb30962dcec9ad3ece094ea8e0289b5ec05 100644 --- a/src/stars_logger.h +++ b/src/stars_logger.h @@ -37,7 +37,7 @@ #elif defined(STARS_EAGLE) #error TODO #elif defined(STARS_GEAR) -#error TODO +#include "./stars/GEAR/stars_logger.h" #else #error "Invalid choice of star model" #endif diff --git a/tools/plot_task_level.py b/tools/plot_task_level.py index 2fbe55c025db7f400aa009e488412475c9259630..668baaf895b66c73fb52545997f55596190f9632 100755 --- a/tools/plot_task_level.py +++ b/tools/plot_task_level.py @@ -3,7 +3,9 @@ description = """ Plot the number of tasks for each depth level and each type of task. Usage: - ./plot_task_level.py task_level.txt + ./plot_task_level.py task_level_0.txt + or + ./plot_task_level.py task_level_*_0.txt """ @@ -61,43 +63,51 @@ def parse_args(): parser.add_argument( "file", type=str, - help="Required file name of .csv file(s) of the task levels " + nargs="+", + help="Required file name(s) of .txt file(s) of the task levels " "generated by swift.", ) args = parser.parse_args() - filename = args.file - print(filename) + files = args.file - if not path.exists(filename): - raise FileNotFoundError("File not found:'" + filename + "'") + for f in files: + if not path.exists(f): + raise FileNotFoundError("File not found:'" + f + "'") - return args, filename + return args, files -def read_data(filename): +def read_data(files): """ - Reads in data from the csv file. + Reads in data from the .txt file. Parameters ---------- - filename: str - filename to be read from + files: list + list of filenames to be read from Returns ------- - data: pandas dataset - dataset containing read in data + data: pandas dataframe + dataframe containing read in data """ # Column names names = ["type", "subtype", "depth", "count"] - # read file - data = pd.read_csv(filename, sep=" ", comment="#", names=names) + alldata = None + for f in files: + # read file + data = pd.read_csv(f, sep=" ", comment="#", names=names) + if alldata is None: + alldata = data + else: + concat = pd.concat([alldata, data]) + alldata = concat.groupby(["type", "subtype", "depth"], as_index=False).sum() return data @@ -237,9 +247,9 @@ def add_displacement(data): if __name__ == "__main__": - args, filename = parse_args() + args, files = parse_args() - data = read_data(filename) + data = read_data(files) cmap = get_discrete_cmap(data["depth"].max()) # are we counting the levels?