diff --git a/examples/main.c b/examples/main.c index 79d917690921e199832bfaa2cab8d896f7580777..c01c5494644eeb7c5603e99e63a09e0060887b92 100644 --- a/examples/main.c +++ b/examples/main.c @@ -840,6 +840,11 @@ int main(int argc, char *argv[]) { } else { + /* Verify that the fields to dump actually exist */ + if (myrank == 0) + io_check_output_fields(output_options, with_cosmology, with_fof, + with_structure_finding); + /* Not restarting so look for the ICs. */ /* Initialize unit system and constants */ units_init_from_params(&us, params, "InternalUnitSystem"); @@ -1158,11 +1163,6 @@ int main(int argc, char *argv[]) { N_total[swift_type_black_hole] = s.nr_bparts; #endif - /* Verify that the fields to dump actually exist - this must be done after - * space_init so we know whether or not we have gas particles. */ - if (myrank == 0) - io_check_output_fields(output_options, N_total, with_cosmology); - /* Say a few nice things about the space we just created. */ if (myrank == 0) { message("space dimensions are [ %.3f %.3f %.3f ].", s.dim[0], s.dim[1], diff --git a/src/common_io.c b/src/common_io.c index 4cf4c5c5bba6b59dd81563dcc3bd24dd30d214bf..a775db663822836e54de615067692b8207eb36f1 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -2278,12 +2278,11 @@ void io_collect_gparts_background_to_write( * * @param params The #swift_params instance corresponding to the select_output * file. - * @param N_total The total number of each particle type. * @param with_cosmolgy Ran with cosmology? */ void io_check_output_fields(struct output_options* output_options, - const long long N_total[swift_type_count], - const int with_cosmology) { + const int with_cosmology, const int with_fof, + const int with_stf) { const int MAX_NUM_PTYPE_FIELDS = 100; @@ -2295,8 +2294,8 @@ void io_check_output_fields(struct output_options* output_options, struct io_props field_list[swift_type_count][MAX_NUM_PTYPE_FIELDS]; for (int ptype = 0; ptype < swift_type_count; ptype++) - ptype_num_fields_total[ptype] = - get_ptype_fields(ptype, field_list[ptype], with_cosmology); + ptype_num_fields_total[ptype] = get_ptype_fields( + ptype, field_list[ptype], with_cosmology, with_fof, with_stf); /* Check for whether we have a `Default` section */ int have_default = 0; @@ -2377,7 +2376,10 @@ void io_check_output_fields(struct output_options* output_options, if (strcmp(param_name, field_name) == 0) break; } - if (field_id == ptype_num_fields_total[param_ptype]) + int param_is_known = 0; /* Update below if it is a known one */ + if (field_id < ptype_num_fields_total[param_ptype]) + param_is_known = 1; + else message( "WARNING: Trying to change behaviour of field '%s' (read from " "'%s') that does not exist. This may be because you are not " @@ -2385,32 +2387,34 @@ void io_check_output_fields(struct output_options* output_options, param_name, params->fileName); /* Perform a correctness check on the _value_ of the parameter */ - char field_value[FIELD_BUFFER_SIZE]; - parser_get_param_string(params, field_name, field_value); + char param_value[FIELD_BUFFER_SIZE]; + parser_get_param_string(params, param_name, param_value); int value_id = 0; for (value_id = 0; value_id < compression_level_count; value_id++) - if (strcmp(field_value, compression_level_names[value_id]) == 0) break; + if (strcmp(param_value, compression_level_names[value_id]) == 0) break; if (value_id == compression_level_count) error("Choice of output selection parameter %s ('%s') is invalid.", - field_name, field_value); + param_name, param_value); /* Adjust number of fields to be written for param_ptype, if this field's - * status is different from default */ - const int is_on = - strcmp(field_value, - compression_level_names[compression_do_not_write]) != 0; - - if (is_on && !ptype_default_write_status[param_ptype]) { - /* Particle should be written even though default is off: - * increase field count */ - ptype_num_fields_to_write[param_ptype] += 1; - } - if (!is_on && ptype_default_write_status[param_ptype]) { - /* Particle should not be written, even though default is on: - * decrease field count */ - ptype_num_fields_to_write[param_ptype] -= 1; + * status is different from default and it is a known one. */ + if (param_is_known) { + const int is_on = + strcmp(param_value, + compression_level_names[compression_do_not_write]) != 0; + + if (is_on && !ptype_default_write_status[param_ptype]) { + /* Particle should be written even though default is off: + * increase field count */ + ptype_num_fields_to_write[param_ptype] += 1; + } + if (!is_on && ptype_default_write_status[param_ptype]) { + /* Particle should not be written, even though default is on: + * decrease field count */ + ptype_num_fields_to_write[param_ptype] -= 1; + } } } /* ends loop over parameters */ @@ -2459,7 +2463,8 @@ void io_write_output_field_parameter(const char* filename, int with_cosmology) { for (int ptype = 0; ptype < swift_type_count; ptype++) { struct io_props list[100]; - int num_fields = get_ptype_fields(ptype, list, with_cosmology); + int num_fields = get_ptype_fields(ptype, list, with_cosmology, + /*with_fof=*/1, /*with_stf=*/1); if (num_fields == 0) continue; @@ -2566,11 +2571,14 @@ void io_get_snapshot_filename(char filename[1024], char xmf_filename[1024], * @param ptype The index of the particle type under consideration. * @param list An io_props list that will hold the individual fields. * @param with_cosmology Use cosmological name variant? + * @param with_fof Include FoF related fields? + * @param with_stf Include STF related fields? * * @return The total number of fields that can be written for the ptype. */ int get_ptype_fields(const int ptype, struct io_props* list, - const int with_cosmology) { + const int with_cosmology, const int with_fof, + const int with_stf) { int num_fields = 0; @@ -2585,20 +2593,24 @@ int get_ptype_fields(const int ptype, struct io_props* list, with_cosmology); num_fields += star_formation_write_particles(NULL, NULL, list + num_fields); - num_fields += fof_write_parts(NULL, NULL, list + num_fields); - num_fields += velociraptor_write_parts(NULL, NULL, list + num_fields); + if (with_fof) + num_fields += fof_write_parts(NULL, NULL, list + num_fields); + if (with_stf) + num_fields += velociraptor_write_parts(NULL, NULL, list + num_fields); break; case swift_type_dark_matter: darkmatter_write_particles(NULL, list, &num_fields); - num_fields += fof_write_gparts(NULL, list + num_fields); - num_fields += velociraptor_write_gparts(NULL, list + num_fields); + if (with_fof) num_fields += fof_write_gparts(NULL, list + num_fields); + if (with_stf) + num_fields += velociraptor_write_gparts(NULL, list + num_fields); break; case swift_type_dark_matter_background: darkmatter_write_particles(NULL, list, &num_fields); - num_fields += fof_write_gparts(NULL, list + num_fields); - num_fields += velociraptor_write_gparts(NULL, list + num_fields); + if (with_fof) num_fields += fof_write_gparts(NULL, list + num_fields); + if (with_stf) + num_fields += velociraptor_write_gparts(NULL, list + num_fields); break; case 3: @@ -2610,15 +2622,17 @@ int get_ptype_fields(const int ptype, struct io_props* list, num_fields += tracers_write_sparticles(NULL, list + num_fields, with_cosmology); num_fields += star_formation_write_sparticles(NULL, list + num_fields); - num_fields += fof_write_sparts(NULL, list + num_fields); - num_fields += velociraptor_write_sparts(NULL, list + num_fields); + if (with_fof) num_fields += fof_write_sparts(NULL, list + num_fields); + if (with_stf) + num_fields += velociraptor_write_sparts(NULL, list + num_fields); break; case swift_type_black_hole: black_holes_write_particles(NULL, list, &num_fields, with_cosmology); num_fields += chemistry_write_bparticles(NULL, list + num_fields); - num_fields += fof_write_bparts(NULL, list + num_fields); - num_fields += velociraptor_write_bparts(NULL, list + num_fields); + if (with_fof) num_fields += fof_write_bparts(NULL, list + num_fields); + if (with_stf) + num_fields += velociraptor_write_bparts(NULL, list + num_fields); break; default: diff --git a/src/common_io.h b/src/common_io.h index 2fe5db82cbe2d701dd2d777286e8072593a0c666..3677ae556e7ff5dba13b0a134293f5b77f68f405 100644 --- a/src/common_io.h +++ b/src/common_io.h @@ -173,8 +173,8 @@ void io_duplicate_black_holes_gparts(struct threadpool* tp, size_t Ndm); void io_check_output_fields(struct output_options* output_options, - const long long N_total[swift_type_count], - const int with_cosmology); + const int with_cosmology, const int with_fof, + const int with_stf); void io_write_output_field_parameter(const char* filename, int with_cosmology); @@ -187,7 +187,8 @@ void io_get_snapshot_filename(char filename[1024], char xmf_filename[1024], const char* subdir, const char* basename); int get_ptype_fields(const int ptype, struct io_props* list, - const int with_cosmology); + const int with_cosmology, const int with_fof, + const int with_stf); int get_param_ptype(const char* name); #endif /* SWIFT_COMMON_IO_H */ diff --git a/src/distributed_io.c b/src/distributed_io.c index 56d5b2731a38d7364cd5bcd08c377292a2177984..b2789f219f8360198a909bde1255481f42cac8c0 100644 --- a/src/distributed_io.c +++ b/src/distributed_io.c @@ -460,7 +460,6 @@ void write_output_distributed(struct engine* e, /* Write the number of particles as an attribute */ io_write_attribute_l(h_grp, "NumberOfParticles", N[ptype]); - io_write_attribute_i(h_grp, "NumberOfFields", numFields[ptype]); int num_fields = 0; struct io_props list[100]; @@ -748,11 +747,9 @@ void write_output_distributed(struct engine* e, num_fields_written++; } } -#ifdef SWIFT_DEBUG_CHECKS - if (num_fields_written != numFields[ptype]) - error("Wrote %d fields for particle type %s, but expected to write %d.", - num_fields_written, part_type_names[ptype], numFields[ptype]); -#endif + + /* Only write this now that we know exactly how many fields there are. */ + io_write_attribute_i(h_grp, "NumberOfFields", num_fields_written); /* Free temporary arrays */ if (parts_written) swift_free("parts_written", parts_written); diff --git a/src/parallel_io.c b/src/parallel_io.c index 0a90921848005389d66de7f5cfa14e124232c4f5..9ca4a6eaf44b191475bb54269247e507d5ae2125 100644 --- a/src/parallel_io.c +++ b/src/parallel_io.c @@ -1184,7 +1184,6 @@ void prepare_file(struct engine* e, const char* fileName, /* Write the number of particles as an attribute */ io_write_attribute_l(h_grp, "NumberOfParticles", N_total[ptype]); - io_write_attribute_i(h_grp, "NumberOfFields", numFields[ptype]); int num_fields = 0; struct io_props list[100]; @@ -1286,11 +1285,9 @@ void prepare_file(struct engine* e, const char* fileName, num_fields_written++; } } -#ifdef SWIFT_DEBUG_CHECKS - if (num_fields_written != numFields[ptype]) - error("Wrote %d fields for particle type %s, but expected to write %d.", - num_fields_written, part_type_names[ptype], numFields[ptype]); -#endif + + /* Only write this now that we know exactly how many fields there are. */ + io_write_attribute_i(h_grp, "NumberOfFields", num_fields_written); /* Close particle group */ H5Gclose(h_grp); diff --git a/src/serial_io.c b/src/serial_io.c index cf7280248de45782987fc4fa84ce9b4ec887d480..8dcbcb56b8a61e799a49f13deaa3ac9af16cd6af 100644 --- a/src/serial_io.c +++ b/src/serial_io.c @@ -1061,7 +1061,6 @@ void write_output_serial(struct engine* e, /* Write the number of particles as an attribute */ io_write_attribute_l(h_grp, "NumberOfParticles", N_total[ptype]); - io_write_attribute_i(h_grp, "NumberOfFields", numFields[ptype]); /* Close particle group */ H5Gclose(h_grp); @@ -1433,12 +1432,12 @@ void write_output_serial(struct engine* e, num_fields_written++; } } -#ifdef SWIFT_DEBUG_CHECKS - if (num_fields_written != numFields[ptype]) - error( - "Wrote %d fields for particle type %s, but expected to write %d.", - num_fields_written, part_type_names[ptype], numFields[ptype]); -#endif + + if (mpi_rank == 0) { + /* Only write this now that we know exactly how many fields there are. + */ + io_write_attribute_i(h_grp, "NumberOfFields", num_fields_written); + } /* Free temporary array */ if (parts_written) swift_free("parts_written", parts_written); diff --git a/src/single_io.c b/src/single_io.c index f69db4ff86d4fcb6b630d103ce00933124b21764..3086547fd8edbb8f8278157a8f3e24208ece2bc5 100644 --- a/src/single_io.c +++ b/src/single_io.c @@ -921,7 +921,6 @@ void write_output_single(struct engine* e, /* Write the number of particles and fields as an attribute */ io_write_attribute_l(h_grp, "NumberOfParticles", numParticles[ptype]); - io_write_attribute_i(h_grp, "NumberOfFields", numFields[ptype]); int num_fields = 0; struct io_props list[100]; @@ -1213,11 +1212,9 @@ void write_output_single(struct engine* e, num_fields_written++; } } -#ifdef SWIFT_DEBUG_CHECKS - if (num_fields_written != numFields[ptype]) - error("Wrote %d fields for particle type %s, but expected to write %d.", - num_fields_written, part_type_names[ptype], numFields[ptype]); -#endif + + /* Only write this now that we know exactly how many fields there are. */ + io_write_attribute_i(h_grp, "NumberOfFields", num_fields_written); /* Free temporary arrays */ if (parts_written) swift_free("parts_written", parts_written); diff --git a/tests/testSelectOutput.c b/tests/testSelectOutput.c index cab98275e5e50e0456e144a71c2309ebe0c9f5d7..d84e42812a9c2a8926c6d3a19c3a344baa21a618 100644 --- a/tests/testSelectOutput.c +++ b/tests/testSelectOutput.c @@ -159,9 +159,8 @@ int main(int argc, char *argv[]) { /* check output selection */ message("Checking output parameters."); - long long N_total[swift_type_count] = { - (long long)Ngas, (long long)Ngpart, 0, 0, (long long)Nspart, 0}; - io_check_output_fields(&output_options, N_total, /*with_cosmology=*/0); + io_check_output_fields(&output_options, /*with_cosmology=*/0, /*with_fof=*/0, + /*with_structure_finding=*/0); /* write output file */ message("Writing output.");