Commit 0175e6cd authored by Matthieu Schaller's avatar Matthieu Schaller

Merge branch 'logger_api1' into 'master'

Implement logger writer

See merge request !1104
parents 10f5798e b93184e5
......@@ -1129,6 +1129,7 @@ if test "x$with_python" != "xno"; then
AC_MSG_RESULT([$PYTHON_INCS])
])
have_python="yes"
AC_DEFINE([HAVE_PYTHON],1,[Python appears to be present.])
fi
AC_SUBST([PYTHON_INCS])
AM_CONDITIONAL([HAVEPYTHON],[test -n "$PYTHON_INCS"])
......
......@@ -1362,7 +1362,7 @@ int main(int argc, char *argv[]) {
/* Write the state of the system before starting time integration. */
#ifdef WITH_LOGGER
if (e.policy & engine_policy_logger) {
logger_log_all(e.logger, &e);
logger_log_all_particles(e.logger, &e);
engine_dump_index(&e);
}
#endif
......@@ -1568,7 +1568,7 @@ int main(int argc, char *argv[]) {
}
#ifdef WITH_LOGGER
if (e.policy & engine_policy_logger) {
logger_log_all(e.logger, &e);
logger_log_all_particles(e.logger, &e);
/* Write a final index file */
engine_dump_index(&e);
......
......@@ -22,6 +22,7 @@
#include "logger_reader.h"
#include "logger_time.h"
#ifdef HAVE_PYTHON
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <Python.h>
......@@ -447,3 +448,5 @@ PyMODINIT_FUNC PyInit_liblogger(void) {
return m;
}
#endif // HAVE_PYTHON
......@@ -29,6 +29,7 @@
#include "../src/error.h"
#include "../src/inline.h"
#include "../src/logger.h"
#include "../src/logger_io.h"
#include "../src/part_type.h"
#ifdef HAVE_PYTHON
......
......@@ -135,7 +135,8 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h
gravity/Potential/gravity.h gravity/Potential/gravity_iact.h gravity/Potential/gravity_io.h \
gravity/Potential/gravity_debug.h gravity/Potential/gravity_part.h \
gravity/MultiSoftening/gravity.h gravity/MultiSoftening/gravity_iact.h gravity/MultiSoftening/gravity_io.h \
gravity/MultiSoftening/gravity_debug.h gravity/MultiSoftening/gravity_part.h \
gravity/MultiSoftening/gravity_debug.h gravity/MultiSoftening/gravity_part.h \
gravity/MultiSoftening/gravity_logger.h \
equation_of_state.h \
equation_of_state/ideal_gas/equation_of_state.h equation_of_state/isothermal/equation_of_state.h \
hydro.h hydro_io.h hydro_parameters.h \
......@@ -147,7 +148,7 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h
hydro/Default/hydro_parameters.h \
hydro/Gadget2/hydro.h hydro/Gadget2/hydro_iact.h hydro/Gadget2/hydro_io.h \
hydro/Gadget2/hydro_debug.h hydro/Gadget2/hydro_part.h \
hydro/Gadget2/hydro_parameters.h \
hydro/Gadget2/hydro_parameters.h hydro/Gadget2/hydro_logger.h \
hydro/PressureEntropy/hydro.h hydro/PressureEntropy/hydro_iact.h hydro/PressureEntropy/hydro_io.h \
hydro/PressureEntropy/hydro_debug.h hydro/PressureEntropy/hydro_part.h \
hydro/PressureEntropy/hydro_parameters.h \
......@@ -209,7 +210,7 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h
riemann/riemann_checks.h \
stars.h stars_io.h \
stars/Default/stars.h stars/Default/stars_iact.h stars/Default/stars_io.h \
stars/Default/stars_debug.h stars/Default/stars_part.h \
stars/Default/stars_debug.h stars/Default/stars_part.h stars/Default/stars_logger.h \
stars/EAGLE/stars.h stars/EAGLE/stars_iact.h stars/EAGLE/stars_io.h \
stars/EAGLE/stars_debug.h stars/EAGLE/stars_part.h \
stars/GEAR/stars.h stars/GEAR/stars_iact.h stars/GEAR/stars_io.h \
......@@ -293,7 +294,7 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h
pressure_floor/GEAR/pressure_floor_iact.h pressure_floor/none/pressure_floor_iact.h \
pressure_floor/GEAR/pressure_floor_struct.h pressure_floor/none/pressure_floor_struct.h \
task_order/GEAR/task_order.h task_order/EAGLE/task_order.h task_order/default/task_order.h \
sink/Default/sink.h sink/Default/sink_io.h sink/Default/sink_part.h \
sink/Default/sink.h sink/Default/sink_io.h sink/Default/sink_part.h \
sink.h sink_io.h
......
......@@ -4883,6 +4883,15 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) {
* by another thread before we do the deed. */
if (!part_is_inhibited(p, e)) {
#ifdef WITH_LOGGER
if (e->policy & engine_policy_logger) {
/* Log the particle one last time. */
logger_log_part(
e->logger, p, xp, e, /* log_all */ 1,
logger_pack_flags_and_data(logger_flag_delete, 0));
}
#endif
/* One last action before death? */
hydro_remove_part(p, xp);
......@@ -5053,6 +5062,17 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) {
/* Remove the particle entirely */
if (gp->type == swift_type_dark_matter) {
#ifdef WITH_LOGGER
if (e->policy & engine_policy_logger) {
/* Log the particle one last time. */
logger_log_gpart(
e->logger, gp, e, /* log_all */ 1,
logger_pack_flags_and_data(logger_flag_delete, 0));
}
#endif
/* Remove the particle */
cell_remove_gpart(e, c, gp);
}
}
......@@ -5194,6 +5214,15 @@ void cell_drift_spart(struct cell *c, const struct engine *e, int force) {
* by another thread before we do the deed. */
if (!spart_is_inhibited(sp, e)) {
#ifdef WITH_LOGGER
if (e->policy & engine_policy_logger) {
/* Log the particle one last time. */
logger_log_spart(
e->logger, sp, e, /* log_all */ 1,
logger_pack_flags_and_data(logger_flag_delete, 0));
}
#endif
/* Remove the particle entirely */
cell_remove_spart(e, c, sp);
}
......@@ -5365,6 +5394,12 @@ void cell_drift_bpart(struct cell *c, const struct engine *e, int force) {
* by another thread before we do the deed. */
if (!bpart_is_inhibited(bp, e)) {
#ifdef WITH_LOGGER
if (e->policy & engine_policy_logger) {
error("Logging of black hole particles is not yet implemented.");
}
#endif
/* Remove the particle entirely */
cell_remove_bpart(e, c, bp);
}
......
......@@ -562,14 +562,11 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
#ifdef WITH_LOGGER
if (e->policy & engine_policy_logger) {
const uint32_t logger_flag =
logger_pack_flags_and_data(logger_flag_mpi_exit, node_id);
/* Log the particle when leaving a rank. */
logger_log_part(
e->logger, &s->parts[offset_parts + k], &s->xparts[offset_parts + k],
logger_masks_all_part | logger_mask_data[logger_special_flags].mask,
logger_flag);
e, /* log_all_fields */ 1,
logger_pack_flags_and_data(logger_flag_mpi_exit, node_id));
}
#endif
}
......@@ -610,14 +607,11 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
#ifdef WITH_LOGGER
if (e->policy & engine_policy_logger) {
const uint32_t logger_flag =
logger_pack_flags_and_data(logger_flag_mpi_exit, node_id);
/* Log the particle when leaving a rank. */
logger_log_spart(
e->logger, &s->sparts[offset_sparts + k],
logger_masks_all_spart | logger_mask_data[logger_special_flags].mask,
logger_flag);
e->logger, &s->sparts[offset_sparts + k], e,
/* log_all_fields */ 1,
logger_pack_flags_and_data(logger_flag_mpi_exit, node_id));
}
#endif
}
......@@ -696,14 +690,11 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
if ((e->policy & engine_policy_logger) &&
s->gparts[offset_gparts + k].type == swift_type_dark_matter) {
const uint32_t logger_flag =
logger_pack_flags_and_data(logger_flag_mpi_exit, node_id);
/* Log the particle when leaving a rank. */
logger_log_gpart(
e->logger, &s->gparts[offset_gparts + k],
logger_masks_all_gpart | logger_mask_data[logger_special_flags].mask,
logger_flag);
e->logger, &s->gparts[offset_gparts + k], e,
/* log_all_fields */ 1,
logger_pack_flags_and_data(logger_flag_mpi_exit, node_id));
}
#endif
}
......@@ -937,22 +928,16 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts,
struct gpart *gparts = &s->gparts[offset_gparts + count_gparts];
/* Log the gas particles */
logger_log_parts(
e->logger, parts, xparts, prox->nr_parts_in,
logger_masks_all_part | logger_mask_data[logger_special_flags].mask,
flag);
logger_log_parts(e->logger, parts, xparts, prox->nr_parts_in, e,
/* log_all_fields */ 1, flag);
/* Log the stellar particles */
logger_log_sparts(e->logger, sparts, prox->nr_sparts_in,
logger_masks_all_spart |
logger_mask_data[logger_special_flags].mask,
flag);
logger_log_sparts(e->logger, sparts, prox->nr_sparts_in, e,
/* log_all_fields */ 1, flag);
/* Log the gparts */
logger_log_gparts(e->logger, gparts, prox->nr_gparts_in,
logger_masks_all_gpart |
logger_mask_data[logger_special_flags].mask,
flag);
logger_log_gparts(e->logger, gparts, prox->nr_gparts_in, e,
/* log_all_fields */ 1, flag);
/* Log the bparts */
if (prox->nr_bparts_in > 0) {
......@@ -3980,7 +3965,7 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params,
#if defined(WITH_LOGGER)
if (e->policy & engine_policy_logger) {
e->logger = (struct logger_writer *)malloc(sizeof(struct logger_writer));
logger_init(e->logger, params);
logger_init(e->logger, e, params);
}
#endif
......
......@@ -1004,22 +1004,16 @@ void engine_redistribute(struct engine *e) {
const uint32_t flag = logger_pack_flags_and_data(logger_flag_mpi_exit, i);
/* Log the hydro parts. */
logger_log_parts(
e->logger, &parts[part_offset], &xparts[part_offset], counts[c_ind],
logger_masks_all_part | logger_mask_data[logger_special_flags].mask,
flag);
logger_log_parts(e->logger, &parts[part_offset], &xparts[part_offset],
counts[c_ind], e, /* log_all_fields */ 1, flag);
/* Log the stellar parts. */
logger_log_sparts(
e->logger, &sparts[spart_offset], s_counts[c_ind],
logger_masks_all_spart | logger_mask_data[logger_special_flags].mask,
flag);
logger_log_sparts(e->logger, &sparts[spart_offset], s_counts[c_ind], e,
/* log_all_fields */ 1, flag);
/* Log the gparts */
logger_log_gparts(
e->logger, &gparts[gpart_offset], g_counts[c_ind],
logger_masks_all_gpart | logger_mask_data[logger_special_flags].mask,
flag);
logger_log_gparts(e->logger, &gparts[gpart_offset], g_counts[c_ind], e,
/* log_all_fields */ 1, flag);
/* Log the bparts */
if (b_counts[c_ind] > 0) {
......@@ -1110,23 +1104,17 @@ void engine_redistribute(struct engine *e) {
logger_pack_flags_and_data(logger_flag_mpi_enter, i);
/* Log the hydro parts. */
logger_log_parts(
e->logger, &s->parts[part_offset], &s->xparts[part_offset],
counts[c_ind],
logger_masks_all_part | logger_mask_data[logger_special_flags].mask,
flag);
logger_log_parts(e->logger, &s->parts[part_offset],
&s->xparts[part_offset], counts[c_ind], e,
/* log_all_fields */ 1, flag);
/* Log the stellar parts. */
logger_log_sparts(
e->logger, &s->sparts[spart_offset], s_counts[c_ind],
logger_masks_all_spart | logger_mask_data[logger_special_flags].mask,
flag);
logger_log_sparts(e->logger, &s->sparts[spart_offset], s_counts[c_ind], e,
/* log_all_fields */ 1, flag);
/* Log the gparts */
logger_log_gparts(
e->logger, &s->gparts[gpart_offset], g_counts[c_ind],
logger_masks_all_gpart | logger_mask_data[logger_special_flags].mask,
flag);
logger_log_gparts(e->logger, &s->gparts[gpart_offset], g_counts[c_ind], e,
/* log_all_fields */ 1, flag);
/* Log the bparts */
if (b_counts[c_ind] > 0) {
......
/*******************************************************************************
* 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_MULTISOFTENING_GRAVITY_LOGGER_H
#define SWIFT_MULTISOFTENING_GRAVITY_LOGGER_H
#include "logger_io.h"
#ifdef WITH_LOGGER
/*
* List of all possible mask.
* Outside the module, only logger_gravity_count is used.
*/
enum gravity_logger_fields {
gravity_logger_field_coordinates = 0,
gravity_logger_field_velocities,
gravity_logger_field_accelerations,
gravity_logger_field_masses,
gravity_logger_field_particle_ids,
gravity_logger_field_count,
};
/* Name of each possible mask. */
static const char *gravity_logger_field_names[gravity_logger_field_count] = {
"Coordinates", "Velocities", "Accelerations", "Masses", "ParticleIDs",
};
/**
* @brief Initialize the logger.
*
* WARNING: this should be done in the same order than
* #gravity_logger_write_particle.
*
* @param mask_data Data for each type of mask.
*
* @return Number of masks used.
*/
INLINE static int gravity_logger_populate_mask_data(
struct mask_data *mask_data) {
mask_data[gravity_logger_field_coordinates] = logger_create_mask_entry(
gravity_logger_field_names[gravity_logger_field_coordinates],
3 * sizeof(double));
mask_data[gravity_logger_field_velocities] = logger_create_mask_entry(
gravity_logger_field_names[gravity_logger_field_velocities],
3 * sizeof(float));
mask_data[gravity_logger_field_accelerations] = logger_create_mask_entry(
gravity_logger_field_names[gravity_logger_field_accelerations],
3 * sizeof(float));
mask_data[gravity_logger_field_masses] = logger_create_mask_entry(
gravity_logger_field_names[gravity_logger_field_masses], sizeof(float));
mask_data[gravity_logger_field_particle_ids] = logger_create_mask_entry(
gravity_logger_field_names[gravity_logger_field_particle_ids],
sizeof(long long));
return gravity_logger_field_count;
}
/**
* @brief Generates the mask and compute the size of the record.
*
* @param masks The list of masks (same order than in #gravity_logger_init).
* @param part The #gpart 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 gravity_logger_compute_size_and_mask(
const struct mask_data *masks, const struct gpart *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[gravity_logger_field_coordinates],
gravity_logger_field_names[gravity_logger_field_coordinates],
buffer_size);
/* Add the velocities. */
*mask |= logger_add_field_to_mask(
masks[gravity_logger_field_velocities],
gravity_logger_field_names[gravity_logger_field_velocities], buffer_size);
/* Add the accelerations. */
*mask |= logger_add_field_to_mask(
masks[gravity_logger_field_accelerations],
gravity_logger_field_names[gravity_logger_field_accelerations],
buffer_size);
/* Add the masses. */
*mask |= logger_add_field_to_mask(
masks[gravity_logger_field_masses],
gravity_logger_field_names[gravity_logger_field_masses], buffer_size);
/* Add the ID. */
*mask |= logger_add_field_to_mask(
masks[gravity_logger_field_particle_ids],
gravity_logger_field_names[gravity_logger_field_particle_ids],
buffer_size);
}
/**
* @brief Write a particle to the logger.
*
* @param masks The list of masks (same order than in #gravity_logger_init).
* @param p The #gpart 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 *gravity_logger_write_particle(
const struct mask_data *mask_data, const struct gpart *p,
unsigned int *mask, char *buff) {
/* Write the coordinate. */
if (logger_should_write_field(
mask_data[gravity_logger_field_coordinates], mask,
gravity_logger_field_names[gravity_logger_field_coordinates])) {
memcpy(buff, p->x, 3 * sizeof(double));
buff += 3 * sizeof(double);
}
/* Write the velocity. */
if (logger_should_write_field(
mask_data[gravity_logger_field_velocities], mask,
gravity_logger_field_names[gravity_logger_field_velocities])) {
memcpy(buff, p->v_full, 3 * sizeof(float));
buff += 3 * sizeof(float);
}
/* Write the acceleration. */
if (logger_should_write_field(
mask_data[gravity_logger_field_accelerations], mask,
gravity_logger_field_names[gravity_logger_field_accelerations])) {
memcpy(buff, p->a_grav, 3 * sizeof(float));
buff += 3 * sizeof(float);
}
/* Write the mass. */
if (logger_should_write_field(
mask_data[gravity_logger_field_masses], mask,
gravity_logger_field_names[gravity_logger_field_masses])) {
memcpy(buff, &p->mass, sizeof(float));
buff += sizeof(float);
}
/* Write the Id. */
if (logger_should_write_field(
mask_data[gravity_logger_field_particle_ids], mask,
gravity_logger_field_names[gravity_logger_field_particle_ids])) {
memcpy(buff, &p->id_or_neg_offset, sizeof(long long));
buff += sizeof(long long);
}
return buff;
}
#endif // WITH_LOGGER
#endif // SWIFT_MULTISOFTENING_GRAVITY_LOGGER_H
......@@ -32,6 +32,7 @@
#include "./gravity/Potential/gravity_io.h"
#elif defined(MULTI_SOFTENING_GRAVITY)
#include "./gravity/MultiSoftening/gravity_io.h"
#include "./gravity/MultiSoftening/gravity_logger.h"
#else
#error "Invalid choice of gravity variant"
#endif
......
/*******************************************************************************
* 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_GADGET2_HYDRO_LOGGER_H
#define SWIFT_GADGET2_HYDRO_LOGGER_H
#include "logger_io.h"
#ifdef WITH_LOGGER
/*
* List of all possible mask.
* Outside the module, only hydro_logger_field_count is used.
*/
enum hydro_logger_fields_mask {
hydro_logger_field_coordinates = 0,
hydro_logger_field_velocities,
hydro_logger_field_accelerations,
hydro_logger_field_masses,
hydro_logger_field_smoothing_lengths,
hydro_logger_field_entropies,
hydro_logger_field_particle_ids,
hydro_logger_field_densities,
hydro_logger_field_count,
};
/* Name of each possible mask. */
static const char *hydro_logger_field_names[hydro_logger_field_count] = {
"Coordinates", "Velocities", "Accelerations", "Masses",
"SmoothingLengths", "Entropies", "ParticleIDs", "Densities"};
/**
* @brief Initialize the logger.
*
* WARNING: this should be done in the same order than
* #hydro_logger_write_particle.
*
* @param mask_data Data for each type of mask.
*
* @return Number of masks used.
*/
INLINE static int hydro_logger_populate_mask_data(struct mask_data *mask_data) {
mask_data[hydro_logger_field_coordinates] = logger_create_mask_entry(
hydro_logger_field_names[hydro_logger_field_coordinates],
3 * sizeof(double));
mask_data[hydro_logger_field_velocities] = logger_create_mask_entry(
hydro_logger_field_names[hydro_logger_field_velocities],
3 * sizeof(float));
mask_data[hydro_logger_field_accelerations] = logger_create_mask_entry(
hydro_logger_field_names[hydro_logger_field_accelerations],
3 * sizeof(float));
mask_data[hydro_logger_field_masses] = logger_create_mask_entry(
hydro_logger_field_names[hydro_logger_field_masses], sizeof(float));
mask_data[hydro_logger_field_smoothing_lengths] = logger_create_mask_entry(
hydro_logger_field_names[hydro_logger_field_smoothing_lengths],
sizeof(float));
mask_data[hydro_logger_field_entropies] = logger_create_mask_entry(
hydro_logger_field_names[hydro_logger_field_entropies], sizeof(float));
mask_data[hydro_logger_field_particle_ids] = logger_create_mask_entry(
hydro_logger_field_names[hydro_logger_field_particle_ids],
sizeof(long long));
mask_data[hydro_logger_field_densities] = logger_create_mask_entry(
hydro_logger_field_names[hydro_logger_field_densities], sizeof(float));
return hydro_logger_field_count;
}
/**
* @brief Generates the mask and compute the size of the record.
*
* @param masks The list of masks (same order than in #hydro_logger_init).
* @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 hydro_logger_compute_size_and_mask(
const struct mask_data *masks, const struct part *part,
const struct xpart *xpart, 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[hydro_logger_field_coordinates],
hydro_logger_field_names[hydro_logger_field_coordinates], buffer_size);
/* Add the velocities. */
*mask |= logger_add_field_to_mask(
masks[hydro_logger_field_velocities],
hydro_logger_field_names[hydro_logger_field_velocities], buffer_size);
/* Add the accelerations. */
*mask |= logger_add_field_to_mask(
masks[hydro_logger_field_accelerations],
hydro_logger_field_names[hydro_logger_field_accelerations], buffer_size);
/* Add the masses. */
*mask |= logger_add_field_to_mask(
masks[hydro_logger_field_masses],
hydro_logger_field_names[hydro_logger_field_masses], buffer_size);
/* Add the smoothing lengths. */
*mask |= logger_add_field_to_mask(
masks[hydro_logger_field_smoothing_lengths],
hydro_logger_field_names[hydro_logger_field_smoothing_lengths],
buffer_size);
/* Add the entropies. */
*mask |= logger_add_field_to_mask(
masks[hydro_logger_field_entropies],
hydro_logger_field_names[hydro_logger_field_entropies], buffer_size);
/* Add the ID. */
*mask |= logger_add_field_to_mask(
masks[hydro_logger_field_particle_ids],
hydro_logger_field_names[hydro_logger_field_particle_ids], buffer_size);
/* Add the density. */
*mask |= logger_add_field_to_mask(
masks[hydro_logger_field_densities],
hydro_logger_field_names[hydro_logger_field_densities], buffer_size);
}
/**
* @brief Write a particle to the logger.
*
* @param masks The list of masks (same order than in #hydro_logger_init).
* @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 *hydro_logger_write_particle(
const struct mask_data *mask_data, const struct part *p,
const struct xpart *xp, unsigned int *mask, char *buff) {
/* Write the coordinate. */
if (logger_should_write_field(
mask_data[hydro_logger_field_coordinates], mask,
hydro_logger_field_names[hydro_logger_field_coordinates])) {
memcpy(buff, p->x, 3 * sizeof(double));
buff += 3 * sizeof(double);
}
/* Write the velocity. */
if (logger_should_write_field(
mask_data[hydro_logger_field_velocities], mask,
hydro_logger_field_names[hydro_logger_field_velocities])) {
memcpy(buff, p->v, 3 * sizeof(float));
buff += 3 * sizeof(float);
}
/* Write the acceleration. */
if (logger_should_write_field(
mask_data[hydro_logger_field_accelerations], mask,
hydro_logger_field_names[hydro_logger_field_accelerations])) {
/* Compute the acceleration due to hydro and gravity */
float *acc = (float *)buff;
acc[0] = p->a_hydro[0] + xp->a_grav[0];
acc[1] = p->a_hydro[1] + xp->a_grav[1];
acc[2] = p->a_hydro[2] + xp->a_grav[2];
memcpy(buff, acc, 3 * sizeof(float));
buff += 3 * sizeof(float);
}
/* Write the mass. */
if (logger_should_write_field(
mask_data[hydro_logger_field_masses], mask,
hydro_logger_field_names[hydro_logger_field_masses])) {
memcpy(buff, &p->mass, sizeof(float));
buff += sizeof(float);
}
/* Write the smoothing length. */
if (logger_should_write_field(
mask_data[hydro_logger_field_smoothing_lengths], mask,
hydro_logger_field_names[hydro_logger_field_smoothing_lengths])) {
memcpy(buff, &p->h, sizeof(float));
buff += sizeof(float);
}
/* Write the entropy. */
if (logger_should_write_field(
mask_data[hydro_logger_field_entropies], mask,
hydro_logger_field_names[hydro_logger_field_entropies])) {
memcpy(buff, &p->entropy, sizeof(float));
buff += sizeof(float);
}
/* Write the Id. */
if (logger_should_write_field(
mask_data[hydro_logger_field_particle_ids], mask,
hydro_logger_field_names[hydro_logger_field_particle_ids])) {
memcpy(buff, &p->id, sizeof(long long));
buff += sizeof(long long);
}
/* Write the density. */
if (logger_should_write_field(