diff --git a/examples/main.c b/examples/main.c index b3577b0e2adec7650bb6acd73b128552071f47d8..2c78d6b1aab0d6fbad630266a4762957a7810bda 100644 --- a/examples/main.c +++ b/examples/main.c @@ -861,7 +861,7 @@ int main(int argc, char *argv[]) { fflush(stdout); /* Get ready to read particles of all kinds */ - size_t Ngas = 0, Ngpart = 0, Nspart = 0, Nbpart = 0; + size_t Ngas = 0, Ngpart = 0, Ngpart_background = 0, Nspart = 0, Nbpart = 0; double dim[3] = {0., 0., 0.}; if (myrank == 0) clocks_gettime(&tic); #if defined(HAVE_HDF5) @@ -883,10 +883,11 @@ int main(int argc, char *argv[]) { #endif #else read_ic_single(ICfileName, &us, dim, &parts, &gparts, &sparts, &bparts, - &Ngas, &Ngpart, &Nspart, &Nbpart, &flag_entropy_ICs, - with_hydro, (with_external_gravity || with_self_gravity), - with_stars, with_black_holes, cleanup_h, cleanup_sqrt_a, - cosmo.h, cosmo.a, nr_threads, dry_run); + &Ngas, &Ngpart, &Ngpart_background, &Nspart, &Nbpart, + &flag_entropy_ICs, with_hydro, + (with_external_gravity || with_self_gravity), with_stars, + with_black_holes, cleanup_h, cleanup_sqrt_a, cosmo.h, + cosmo.a, nr_threads, dry_run); #endif #endif if (myrank == 0) { @@ -918,23 +919,35 @@ int main(int argc, char *argv[]) { #endif /* Get the total number of particles across all nodes. */ - long long N_total[4] = {0, 0, 0, 0}; + long long N_total[swift_type_count + 1] = {0}; + const long long Nbaryons = Ngas + Nspart + Nbpart; #if defined(WITH_MPI) - long long N_long[4] = {Ngas, Ngpart, Nspart, Nbpart}; - MPI_Allreduce(&N_long, &N_total, 4, MPI_LONG_LONG_INT, MPI_SUM, - MPI_COMM_WORLD); + long long N_long[swift_type_count + 1] = {0}; + N_long[swift_type_gas] = Ngas; + N_long[swift_type_dark_matter] = Ngpart - Ngpart_background - Nbaryons; + N_long[swift_type_dark_matter_background] = Ngpart_background; + N_long[swift_type_stars] = Nspart; + N_long[swift_type_black_hole] = Nbpart; + N_long[swift_type_count] = Ngpart; + MPI_Allreduce(&N_long, &N_total, swift_type_count + 1, MPI_LONG_LONG_INT, + MPI_SUM, MPI_COMM_WORLD); #else - N_total[0] = Ngas; - N_total[1] = Ngpart; - N_total[2] = Nspart; - N_total[3] = Nbpart; + N_total[swift_type_gas] = Ngas; + N_total[swift_type_dark_matter] = Ngpart - Ngpart_background - Nbaryons; + N_total[swift_type_dark_matter_background] = Ngpart_background; + N_total[swift_type_stars] = Nspart; + N_total[swift_type_black_hole] = Nbpart; + N_total[swift_type_count] = Ngpart; #endif if (myrank == 0) message( "Read %lld gas particles, %lld stars particles, %lld black hole " - "particles and %lld gparts from the ICs.", - N_total[0], N_total[2], N_total[3], N_total[1]); + "particles, %lld DM particles and %lld DM background particles from " + "the ICs.", + N_total[swift_type_gas], N_total[swift_type_stars], + N_total[swift_type_black_hole], N_total[swift_type_dark_matter], + N_total[swift_type_dark_matter_background]); /* Verify that the fields to dump actually exist */ if (myrank == 0) io_check_output_fields(params, N_total); diff --git a/src/common_io.c b/src/common_io.c index 945badd14cb814e5c06c5e0edf2b983669259850..88d67d4785f248e9a71cc8b9eef3139663ab8386 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -24,13 +24,11 @@ /* This object's header. */ #include "common_io.h" -/* First common header */ -#include "engine.h" - /* Local includes. */ #include "black_holes_io.h" #include "chemistry_io.h" #include "cooling_io.h" +#include "engine.h" #include "error.h" #include "fof_io.h" #include "gravity_io.h" @@ -1551,6 +1549,42 @@ void io_prepare_dm_gparts(struct threadpool* tp, struct gpart* const gparts, sizeof(struct gpart), 0, NULL); } +void io_prepare_dm_background_gparts_mapper(void* restrict data, int Ndm, + void* dummy) { + + struct gpart* restrict gparts = (struct gpart*)data; + + /* Let's give all these gparts a negative id */ + for (int i = 0; i < Ndm; ++i) { + + /* Negative ids are not allowed */ + if (gparts[i].id_or_neg_offset < 0) + error("Negative ID for DM particle %i: ID=%lld", i, + gparts[i].id_or_neg_offset); + + /* Set gpart type */ + gparts[i].type = swift_type_dark_matter_background; + } +} + +/** + * @brief Prepare the DM backgorund particles (in gparts) read in + * for the addition of the other particle types + * + * This function assumes that the DM particles are all at the start of the + * gparts array and that the background particles directly follow them. + * + * @param tp The current #threadpool. + * @param gparts The array of #gpart freshly read in. + * @param Ndm The number of DM particles read in. + */ +void io_prepare_dm_background_gparts(struct threadpool* tp, + struct gpart* const gparts, size_t Ndm) { + + threadpool_map(tp, io_prepare_dm_background_gparts_mapper, gparts, Ndm, + sizeof(struct gpart), 0, NULL); +} + struct duplication_data { struct part* parts; @@ -1895,7 +1929,7 @@ void io_collect_gparts_to_write( * @param N_total The total number of each particle type. */ void io_check_output_fields(const struct swift_params* params, - const long long N_total[3]) { + const long long N_total[swift_type_count]) { /* Copy N_total to array with length == 6 */ const long long nr_total[swift_type_count] = {N_total[0], N_total[1], 0, @@ -1908,7 +1942,7 @@ void io_check_output_fields(const struct swift_params* params, struct io_props list[100]; /* Don't do anything if no particle of this kind */ - if (nr_total[ptype] == 0) continue; + if (N_total[ptype] == 0) continue; /* Gather particle fields from the particle structures */ switch (ptype) { @@ -1932,6 +1966,12 @@ void io_check_output_fields(const struct swift_params* params, 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); + break; + case swift_type_stars: stars_write_particles(NULL, list, &num_fields, /*with_cosmology=*/1); num_fields += chemistry_write_sparticles(NULL, list + num_fields); @@ -2045,6 +2085,12 @@ void io_write_output_field_parameter(const char* filename) { 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); + break; + case swift_type_stars: stars_write_particles(NULL, list, &num_fields, /*with_cosmology=*/1); num_fields += chemistry_write_sparticles(NULL, list + num_fields); diff --git a/src/common_io.h b/src/common_io.h index 03437d1a38a09e59e6abd4b9ca762f181ffc3731..ca28d60901535422dd842f4554480d083c05e622 100644 --- a/src/common_io.h +++ b/src/common_io.h @@ -127,6 +127,8 @@ void io_collect_gparts_to_write(const struct gpart* restrict gparts, const size_t Ngparts_written, int with_stf); void io_prepare_dm_gparts(struct threadpool* tp, struct gpart* const gparts, size_t Ndm); +void io_prepare_dm_background_gparts(struct threadpool* tp, + struct gpart* const gparts, size_t Ndm); void io_duplicate_hydro_gparts(struct threadpool* tp, struct part* const parts, struct gpart* const gparts, size_t Ngas, size_t Ndm); diff --git a/src/part.c b/src/part.c index 7d967caad18caf0c45d2a422fb4766d34f559d00..a6475983dcf5d8c3dfca239b85a56d32ef80a771 100644 --- a/src/part.c +++ b/src/part.c @@ -188,6 +188,15 @@ void part_verify_links(struct part *parts, struct gpart *gparts, error("DM gpart particle linked to something !"); } + /* We have a background DM particle */ + if (gparts[k].type == swift_type_dark_matter_background && + gparts[k].time_bin != time_bin_not_created) { + + /* Check that it's not linked */ + if (gparts[k].id_or_neg_offset <= 0) + error("DM gpart particle linked to something !"); + } + /* We have a gas particle */ else if (gparts[k].type == swift_type_gas) { diff --git a/src/part_type.c b/src/part_type.c index 75a3f270d06576831833cf75c9bed9b7fde2c68d..5a2eee2ee2e4296f4abdd1dd3ae4927748484b15 100644 --- a/src/part_type.c +++ b/src/part_type.c @@ -21,4 +21,4 @@ #include "part_type.h" const char* part_type_names[swift_type_count] = { - "Gas", "DM", "DM_boundary", "Dummy", "Stars", "BH"}; + "Gas", "DM", "DM_background", "Dummy", "Stars", "BH"}; diff --git a/src/part_type.h b/src/part_type.h index edab07a17080f90bee99507cd5ee3d6ed08054aa..8311f5d17a7b838b9577a029387a5f01fb1a0801 100644 --- a/src/part_type.h +++ b/src/part_type.h @@ -27,7 +27,7 @@ enum part_type { swift_type_gas = 0, swift_type_dark_matter = 1, - swift_type_dark_matter_boundary = 2, + swift_type_dark_matter_background = 2, swift_type_stars = 4, swift_type_black_hole = 5, swift_type_count diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index c6885746a29fd7b6bd828496316f8dad01c1b7da..d308d4712354b8266db9fb002c0cb7f3e44737db 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -1382,6 +1382,8 @@ static INLINE void runner_dopair_grav_mm_progenies(struct runner *r, struct cell *restrict ci, struct cell *restrict cj) { + return; + /* Loop over all pairs of progenies */ for (int i = 0; i < 8; i++) { if (ci->progeny[i] != NULL) { @@ -1503,6 +1505,8 @@ static INLINE void runner_dopair_recursive_grav(struct runner *r, struct cell *ci, struct cell *cj, int gettimer) { + return; + /* Some constants */ const struct engine *e = r->e; const int nodeID = e->nodeID; @@ -1657,6 +1661,8 @@ static INLINE void runner_dopair_recursive_grav(struct runner *r, static INLINE void runner_doself_recursive_grav(struct runner *r, struct cell *c, int gettimer) { + return; + /* Some constants */ const struct engine *e = r->e; diff --git a/src/single_io.c b/src/single_io.c index 76a5630120df5e946093e9f046503f73bce706b6..6be604ddf215a5be527930f45c7dc483c0cd2b9f 100644 --- a/src/single_io.c +++ b/src/single_io.c @@ -404,11 +404,11 @@ void read_ic_single(const char* fileName, const struct unit_system* internal_units, double dim[3], struct part** parts, struct gpart** gparts, struct spart** sparts, struct bpart** bparts, size_t* Ngas, - size_t* Ngparts, size_t* Nstars, size_t* Nblackholes, - int* flag_entropy, int with_hydro, int with_gravity, - int with_stars, int with_black_holes, int cleanup_h, - int cleanup_sqrt_a, double h, double a, int n_threads, - int dry_run) { + size_t* Ngparts, size_t* Ngparts_background, size_t* Nstars, + size_t* Nblackholes, int* flag_entropy, int with_hydro, + int with_gravity, int with_stars, int with_black_holes, + int cleanup_h, int cleanup_sqrt_a, double h, double a, + int n_threads, int dry_run) { hid_t h_file = 0, h_grp = 0; /* GADGET has only cubic boxes (in cosmological mode) */ @@ -419,9 +419,11 @@ void read_ic_single(const char* fileName, size_t N[swift_type_count] = {0}; int dimension = 3; /* Assume 3D if nothing is specified */ size_t Ndm = 0; + size_t Ndm_background = 0; /* Initialise counters */ - *Ngas = 0, *Ngparts = 0, *Nstars = 0, *Nblackholes = 0; + *Ngas = 0, *Ngparts = 0, *Ngparts_background = 0, *Nstars = 0, + *Nblackholes = 0; /* Open file */ /* message("Opening file '%s' as IC.", fileName); */ @@ -563,10 +565,13 @@ void read_ic_single(const char* fileName, /* Allocate memory to store all gravity particles */ if (with_gravity) { Ndm = N[swift_type_dark_matter]; + Ndm_background = N[swift_type_dark_matter_background]; *Ngparts = (with_hydro ? N[swift_type_gas] : 0) + N[swift_type_dark_matter] + + N[swift_type_dark_matter_background] + (with_stars ? N[swift_type_stars] : 0) + (with_black_holes ? N[swift_type_black_hole] : 0); + *Ngparts_background = Ndm_background; if (swift_memalign("gparts", (void**)gparts, gpart_align, *Ngparts * sizeof(struct gpart)) != 0) error("Error while allocating memory for gravity particles"); @@ -615,6 +620,13 @@ void read_ic_single(const char* fileName, } break; + case swift_type_dark_matter_background: + if (with_gravity) { + Nparticles = Ndm_background; + darkmatter_read_particles(*gparts + Ndm, list, &num_fields); + } + break; + case swift_type_stars: if (with_stars) { Nparticles = *Nstars; @@ -653,17 +665,23 @@ void read_ic_single(const char* fileName, /* Prepare the DM particles */ io_prepare_dm_gparts(&tp, *gparts, Ndm); + /* Prepare the DM background particles */ + io_prepare_dm_background_gparts(&tp, *gparts + Ndm, Ndm_background); + /* Duplicate the hydro particles into gparts */ - if (with_hydro) io_duplicate_hydro_gparts(&tp, *parts, *gparts, *Ngas, Ndm); + if (with_hydro) + io_duplicate_hydro_gparts(&tp, *parts, *gparts, *Ngas, + Ndm + Ndm_background); /* Duplicate the star particles into gparts */ if (with_stars) - io_duplicate_stars_gparts(&tp, *sparts, *gparts, *Nstars, Ndm + *Ngas); + io_duplicate_stars_gparts(&tp, *sparts, *gparts, *Nstars, + Ndm + Ndm_background + *Ngas); /* Duplicate the black hole particles into gparts */ if (with_black_holes) io_duplicate_black_holes_gparts(&tp, *bparts, *gparts, *Nblackholes, - Ndm + *Ngas + *Nstars); + Ndm + Ndm_background + *Ngas + *Nstars); threadpool_clean(&tp); } diff --git a/src/single_io.h b/src/single_io.h index 9ff04c893378d7f8c01621e7dbf387dc939d0157..47b575272c2fbe5b170eb4370743cd6830b99ae0 100644 --- a/src/single_io.h +++ b/src/single_io.h @@ -34,11 +34,11 @@ void read_ic_single(const char* fileName, const struct unit_system* internal_units, double dim[3], struct part** parts, struct gpart** gparts, struct spart** sparts, struct bpart** bparts, size_t* Ngas, - size_t* Ndm, size_t* Nstars, size_t* Nblackholes, - int* flag_entropy, int with_hydro, int with_gravity, - int with_stars, int with_black_holes, int cleanup_h, - int cleanup_sqrt_a, double h, double a, int nr_threads, - int dry_run); + size_t* Ndm, size_t* Ndm_background, size_t* Nstars, + size_t* Nblackholes, int* flag_entropy, int with_hydro, + int with_gravity, int with_stars, int with_black_holes, + int cleanup_h, int cleanup_sqrt_a, double h, double a, + int nr_threads, int dry_run); void write_output_single(struct engine* e, const char* baseName, const struct unit_system* internal_units, diff --git a/src/space.c b/src/space.c index 49c714743728a3b93f631434d87de69a61dd716f..b25750b0d648a5123454a8d2551fb8999c6fa4cb 100644 --- a/src/space.c +++ b/src/space.c @@ -3945,6 +3945,9 @@ void space_synchronize_particle_positions_mapper(void *map_data, int nr_gparts, if (gp->type == swift_type_dark_matter) continue; + else if (gp->type == swift_type_dark_matter_background) + continue; + else if (gp->type == swift_type_gas) { /* Get its gassy friend */ @@ -3988,6 +3991,10 @@ void space_synchronize_particle_positions_mapper(void *map_data, int nr_gparts, gp->mass = bp->mass; } + + else { + error("Invalid type!"); + } } } diff --git a/src/velociraptor_interface.c b/src/velociraptor_interface.c index 47c107d047e3abfcac32571f780cf52649a9c38d..2599c7b6ec4df05c0ae701e33474ffb126f3d6e3 100644 --- a/src/velociraptor_interface.c +++ b/src/velociraptor_interface.c @@ -283,6 +283,13 @@ void velociraptor_convert_particles_mapper(void *map_data, int nr_gparts, swift_parts[i].T = 0.f; break; + case swift_type_dark_matter_background: + + swift_parts[i].id = gparts[i].id_or_neg_offset; + swift_parts[i].u = 0.f; + swift_parts[i].T = 0.f; + break; + default: error("Particle type not handled by VELOCIraptor."); }