/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2017 Pedro Gonnet (pedro.gonnet@durham.ac.uk)
* 2018 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 .
*
******************************************************************************/
#ifndef SWIFT_CSDS_H
#define SWIFT_CSDS_H
#include
#ifdef WITH_CSDS
/* Includes. */
#include "align.h"
#include "common_io.h"
#include "error.h"
#include "inline.h"
#include "timeline.h"
#include "units.h"
/* Include the CSDS */
#include "csds/src/logfile_writer.h"
/* Forward declaration. */
struct gpart;
struct part;
struct engine;
/**
* Csds entries contain messages representing the particle data at a given
* point in time during the simulation.
*
* The csds messages always start with an 8-byte header structured as
* follows:
*
* data: [ mask | offset ]
* byte: [ 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 ]
*
* I.e. a first "mask" byte followed by 6 "offset" bytes. The mask contains
* information on what kind of data is packed after the header. The mask
* bits correspond to the following data:
*
* There is no distinction between gravity and SPH particles.
*
* The offset refers to the relative location of the previous message for the
* same particle or for the previous timestamp. I.e.
* the previous log entry will be at the address of the current mask byte minus
* the unsigned value stored in the offset. An offset equal to the record offset
* indicated that this is the first message for the given particle/timestamp.
*/
/**
* @brief structure containing global data for the particle csds.
*/
struct csds_writer {
/* Number of particle updates between log entries. */
short int delta_step;
/* Csds basename. */
char base_name[CSDS_STRING_SIZE];
/* The logfile writer. */
struct csds_logfile_writer logfile;
/* timestamp offset for csds. */
size_t timestamp_offset;
/* scaling factor when buffer is too small. */
float buffer_scale;
/* Size of a record if every mask are activated. */
int max_record_size;
/* Description of all the fields that can be written. */
struct csds_field *list_fields;
/* Pointer to the variable list_fields for each module. */
struct csds_field *field_pointers[swift_type_count];
/* Number of fields for each particle type. */
int number_fields[swift_type_count];
/* Number of elements in list_fields. */
int total_number_fields;
} SWIFT_STRUCT_ALIGN;
/* required structure for each particle type. */
struct csds_part_data {
/* Number of particle updates since last output. */
int steps_since_last_output;
/* offset of last particle log entry. */
uint64_t last_offset;
};
/* Function prototypes. */
void csds_log_all_particles(struct csds_writer *log, const struct engine *e,
const enum csds_special_flags flag);
void csds_log_part(struct csds_writer *log, const struct part *p,
struct xpart *xp, const struct engine *e,
const int log_all_fields, const enum csds_special_flags flag,
const int flag_data);
void csds_log_parts(struct csds_writer *log, const struct part *p,
struct xpart *xp, int count, const struct engine *e,
const int log_all_fields,
const enum csds_special_flags flag, const int flag_data);
void csds_log_spart(struct csds_writer *log, struct spart *p,
const struct engine *e, const int log_all_fields,
const enum csds_special_flags flag, const int flag_data);
void csds_log_sparts(struct csds_writer *log, struct spart *sp, int count,
const struct engine *e, const int log_all_fields,
const enum csds_special_flags flag, const int flag_data);
void csds_log_gpart(struct csds_writer *log, struct gpart *p,
const struct engine *e, const int log_all_fields,
const enum csds_special_flags flag, const int flag_data);
void csds_log_gparts(struct csds_writer *log, struct gpart *gp, int count,
const struct engine *e, const int log_all_fields,
const enum csds_special_flags flag, const int flag_data);
void csds_init(struct csds_writer *log, const struct engine *e,
struct swift_params *params);
void csds_free(struct csds_writer *log);
void csds_log_timestamp(struct csds_writer *log, integertime_t t, double time,
size_t *offset);
void csds_ensure_size(struct csds_writer *log, const struct engine *e);
void csds_write_file_header(struct csds_writer *log);
int csds_read_part(const struct csds_writer *log, struct part *p,
size_t *offset, const char *buff);
int csds_read_gpart(const struct csds_writer *log, struct gpart *p,
size_t *offset, const char *buff);
int csds_read_timestamp(const struct csds_writer *log, integertime_t *t,
double *time, size_t *offset, const char *buff);
void csds_struct_dump(const struct csds_writer *log, FILE *stream);
void csds_struct_restore(struct csds_writer *log, FILE *stream);
/**
* @brief Initialize the csds data for a particle.
*
* @param csds The #csds_part_data.
*/
INLINE static void csds_part_data_init(struct csds_part_data *csds) {
csds->last_offset = 0;
csds->steps_since_last_output = 0;
}
/**
* @brief Should this particle write its data now ?
*
* @param csds_data The #csds_part_data of a particle.
* @param log The #csds_writer.
*
* @return 1 if the particle should be writen, 0 otherwise.
*/
__attribute__((always_inline)) INLINE static int csds_should_write(
const struct csds_part_data *csds_data, const struct csds_writer *log) {
return (csds_data->steps_since_last_output > log->delta_step);
}
#endif /* WITH_CSDS */
#endif /* SWIFT_CSDS_H */