diff --git a/examples/main.c b/examples/main.c index 0dafea744f4250c71d5ac1b28d4a465fe42e0690..7ca517090f96d2cd8e0f315188864695c8788d3c 100644 --- a/examples/main.c +++ b/examples/main.c @@ -482,7 +482,6 @@ int main(int argc, char *argv[]) { MPI_Bcast(output_fields, sizeof(struct swift_params), MPI_BYTE, 0, MPI_COMM_WORLD); #endif - /* Check that we can write the snapshots by testing if the output * directory exists and is searchable and writable. */ char basename[PARSER_MAX_LINE_SIZE]; @@ -837,6 +836,10 @@ int main(int argc, char *argv[]) { &cooling_func, &chemistry, &sourceterms); engine_config(0, &e, params, nr_nodes, myrank, nr_threads, with_aff, talking, restart_file); + + /* check output field */ + io_check_output_fields(output_fields, &e); + if (myrank == 0) { clocks_gettime(&toc); message("engine_init took %.3f %s.", clocks_diff(&tic, &toc), @@ -871,6 +874,7 @@ int main(int argc, char *argv[]) { message("Time integration ready to start. End of dry-run."); engine_clean(&e); free(params); + free(output_fields); return 0; } @@ -1093,6 +1097,7 @@ int main(int argc, char *argv[]) { if (with_verbose_timers) timers_close_file(); if (with_cosmology) cosmology_clean(&cosmo); engine_clean(&e); + free(output_fields); free(params); /* Say goodbye. */ diff --git a/examples/output_fields_example.yml b/examples/output_fields_example.yml index 9dabdac217fe93054e1191aaf19f2fd81a97b142..22dfdc35a91efeabdc96fbdcb92dfa65fbc191b8 100644 --- a/examples/output_fields_example.yml +++ b/examples/output_fields_example.yml @@ -3,7 +3,7 @@ PartType0: Coordinates: 1 # Request to write output Masses: 1 Velocities: 1 - SmoothingLenght: 1 + SmoothingLength: 1 Entropy: 1 ParticleIDs: 1 Density: 1 diff --git a/src/chemistry/none/chemistry_io.h b/src/chemistry/none/chemistry_io.h index 142d2f75ce1487393e8689edbb9a6fdb1b1e85cd..fc460944ec5244ecdeda5b363a2c6c9a964c001a 100644 --- a/src/chemistry/none/chemistry_io.h +++ b/src/chemistry/none/chemistry_io.h @@ -29,7 +29,8 @@ * * @return Returns the number of fields to write. */ -int chemistry_read_particles(struct part* parts, struct io_props* list) { +__attribute__((always_inline)) INLINE static int chemistry_read_particles( + struct part* parts, struct io_props* list) { /* update list according to hydro_io */ @@ -45,7 +46,8 @@ int chemistry_read_particles(struct part* parts, struct io_props* list) { * * @return Returns the number of fields to write. */ -int chemistry_write_particles(const struct part* parts, struct io_props* list) { +__attribute__((always_inline)) INLINE static int chemistry_write_particles( + const struct part* parts, struct io_props* list) { /* update list according to hydro_io */ @@ -59,7 +61,8 @@ int chemistry_write_particles(const struct part* parts, struct io_props* list) { * @brief Writes the current model of SPH to the file * @param h_grp The HDF5 group in which to write */ -void chemistry_write_flavour(hid_t h_grp) { +__attribute__((always_inline)) INLINE static void chemistry_write_flavour( + hid_t h_grp) { io_write_attribute_s(h_grp, "Chemistry Model", "None"); } diff --git a/src/common_io.c b/src/common_io.c index 8b173adb7b5e5a014b0967b4fd04aef5ee6606e9..f17ade1aab427d2a6eb7b3fe945f9ceeb96746a7 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -25,12 +25,16 @@ #include "common_io.h" /* Local includes. */ +#include "chemistry_io.h" #include "engine.h" #include "error.h" +#include "gravity_io.h" #include "hydro.h" +#include "hydro_io.h" #include "io_properties.h" #include "kernel_hydro.h" #include "part.h" +#include "stars_io.h" #include "threadpool.h" #include "units.h" #include "version.h" @@ -805,3 +809,86 @@ void io_collect_dm_gparts(const struct gpart* const gparts, size_t Ntot, error("Collected the wrong number of dm particles (%zu vs. %zu expected)", count, Ndm); } + +/** + * @brief Verify the io parameter file + * + * @param e The #engine + */ +void io_check_output_fields(const struct swift_params *output_fields, + const struct engine *e) { + + if (output_fields->paramCount == 0) + error("You need to provide an output field in %s", output_fields->fileName); + + /* particles */ + 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; + + /* number of particles */ + const size_t Ngas = e->s->nr_parts; + const size_t Nstars = e->s->nr_sparts; + const size_t Ntot = e->s->nr_gparts; + + const size_t Ndm = Ntot > 0 ? Ntot - (Ngas + Nstars) : 0; + + long long N_total[swift_type_count] = { + (long long)Ngas, (long long)Ndm, 0, 0, (long long)Nstars, 0}; + + + /* get all the possible outputs */ + for (int ptype = 0; ptype < swift_type_count; ptype++) { + int num_fields = 0; + struct io_props list[100]; + + /* Don't do anything if no particle of this kind */ + if (N_total[ptype] == 0) continue; + + /* Write particle fields from the particle structure */ + switch (ptype) { + + case swift_type_gas: + hydro_write_particles(parts, xparts, list, &num_fields); + num_fields += chemistry_write_particles(parts, list + num_fields); + break; + + case swift_type_dark_matter: + darkmatter_write_particles(gparts, list, &num_fields); + break; + + case swift_type_star: + star_write_particles(sparts, list, &num_fields); + break; + + default: + error("Particle Type %d not yet supported. Aborting", ptype); + } + /* loop over each parameter */ + for (int param_id = 0; param_id < output_fields->paramCount; param_id++) { + const char *param_name = output_fields->data[param_id].name; + + /* skip if wrong part type */ + char section_name[200]; + sprintf(section_name, "PartType%i", ptype); + if (strstr(param_name, section_name) == NULL) + continue; + + int found = 0; + + /* loop over each possible output field */ + for (int field_id = 0; field_id < num_fields; field_id++) { + char field_name[200]; + sprintf(field_name, "PartType%i:%s", ptype, list[field_id].name); + if (strcmp(param_name, field_name) == 0) { + found = 1; + continue; + } + } + if (!found) + error("Unable to find field corresponding to %s", param_name); + } + } + +} diff --git a/src/common_io.h b/src/common_io.h index d9e676db934b58ee476f18894acf55c4d38344f9..0aba3be1e0fa6ba5ccacd836917905bedf5b4e36 100644 --- a/src/common_io.h +++ b/src/common_io.h @@ -100,4 +100,7 @@ void io_duplicate_star_gparts(struct threadpool* tp, struct spart* const sparts, struct gpart* const gparts, size_t Nstars, size_t Ndm); +void io_check_output_fields(const struct swift_params *output_fields, + const struct engine *e); + #endif /* SWIFT_COMMON_IO_H */ diff --git a/src/gravity/Default/gravity_io.h b/src/gravity/Default/gravity_io.h index a3f151510b001c3ab34dd360475ac9d28bc9f9a4..d69310f2fc5e8d689659ffedaaea855a4731a11e 100644 --- a/src/gravity/Default/gravity_io.h +++ b/src/gravity/Default/gravity_io.h @@ -21,8 +21,8 @@ #include "io_properties.h" -void convert_gpart_pos(const struct engine* e, const struct gpart* gp, - double* ret) { +__attribute__((always_inline)) INLINE static void convert_gpart_pos( + const struct engine* e, const struct gpart* gp, double* ret) { if (e->s->periodic) { ret[0] = box_wrap(gp->x[0], 0.0, e->s->dim[0]); @@ -35,8 +35,8 @@ void convert_gpart_pos(const struct engine* e, const struct gpart* gp, } } -void convert_gpart_vel(const struct engine* e, const struct gpart* gp, - float* ret) { +__attribute__((always_inline)) INLINE static void convert_gpart_vel( + const struct engine* e, const struct gpart* gp, float* ret) { const int with_cosmology = (e->policy & engine_policy_cosmology); const struct cosmology* cosmo = e->cosmology; @@ -74,8 +74,8 @@ void convert_gpart_vel(const struct engine* e, const struct gpart* gp, * @param list The list of i/o properties to read. * @param num_fields The number of i/o fields to read. */ -void darkmatter_read_particles(struct gpart* gparts, struct io_props* list, - int* num_fields) { +__attribute__((always_inline)) INLINE static void darkmatter_read_particles( + struct gpart* gparts, struct io_props* list, int* num_fields) { /* Say how much we want to read */ *num_fields = 4; @@ -98,8 +98,8 @@ void darkmatter_read_particles(struct gpart* gparts, struct io_props* list, * @param list The list of i/o properties to write. * @param num_fields The number of i/o fields to write. */ -void darkmatter_write_particles(const struct gpart* gparts, - struct io_props* list, int* num_fields) { +__attribute__((always_inline)) INLINE static void darkmatter_write_particles( + const struct gpart* gparts, struct io_props* list, int* num_fields) { /* Say how much we want to write */ *num_fields = 5; diff --git a/src/hydro/Gadget2/hydro_io.h b/src/hydro/Gadget2/hydro_io.h index d2371624476d68f203e1ca27399a2a4c6bd2d80b..3ed358ebb17bbb026bd2b8249755d1c76a023c0c 100644 --- a/src/hydro/Gadget2/hydro_io.h +++ b/src/hydro/Gadget2/hydro_io.h @@ -31,8 +31,8 @@ * @param list The list of i/o properties to read. * @param num_fields The number of i/o fields to read. */ -void hydro_read_particles(struct part* parts, struct io_props* list, - int* num_fields) { +__attribute__((always_inline)) INLINE static void hydro_read_particles( + struct part* parts, struct io_props* list, int* num_fields) { *num_fields = 8; @@ -55,20 +55,23 @@ void hydro_read_particles(struct part* parts, struct io_props* list, UNIT_CONV_DENSITY, parts, rho); } -void convert_part_u(const struct engine* e, const struct part* p, - const struct xpart* xp, float* ret) { +__attribute__((always_inline)) INLINE static void convert_part_u( + const struct engine* e, const struct part* p, + const struct xpart* xp, float* ret) { ret[0] = hydro_get_comoving_internal_energy(p); } -void convert_part_P(const struct engine* e, const struct part* p, - const struct xpart* xp, float* ret) { +__attribute__((always_inline)) INLINE static void convert_part_P( + const struct engine* e, const struct part* p, + const struct xpart* xp, float* ret) { ret[0] = hydro_get_comoving_pressure(p); } -void convert_part_pos(const struct engine* e, const struct part* p, - const struct xpart* xp, double* ret) { +__attribute__((always_inline)) INLINE static void convert_part_pos( + const struct engine* e, const struct part* p, + const struct xpart* xp, double* ret) { if (e->s->periodic) { ret[0] = box_wrap(p->x[0], 0.0, e->s->dim[0]); @@ -81,8 +84,9 @@ void convert_part_pos(const struct engine* e, const struct part* p, } } -void convert_part_vel(const struct engine* e, const struct part* p, - const struct xpart* xp, float* ret) { +__attribute__((always_inline)) INLINE static void convert_part_vel( + const struct engine* e, const struct part* p, + const struct xpart* xp, float* ret) { const int with_cosmology = (e->policy & engine_policy_cosmology); const struct cosmology* cosmo = e->cosmology; @@ -115,8 +119,9 @@ void convert_part_vel(const struct engine* e, const struct part* p, ret[2] *= cosmo->a2_inv; } -void convert_part_potential(const struct engine* e, const struct part* p, - const struct xpart* xp, float* ret) { +__attribute__((always_inline)) INLINE static void convert_part_potential( + const struct engine* e, const struct part* p, + const struct xpart* xp, float* ret) { if (p->gpart != NULL) ret[0] = gravity_get_comoving_potential(p->gpart); @@ -131,8 +136,9 @@ void convert_part_potential(const struct engine* e, const struct part* p, * @param list The list of i/o properties to write. * @param num_fields The number of i/o fields to write. */ -void hydro_write_particles(const struct part* parts, const struct xpart* xparts, - struct io_props* list, int* num_fields) { +__attribute__((always_inline)) INLINE static void hydro_write_particles( + const struct part* parts, const struct xpart* xparts, + struct io_props* list, int* num_fields) { *num_fields = 10; @@ -187,7 +193,7 @@ void hydro_write_particles(const struct part* parts, const struct xpart* xparts, * @brief Writes the current model of SPH to the file * @param h_grpsph The HDF5 group in which to write */ -void hydro_write_flavour(hid_t h_grpsph) { +__attribute__((always_inline)) INLINE static void hydro_write_flavour(hid_t h_grpsph) { /* Viscosity and thermal conduction */ io_write_attribute_s(h_grpsph, "Thermal Conductivity Model", @@ -204,6 +210,9 @@ void hydro_write_flavour(hid_t h_grpsph) { * * @return 1 if entropy is in 'internal energy', 0 otherwise. */ -int writeEntropyFlag(void) { return 0; } +__attribute__((always_inline)) INLINE static int writeEntropyFlag(void) { + return 0; +} +>>>>>>> Check if all parameters in output_fields are correct #endif /* SWIFT_GADGET2_HYDRO_IO_H */ diff --git a/src/stars/Default/star_io.h b/src/stars/Default/star_io.h index e465d8c247c5fab0e448f9c4664f5a02b9490f05..9989130539b45daa74f94ef38301058e202ed514 100644 --- a/src/stars/Default/star_io.h +++ b/src/stars/Default/star_io.h @@ -28,8 +28,8 @@ * @param list The list of i/o properties to read. * @param num_fields The number of i/o fields to read. */ -void star_read_particles(struct spart* sparts, struct io_props* list, - int* num_fields) { +__attribute__((always_inline)) INLINE static void star_read_particles( + struct spart* sparts, struct io_props* list, int* num_fields) { /* Say how much we want to read */ *num_fields = 4; @@ -52,8 +52,8 @@ void star_read_particles(struct spart* sparts, struct io_props* list, * @param list The list of i/o properties to write. * @param num_fields The number of i/o fields to write. */ -void star_write_particles(const struct spart* sparts, struct io_props* list, - int* num_fields) { +__attribute__((always_inline)) INLINE static void star_write_particles( + const struct spart* sparts, struct io_props* list, int* num_fields) { /* Say how much we want to read */ *num_fields = 4; diff --git a/src/swift.h b/src/swift.h index 7691720942f32d29d3269ccdd7adbe8db32280bf..10cc8495fd7cec7daf757831bfe2f12d0cc9f1f6 100644 --- a/src/swift.h +++ b/src/swift.h @@ -29,6 +29,7 @@ #include "cell.h" #include "chemistry.h" #include "clocks.h" +#include "common_io.h" #include "const.h" #include "cooling.h" #include "cosmology.h"