Commit 07f1e5b1 authored by Peter W. Draper's avatar Peter W. Draper
Browse files

Merge branch 'cosmo_io' into 'master'

More cosmology work

Closes #407 and #404

See merge request !516
parents a727dda0 4f946aa2
......@@ -33,7 +33,9 @@
/* Local includes. */
#include "parser.h"
#include "physical_constants.h"
#include "restart.h"
#include "units.h"
/**
* @brief Contains all the constants and parameters of the hydro scheme
......@@ -63,10 +65,28 @@ struct hydro_props {
/*! Maximal change of h over one time-step */
float log_max_h_change;
/*! Minimal temperature allowed */
float minimal_temperature;
/*! Minimal internal energy per unit mass */
float minimal_internal_energy;
/*! Initial temperature */
float initial_temperature;
/*! Initial internal energy per unit mass */
float initial_internal_energy;
/*! Primoridal hydrogen mass fraction for initial energy conversion */
float hydrogen_mass_fraction;
};
void hydro_props_print(const struct hydro_props *p);
void hydro_props_init(struct hydro_props *p, const struct swift_params *params);
void hydro_props_init(struct hydro_props *p,
const struct phys_const *phys_const,
const struct unit_system *us,
const struct swift_params *params);
#if defined(HAVE_HDF5)
void hydro_props_print_snapshot(hid_t h_grpsph, const struct hydro_props *p);
......
......@@ -34,9 +34,11 @@ enum DATA_IMPORTANCE { COMPULSORY = 1, OPTIONAL = 0, UNUSED = -1 };
/* Helper typedefs */
typedef void (*conversion_func_part_float)(const struct engine*,
const struct part*, float*);
const struct part*,
const struct xpart*, float*);
typedef void (*conversion_func_part_double)(const struct engine*,
const struct part*, double*);
const struct part*,
const struct xpart*, double*);
typedef void (*conversion_func_gpart_float)(const struct engine*,
const struct gpart*, float*);
typedef void (*conversion_func_gpart_double)(const struct engine*,
......@@ -78,6 +80,7 @@ struct io_props {
/* The particle arrays */
const struct part* parts;
const struct xpart* xparts;
const struct gpart* gparts;
/* Are we converting? */
......@@ -125,6 +128,7 @@ INLINE static struct io_props io_make_input_field_(
r.field = field;
r.partSize = partSize;
r.parts = NULL;
r.xparts = NULL;
r.gparts = NULL;
r.conversion = 0;
r.convert_part_f = NULL;
......@@ -179,10 +183,10 @@ INLINE static struct io_props io_make_output_field_(
/**
* @brief Constructs an #io_props (with conversion) from its parameters
*/
#define io_make_output_field_convert_part(name, type, dim, units, part, \
convert) \
io_make_output_field_convert_part_##type(name, type, dim, units, \
sizeof(part[0]), part, convert)
#define io_make_output_field_convert_part(name, type, dim, units, part, xpart, \
convert) \
io_make_output_field_convert_part_##type( \
name, type, dim, units, sizeof(part[0]), part, xpart, convert)
/**
* @brief Construct an #io_props from its parameters
......@@ -193,6 +197,7 @@ INLINE static struct io_props io_make_output_field_(
* @param units The units of the dataset
* @param partSize The size in byte of the particle
* @param parts The particle array
* @param xparts The xparticle array
* @param functionPtr The function used to convert a particle to a float
*
* Do not call this function directly. Use the macro defined above.
......@@ -200,7 +205,8 @@ INLINE static struct io_props io_make_output_field_(
INLINE static struct io_props io_make_output_field_convert_part_FLOAT(
const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
enum unit_conversion_factor units, size_t partSize,
const struct part* parts, conversion_func_part_float functionPtr) {
const struct part* parts, const struct xpart* xparts,
conversion_func_part_float functionPtr) {
struct io_props r;
strcpy(r.name, name);
......@@ -211,6 +217,7 @@ INLINE static struct io_props io_make_output_field_convert_part_FLOAT(
r.field = NULL;
r.partSize = partSize;
r.parts = parts;
r.xparts = xparts;
r.gparts = NULL;
r.conversion = 1;
r.convert_part_f = functionPtr;
......@@ -230,6 +237,7 @@ INLINE static struct io_props io_make_output_field_convert_part_FLOAT(
* @param units The units of the dataset
* @param partSize The size in byte of the particle
* @param parts The particle array
* @param xparts The xparticle array
* @param functionPtr The function used to convert a particle to a float
*
* Do not call this function directly. Use the macro defined above.
......@@ -237,7 +245,8 @@ INLINE static struct io_props io_make_output_field_convert_part_FLOAT(
INLINE static struct io_props io_make_output_field_convert_part_DOUBLE(
const char name[FIELD_BUFFER_SIZE], enum IO_DATA_TYPE type, int dimension,
enum unit_conversion_factor units, size_t partSize,
const struct part* parts, conversion_func_part_double functionPtr) {
const struct part* parts, const struct xpart* xparts,
conversion_func_part_double functionPtr) {
struct io_props r;
strcpy(r.name, name);
......@@ -248,6 +257,7 @@ INLINE static struct io_props io_make_output_field_convert_part_DOUBLE(
r.field = NULL;
r.partSize = partSize;
r.parts = parts;
r.xparts = xparts;
r.gparts = NULL;
r.conversion = 1;
r.convert_part_f = NULL;
......@@ -293,6 +303,7 @@ INLINE static struct io_props io_make_output_field_convert_gpart_FLOAT(
r.field = NULL;
r.partSize = gpartSize;
r.parts = NULL;
r.xparts = NULL;
r.gparts = gparts;
r.conversion = 1;
r.convert_part_f = NULL;
......@@ -330,6 +341,7 @@ INLINE static struct io_props io_make_output_field_convert_gpart_DOUBLE(
r.field = NULL;
r.partSize = gpartSize;
r.parts = NULL;
r.xparts = NULL;
r.gparts = gparts;
r.conversion = 1;
r.convert_part_f = NULL;
......
......@@ -26,6 +26,10 @@
#include "inline.h"
#include "minmax.h"
/*! Conversion factor between Plummer softening and internal softening */
#define kernel_gravity_softening_plummer_equivalent 3.
#define kernel_gravity_softening_plummer_equivalent_inv (1. / 3.)
/**
* @brief Computes the gravity softening function for potential.
*
......
......@@ -68,13 +68,16 @@ __attribute__((always_inline)) INLINE static void kick_gpart(
* @param dt_kick_hydro The kick time-step for hydro accelerations.
* @param dt_kick_grav The kick time-step for gravity accelerations.
* @param dt_kick_therm The kick time-step for changes in thermal state.
* @param cosmo The cosmological model.
* @param hydro_props The constants used in the scheme
* @param ti_start The starting (integer) time of the kick (for debugging
* checks).
* @param ti_end The ending (integer) time of the kick (for debugging checks).
*/
__attribute__((always_inline)) INLINE static void kick_part(
struct part *restrict p, struct xpart *restrict xp, double dt_kick_hydro,
double dt_kick_grav, double dt_kick_therm, integertime_t ti_start,
double dt_kick_grav, double dt_kick_therm, const struct cosmology *cosmo,
const struct hydro_props *hydro_props, integertime_t ti_start,
integertime_t ti_end) {
#ifdef SWIFT_DEBUG_CHECKS
......@@ -107,7 +110,7 @@ __attribute__((always_inline)) INLINE static void kick_part(
}
/* Extra kick work */
hydro_kick_extra(p, xp, dt_kick_therm);
hydro_kick_extra(p, xp, dt_kick_therm, cosmo, hydro_props);
if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt_kick_grav);
}
......
......@@ -218,12 +218,6 @@ void logger_log_gpart(struct gpart *p, unsigned int mask, size_t *offset,
buff += 3 * sizeof(float);
}
/* Particle smoothing length as a single float. */
if (mask & logger_mask_h) {
memcpy(buff, &p->epsilon, sizeof(float));
buff += sizeof(float);
}
/* Particle constants, which is a bit more complicated. */
if (mask & logger_mask_rho) {
memcpy(buff, &p->mass, sizeof(float));
......@@ -385,12 +379,6 @@ int logger_read_gpart(struct gpart *p, size_t *offset, const char *buff) {
buff += 3 * sizeof(float);
}
/* Particle smoothing length as a single float. */
if (mask & logger_mask_h) {
memcpy(&p->epsilon, buff, sizeof(float));
buff += sizeof(float);
}
/* Particle constants, which is a bit more complicated. */
if (mask & logger_mask_rho) {
memcpy(&p->mass, buff, sizeof(float));
......
......@@ -1524,8 +1524,8 @@ INLINE static void gravity_M2L(struct grav_tensor *l_b,
const double dim[3]) {
/* Recover some constants */
const float eps = props->epsilon;
const float eps_inv = props->epsilon_inv;
const float eps = props->epsilon_cur;
const float eps_inv = props->epsilon_cur_inv;
/* Compute distance vector */
float dx = (float)(pos_b[0] - pos_a[0]);
......@@ -2380,6 +2380,7 @@ INLINE static void gravity_L2P(const struct grav_tensor *lb,
gp->a_grav[2] += a_grav[2];
gp->potential += pot;
}
/**
* @brief Checks whether a cell-cell interaction can be appromixated by a M-M
* interaction using the distance and cell radius.
......
......@@ -69,11 +69,14 @@
* @param offset Offset in the array where this mpi task starts writing.
* @param internal_units The #unit_system used internally.
* @param ic_units The #unit_system used in the snapshots.
* @param cleanup_h Are we removing h-factors from the ICs?
* @param h The value of the reduced Hubble constant to use for cleaning.
*/
void readArray_chunk(hid_t h_data, hid_t h_plist_id,
const struct io_props props, size_t N, long long offset,
const struct unit_system* internal_units,
const struct unit_system* ic_units) {
const struct unit_system* ic_units, int cleanup_h,
double h) {
const size_t typeSize = io_sizeof_type(props.type);
const size_t copySize = typeSize * props.dimension;
......@@ -136,6 +139,23 @@ void readArray_chunk(hid_t h_data, hid_t h_plist_id,
}
}
/* Clean-up h if necessary */
const float h_factor_exp = units_h_factor(internal_units, props.units);
if (cleanup_h && h_factor_exp != 0.f) {
const double h_factor = pow(h, h_factor_exp);
/* message("Multipltying '%s' by h^%f=%f", props.name, h_factor_exp,
* h_factor); */
if (io_is_double_precision(props.type)) {
double* temp_d = (double*)temp;
for (size_t i = 0; i < num_elements; ++i) temp_d[i] *= h_factor;
} else {
float* temp_f = (float*)temp;
for (size_t i = 0; i < num_elements; ++i) temp_f[i] *= h_factor;
}
}
/* Copy temporary buffer to particle data */
char* temp_c = (char*)temp;
for (size_t i = 0; i < N; ++i)
......@@ -158,11 +178,13 @@ void readArray_chunk(hid_t h_data, hid_t h_plist_id,
* @param offset The offset in the array on disk for this rank.
* @param internal_units The #unit_system used internally.
* @param ic_units The #unit_system used in the ICs.
* @param cleanup_h Are we removing h-factors from the ICs?
* @param h The value of the reduced Hubble constant to use for cleaning.
*/
void readArray(hid_t grp, struct io_props props, size_t N, long long N_total,
int mpi_rank, long long offset,
const struct unit_system* internal_units,
const struct unit_system* ic_units) {
const struct unit_system* ic_units, int cleanup_h, double h) {
const size_t typeSize = io_sizeof_type(props.type);
const size_t copySize = typeSize * props.dimension;
......@@ -207,7 +229,7 @@ void readArray(hid_t grp, struct io_props props, size_t N, long long N_total,
/* Write the first chunk */
const size_t this_chunk = (N > max_chunk_size) ? max_chunk_size : N;
readArray_chunk(h_data, h_plist_id, props, this_chunk, offset,
internal_units, ic_units);
internal_units, ic_units, cleanup_h, h);
/* Compute how many items are left */
if (N > max_chunk_size) {
......@@ -309,8 +331,7 @@ void prepareArray(struct engine* e, hid_t grp, char* fileName, FILE* xmfFile,
io_write_attribute_d(
h_data, "CGS conversion factor",
units_cgs_conversion_factor(snapshot_units, props.units));
io_write_attribute_f(h_data, "h-scale exponent",
units_h_factor(snapshot_units, props.units));
io_write_attribute_f(h_data, "h-scale exponent", 0);
io_write_attribute_f(h_data, "a-scale exponent",
units_a_factor(snapshot_units, props.units));
io_write_attribute_s(h_data, "Conversion factor", buffer);
......@@ -541,6 +562,8 @@ void writeArray(struct engine* e, hid_t grp, char* fileName,
* @param with_hydro Are we running with hydro ?
* @param with_gravity Are we running with gravity ?
* @param with_stars Are we running with stars ?
* @param cleanup_h Are we cleaning-up h-factors from the quantities we read?
* @param h The value of the reduced Hubble constant to use for correction.
* @param mpi_rank The MPI rank of this node
* @param mpi_size The number of MPI ranks
* @param comm The MPI communicator
......@@ -554,8 +577,9 @@ void read_ic_parallel(char* fileName, const struct unit_system* internal_units,
struct spart** sparts, size_t* Ngas, size_t* Ngparts,
size_t* Nstars, int* periodic, int* flag_entropy,
int with_hydro, int with_gravity, int with_stars,
int mpi_rank, int mpi_size, MPI_Comm comm, MPI_Info info,
int n_threads, int dry_run) {
int cleanup_h, double h, int mpi_rank, int mpi_size,
MPI_Comm comm, MPI_Info info, int n_threads,
int dry_run) {
hid_t h_file = 0, h_grp = 0;
/* GADGET has only cubic boxes (in cosmological mode) */
......@@ -626,6 +650,13 @@ void read_ic_parallel(char* fileName, const struct unit_system* internal_units,
else if (hydro_dimension == 1)
dim[2] = dim[1] = dim[0];
/* Convert the box size if we want to clean-up h-factors */
if (cleanup_h) {
dim[0] /= h;
dim[1] /= h;
dim[2] /= h;
}
/* message("Found %lld particles in a %speriodic box of size [%f %f %f].", */
/* N_total[0], (periodic ? "": "non-"), dim[0], */
/* dim[1], dim[2]); */
......@@ -771,7 +802,7 @@ void read_ic_parallel(char* fileName, const struct unit_system* internal_units,
if (!dry_run)
for (int i = 0; i < num_fields; ++i)
readArray(h_grp, list[i], Nparticles, N_total[ptype], mpi_rank,
offset[ptype], internal_units, ic_units);
offset[ptype], internal_units, ic_units, cleanup_h, h);
/* Close particle group */
H5Gclose(h_grp);
......@@ -821,9 +852,10 @@ void prepare_file(struct engine* e, const char* baseName, long long N_total[6],
const struct unit_system* internal_units,
const struct unit_system* snapshot_units) {
struct part* parts = e->s->parts;
struct gpart* gparts = e->s->gparts;
struct spart* sparts = e->s->sparts;
const struct part* parts = e->s->parts;
const struct xpart* xparts = e->s->xparts;
const struct gpart* gparts = e->s->gparts;
const struct spart* sparts = e->s->sparts;
FILE* xmfFile = 0;
int periodic = e->s->periodic;
int numFiles = 1;
......@@ -980,7 +1012,7 @@ void prepare_file(struct engine* e, const char* baseName, long long N_total[6],
switch (ptype) {
case swift_type_gas:
hydro_write_particles(parts, list, &num_fields);
hydro_write_particles(parts, xparts, list, &num_fields);
num_fields += chemistry_write_particles(parts, list + num_fields);
break;
......@@ -1045,10 +1077,11 @@ void write_output_parallel(struct engine* e, const char* baseName,
const size_t Ngas = e->s->nr_parts;
const size_t Nstars = e->s->nr_sparts;
const size_t Ntot = e->s->nr_gparts;
struct part* parts = e->s->parts;
struct gpart* gparts = e->s->gparts;
const struct part* parts = e->s->parts;
const struct xpart* xparts = e->s->xparts;
const struct gpart* gparts = e->s->gparts;
struct gpart* dmparts = NULL;
struct spart* sparts = e->s->sparts;
const struct spart* sparts = e->s->sparts;
/* Number of unassociated gparts */
const size_t Ndm = Ntot > 0 ? Ntot - (Ngas + Nstars) : 0;
......@@ -1208,7 +1241,7 @@ void write_output_parallel(struct engine* e, const char* baseName,
case swift_type_gas:
Nparticles = Ngas;
hydro_write_particles(parts, list, &num_fields);
hydro_write_particles(parts, xparts, list, &num_fields);
num_fields += chemistry_write_particles(parts, list + num_fields);
break;
......
......@@ -22,6 +22,8 @@
/* Config parameters. */
#include "../config.h"
#if defined(HAVE_HDF5) && defined(WITH_MPI) && defined(HAVE_PARALLEL_HDF5)
/* MPI headers. */
#ifdef WITH_MPI
#include <mpi.h>
......@@ -32,15 +34,14 @@
#include "part.h"
#include "units.h"
#if defined(HAVE_HDF5) && defined(WITH_MPI) && defined(HAVE_PARALLEL_HDF5)
void read_ic_parallel(char* fileName, const struct unit_system* internal_units,
double dim[3], struct part** parts, struct gpart** gparts,
struct spart** sparts, size_t* Ngas, size_t* Ngparts,
size_t* Nsparts, int* periodic, int* flag_entropy,
int with_hydro, int with_gravity, int with_stars,
int mpi_rank, int mpi_size, MPI_Comm comm, MPI_Info info,
int nr_threads, int dry_run);
int cleanup_h, double h, int mpi_rank, int mpi_size,
MPI_Comm comm, MPI_Info info, int nr_threads,
int dry_run);
void write_output_parallel(struct engine* e, const char* baseName,
const struct unit_system* internal_units,
......
......@@ -119,7 +119,7 @@ void part_verify_links(struct part *parts, struct gpart *gparts,
if (gparts[k].type == swift_type_dark_matter) {
/* Check that it's not linked */
if (gparts[k].id_or_neg_offset < 0)
if (gparts[k].id_or_neg_offset <= 0)
error("DM gpart particle linked to something !");
}
......
......@@ -48,6 +48,7 @@
/* Local headers. */
#include "debug.h"
#include "engine.h"
#include "error.h"
#include "partition.h"
#include "restart.h"
......
......@@ -981,6 +981,7 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) {
const struct engine *e = r->e;
const struct cosmology *cosmo = e->cosmology;
const struct hydro_props *hydro_props = e->hydro_properties;
const int with_cosmology = (e->policy & engine_policy_cosmology);
struct part *restrict parts = c->parts;
struct xpart *restrict xparts = c->xparts;
......@@ -1044,8 +1045,8 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) {
}
/* do the kick */
kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm, ti_begin,
ti_begin + ti_step / 2);
kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm, cosmo,
hydro_props, ti_begin, ti_begin + ti_step / 2);
/* Update the accelerations to be used in the drift for hydro */
if (p->gpart != NULL) {
......@@ -1150,6 +1151,7 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) {
const struct engine *e = r->e;
const struct cosmology *cosmo = e->cosmology;
const struct hydro_props *hydro_props = e->hydro_properties;
const int with_cosmology = (e->policy & engine_policy_cosmology);
const int count = c->count;
const int gcount = c->gcount;
......@@ -1209,8 +1211,8 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) {
}
/* Finish the time-step with a second half-kick */
kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm,
ti_begin + ti_step / 2, ti_begin + ti_step);
kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm, cosmo,
hydro_props, ti_begin + ti_step / 2, ti_begin + ti_step);
#ifdef SWIFT_DEBUG_CHECKS
/* Check that kick and the drift are synchronized */
......
......@@ -466,7 +466,6 @@ static INLINE void runner_dopair_grav_pp(struct runner *r, struct cell *ci,
struct space *s = e->s;
const int periodic = s->periodic;
const double cell_width = s->width[0];
const float theta_crit2 = e->gravity_properties->theta_crit2;
const double a_smooth = e->gravity_properties->a_smooth;
const double r_cut_min = e->gravity_properties->r_cut_min;
const double rlr = cell_width * a_smooth;
......@@ -532,11 +531,11 @@ static INLINE void runner_dopair_grav_pp(struct runner *r, struct cell *ci,
/* Fill the caches */
gravity_cache_populate(e->max_active_bin, ci_cache, ci->gparts, gcount_i,
gcount_padded_i, shift_i, CoM_j, rmax2_j, theta_crit2,
ci);
gcount_padded_i, shift_i, CoM_j, rmax2_j, ci,
e->gravity_properties);
gravity_cache_populate(e->max_active_bin, cj_cache, cj->gparts, gcount_j,
gcount_padded_j, shift_j, CoM_i, rmax2_i, theta_crit2,
cj);
gcount_padded_j, shift_j, CoM_i, rmax2_i, cj,
e->gravity_properties);
/* Can we use the Newtonian version or do we need the truncated one ? */
if (!periodic) {
......@@ -675,7 +674,7 @@ static INLINE void runner_doself_grav_pp_full(struct runner *r,
const int gcount_padded = gcount - (gcount % VEC_SIZE) + VEC_SIZE;
gravity_cache_populate_no_mpole(e->max_active_bin, ci_cache, gparts, gcount,
gcount_padded, loc, c);
gcount_padded, loc, c, e->gravity_properties);
/* Ok... Here we go ! */
......@@ -805,7 +804,7 @@ static INLINE void runner_doself_grav_pp_truncated(struct runner *r,
const int gcount_padded = gcount - (gcount % VEC_SIZE) + VEC_SIZE;
gravity_cache_populate_no_mpole(e->max_active_bin, ci_cache, gparts, gcount,
gcount_padded, loc, c);
gcount_padded, loc, c, e->gravity_properties);
/* Ok... Here we go ! */
......
......@@ -1689,7 +1689,7 @@ void runner_dopair_subset_density_vec(struct runner *r,
struct cell *restrict cj, const int sid,
const int flipped, const double *shift) {
#ifdef WITH_VECTORIZATION
#if defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
TIMER_TIC;
......
......@@ -1435,7 +1435,8 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) {
switch (t->type) {
case task_type_self:
case task_type_sub_self:
if (t->subtype == task_subtype_grav || t->subtype == task_subtype_external_grav)
if (t->subtype == task_subtype_grav ||
t->subtype == task_subtype_external_grav)
qid = t->ci->super_gravity->owner;
else
qid = t->ci->super_hydro->owner;
......
......@@ -67,6 +67,8 @@
* @param offset The offset position where this rank starts reading.
* @param internal_units The #unit_system used internally
* @param ic_units The #unit_system used in the ICs
* @param cleanup_h Are we removing h-factors from the ICs?
* @param h The value of the reduced Hubble constant to use for cleaning.
*
* @todo A better version using HDF5 hyper-slabs to read the file directly into
* the part array will be written once the structures have been stabilized.
......@@ -74,7 +76,7 @@
void readArray(hid_t grp, const struct io_props props, size_t N,
long long N_total, long long offset,
const struct unit_system* internal_units,
const struct unit_system* ic_units) {
const struct unit_system* ic_units, int cleanup_h, double h) {
const size_t typeSize = io_sizeof_type(props.type);
const size_t copySize = typeSize * props.dimension;
......@@ -161,6 +163,23 @@ void readArray(hid_t grp, const struct io_props props, size_t N,
}
}
/* Clean-up h if necessary */
const float h_factor_exp = units_h_factor(internal_units, props.units);
if (cleanup_h && h_factor_exp != 0.f && exist != 0) {
const double h_factor = pow(h, h_factor_exp);
/* message("Multipltying '%s' by h^%f=%f", props.name, h_factor_exp,
* h_factor); */
if (io_is_double_precision(props.type)) {
double* temp_d = (double*)temp;
for (size_t i = 0; i < num_elements; ++i) temp_d[i] *= h_factor;
} else {
float* temp_f = (float*)temp;
for (size_t i = 0; i < num_elements; ++i) temp_f[i] *= h_factor;
}
}
/* Copy temporary buffer to particle data */
char* temp_c = temp;
for (size_t i = 0; i < N; ++i)
......@@ -256,8 +275,7 @@ void prepareArray(const struct engine* e, hid_t grp, char* fileName,
io_write_attribute_d(
h_data, "CGS conversion factor",
units_cgs_conversion_factor(snapshot_units, props.units));
io_write_attribute_f(h_data, "h-scale exponent",
units_h_factor(snapshot_units, props.units));
io_write_attribute_f(h_data, "h-scale exponent", 0);
io_write_attribute_f(h_data, "a-scale exponent",
units_a_factor(snapshot_units, props.units));
io_write_attribute_s(h_data, "Conversion factor", buffer);
......@@ -382,6 +400,8 @@ void writeArray(const struct engine* e, hid_t grp, char* fileName,
* @param with_hydro Are we reading gas particles ?
* @param with_gravity Are we reading/creating #gpart arrays ?
* @param with_stars Are we reading star particles ?
* @param cleanup_h Are we cleaning-up h-factors from the quantities we read?
* @param h The value of the reduced Hubble constant to use for correction.
* @param mpi_rank The MPI rank of this node
* @param mpi_size The number of MPI ranks
* @param comm The MPI communicator
......@@ -402,8 +422,8 @@ void read_ic_serial(char* fileName, const struct unit_system* internal_units,
struct spart** sparts, size_t* Ngas, size_t* Ngparts,
size_t* Nstars, int* periodic, int* flag_entropy,
int with_hydro, int with_gravity, int with_stars,
int mpi_rank, int mpi_size, MPI_Comm comm, MPI_Info info,
int n_threads, int dry_run) {
int cleanup_h, double h, int mpi_rank, int mpi_size,
MPI_Comm comm, MPI_Info info, int n_threads, int dry_run) {
hid_t h_file = 0, h_grp = 0;
/* GADGET has only cubic boxes (in cosmological mode) */
......@@ -476,6 +496,13 @@ void read_ic_serial(char* fileName, const struct unit_system* internal_units,
else if (hydro_dimension == 1)
dim[2] = dim[1] = dim[0];
/* Convert the box size if we want to clean-up h-factors */
if (cleanup_h) {
dim[0] /= h;
dim[1] /= h;
dim[2] /= h;
}
/* message("Found %lld particles in a %speriodic box of size [%f %f %f].",
*/