diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_sink/getIC.sh b/examples/IsolatedGalaxy/IsolatedGalaxy_sink/getIC.sh index a3d16db27aac06abda683a7bd75e72a275f8b9d4..f354eb1c253039e02b409c9562c7c0b0716b07f6 100755 --- a/examples/IsolatedGalaxy/IsolatedGalaxy_sink/getIC.sh +++ b/examples/IsolatedGalaxy/IsolatedGalaxy_sink/getIC.sh @@ -1,2 +1,3 @@ #!/bin/bash -wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/IsolatedGalaxies/3e11-star-only-DM-halo-galaxy.hdf5 +wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/IsolatedGalaxies/$1 + diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_sink/isolated_galaxy.yml b/examples/IsolatedGalaxy/IsolatedGalaxy_sink/isolated_galaxy.yml index c83abbd55d207095655cca733fd77f596a5b6c15..7428181f3f17b5e90b216f597149fcbca3187cc7 100644 --- a/examples/IsolatedGalaxy/IsolatedGalaxy_sink/isolated_galaxy.yml +++ b/examples/IsolatedGalaxy/IsolatedGalaxy_sink/isolated_galaxy.yml @@ -8,6 +8,9 @@ InternalUnitSystem: # Parameters for the self-gravity scheme Gravity: + MAC: adaptive # Choice of mulitpole acceptance criterion: 'adaptive' OR 'geometric'. + epsilon_fmm: 0.001 # Tolerance parameter for the adaptive multipole acceptance criterion. + theta_cr: 0.7 # Opening angle for the purely gemoetric criterion. eta: 0.025 # Constant dimensionless multiplier for time integration. theta: 0.7 # Opening angle (Multipole acceptance criterion). max_physical_DM_softening: 0.7 # Physical softening length (in internal units). @@ -39,4 +42,41 @@ InitialConditions: file_name: isolated_galaxy.hdf5 # The file to read periodic: 0 # Are we running with periodic ICs? +# Parameters for the hydrodynamics scheme +SPH: + resolution_eta: 1.2348 # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel). + CFL_condition: 0.1 # Courant-Friedrich-Levy condition for time integration. + use_mass_weighted_num_ngb: 0 # (Optional) Are we using the mass-weighted definition of the number of neighbours? + h_tolerance: 1e-4 # (Optional) Relative accuracy of the Netwon-Raphson scheme for the smoothing lengths. + h_max: 10. # (Optional) Maximal allowed smoothing length in internal units. Defaults to FLT_MAX if unspecified. + h_min_ratio: 0. # (Optional) Minimal allowed smoothing length in units of the softening. Defaults to 0 if unspecified. + max_volume_change: 1.4 # (Optional) Maximal allowed change of kernel volume over one time-step. + max_ghost_iterations: 30 # (Optional) Maximal number of iterations allowed to converge towards the smoothing length. + particle_splitting: 1 # (Optional) Are we splitting particles that are too massive (default: 0) + particle_splitting_mass_threshold: 7e-4 # (Optional) Mass threshold for particle splitting (in internal units) + generate_random_ids: 0 # (Optional) When creating new particles via splitting, generate ids at random (1) or use new IDs beyond the current range (0) (default: 0) + initial_temperature: 0 # (Optional) Initial temperature (in internal units) to set the gas particles at start-up. Value is ignored if set to 0. + minimal_temperature: 0 # (Optional) Minimal temperature (in internal units) allowed for the gas particles. Value is ignored if set to 0. + H_mass_fraction: 0.755 # (Optional) Hydrogen mass fraction used for initial conversion from temp to internal energy. Default value is derived from the physical constants. + H_ionization_temperature: 1e4 # (Optional) Temperature of the transition from neutral to ionized Hydrogen for primoridal gas. + viscosity_alpha: 0.8 # (Optional) Override for the initial value of the artificial viscosity. In schemes that have a fixed AV, this remains as alpha throughout the run. + viscosity_alpha_max: 2.0 # (Optional) Maximal value for the artificial viscosity in schemes that allow alpha to vary. + viscosity_alpha_min: 0.1 # (Optional) Minimal value for the artificial viscosity in schemes that allow alpha to vary. + viscosity_length: 0.1 # (Optional) Decay length for the artificial viscosity in schemes that allow alpha to vary. + diffusion_alpha: 0.0 # (Optional) Override the initial value for the thermal diffusion coefficient in schemes with thermal diffusion. + diffusion_beta: 0.01 # (Optional) Override the decay/rise rate tuning parameter for the thermal diffusion. + diffusion_alpha_max: 1.0 # (Optional) Override the maximal thermal diffusion coefficient that is allowed for a given particle. + diffusion_alpha_min: 0.0 # (Optional) Override the minimal thermal diffusion coefficient that is allowed for a given particle. +# Hernquist potential parameters +HernquistPotential: + useabspos: 0 # 0 -> positions based on centre, 1 -> absolute positions + position: [0.,0.,0.] # Location of centre of isothermal potential with respect to centre of the box (if 0) otherwise absolute (if 1) (internal units) + idealizeddisk: 1 # Run with an idealized galaxy disk + M200: 137.0 # M200 of the galaxy disk + h: 0.704 # reduced Hubble constant (value does not specify the used units!) + concentration: 9.0 # concentration of the Halo + diskfraction: 0.040 # Disk mass fraction + bulgefraction: 0.014 # Bulge mass fraction + timestep_mult: 0.01 # Dimensionless pre-factor for the time-step condition, basically determines the fraction of the orbital time we use to do the time integration + epsilon: 0.2 # Softening size (internal units) diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_sink/makeIC.py b/examples/IsolatedGalaxy/IsolatedGalaxy_sink/makeIC.py index 3587c9d858ab1a72a39b1b243b6d58bae7fad383..61744122a760bb3afef1f2b61db816bdff766bfb 100644 --- a/examples/IsolatedGalaxy/IsolatedGalaxy_sink/makeIC.py +++ b/examples/IsolatedGalaxy/IsolatedGalaxy_sink/makeIC.py @@ -20,14 +20,14 @@ import h5py import numpy as np from shutil import copyfile +import sys # Add sink particles to the isolated galaxy -fileName = "3e11-star-only-DM-halo-galaxy.hdf5" +fileName = sys.argv[-1] output = "isolated_galaxy.hdf5" -L = 13756 # Size of the box (internal units) -L_sink = 1000 # Size of the sink particle area (L_sink < L) +L_sink = 50 # Size of the sink particle area N = 1000 # Number of sink particles max_vel = 100 # Maximal velocity of the sink particles (in km / s) mass = 0.000142 # Mass of a sink particle (internal units) @@ -40,6 +40,11 @@ copyfile(fileName, output) # File file = h5py.File(output, 'a') +# Get the box size (suppose that the galaxy is at the center of the box) +L = 2 * file["PartType0/Coordinates"][:].mean() +if (L < L_sink): + raise Exception("Error the size of the sink box is too large") + pos = np.random.rand(N, 3) * L_sink + 0.5 * (L - L_sink) vel = 2 * (np .random.rand(N, 3) - 0.5) * max_vel m = mass * np.ones(N) diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_sink/run.sh b/examples/IsolatedGalaxy/IsolatedGalaxy_sink/run.sh index 7d2cee8c29c0eadc886b3188d532567ea861bde5..8f3e976956e4b79a7d5a708eb65ed76284b19b7d 100755 --- a/examples/IsolatedGalaxy/IsolatedGalaxy_sink/run.sh +++ b/examples/IsolatedGalaxy/IsolatedGalaxy_sink/run.sh @@ -1,12 +1,20 @@ #!/bin/bash -if [ ! -e 3e11-star-only-DM-halo-galaxy.hdf5 ] +# filename=fid.hdf5 +# filename=f10.hdf5 +# filename=f90.hdf5 +filename=lowres8.hdf5 +# filename=lowres64.hdf5 +# filename=lowres512.hdf5 +# filename=highres6.hdf5 + +if [ ! -e $filename ] then echo "Fetching initial conditons for the isolated galaxy with an external potential ..." - ./getIC.sh + ./getIC.sh $filename fi echo "Generate initial conditions" -python3 makeIC.py +python3 makeIC.py $filename -../../swift --sinks --external-gravity --self-gravity --threads=16 isolated_galaxy.yml 2>&1 | tee output.log +../../swift --hydro --sinks --external-gravity --self-gravity --threads=1 isolated_galaxy.yml 2>&1 | tee output.log diff --git a/examples/main.c b/examples/main.c index 3a3bee4e51a021310d8a08b5ff92ca77e3d597c1..f8b645111310314575bdf4872ff81bbd11ca2267 100644 --- a/examples/main.c +++ b/examples/main.c @@ -1298,7 +1298,7 @@ int main(int argc, char *argv[]) { if (with_fof) engine_policies |= engine_policy_fof; if (with_logger) engine_policies |= engine_policy_logger; if (with_line_of_sight) engine_policies |= engine_policy_line_of_sight; - if (with_sink) engine_policies |= engine_policy_sink; + if (with_sink) engine_policies |= engine_policy_sinks; if (with_rt) engine_policies |= engine_policy_rt; /* Initialize the engine with the space and policies. */ @@ -1401,10 +1401,12 @@ int main(int argc, char *argv[]) { /* Legend */ if (myrank == 0) { - printf("# %6s %14s %12s %12s %14s %9s %12s %12s %12s %12s %16s [%s] %6s\n", - "Step", "Time", "Scale-factor", "Redshift", "Time-step", "Time-bins", - "Updates", "g-Updates", "s-Updates", "b-Updates", "Wall-clock time", - clocks_getunit(), "Props"); + printf( + "# %6s %14s %12s %12s %14s %9s %12s %12s %12s %12s %12s %16s [%s] " + "%6s\n", + "Step", "Time", "Scale-factor", "Redshift", "Time-step", "Time-bins", + "Updates", "g-Updates", "s-Updates", "sink-Updates", "b-Updates", + "Wall-clock time", clocks_getunit(), "Props"); fflush(stdout); } @@ -1548,19 +1550,21 @@ int main(int argc, char *argv[]) { /* Print some information to the screen */ printf( - " %6d %14e %12.7f %12.7f %14e %4d %4d %12lld %12lld %12lld %12lld" + " %6d %14e %12.7f %12.7f %14e %4d %4d %12lld %12lld %12lld %12lld " + "%12lld" " %21.3f %6d\n", e.step, e.time, e.cosmology->a, e.cosmology->z, e.time_step, e.min_active_bin, e.max_active_bin, e.updates, e.g_updates, e.s_updates, - e.b_updates, e.wallclock_time, e.step_props); + e.sink_updates, e.b_updates, e.wallclock_time, e.step_props); fflush(stdout); fprintf(e.file_timesteps, " %6d %14e %12.7f %12.7f %14e %4d %4d %12lld %12lld %12lld %12lld" - " %21.3f %6d\n", + " %12lld %21.3f %6d\n", e.step, e.time, e.cosmology->a, e.cosmology->z, e.time_step, e.min_active_bin, e.max_active_bin, e.updates, e.g_updates, - e.s_updates, e.b_updates, e.wallclock_time, e.step_props); + e.s_updates, e.sink_updates, e.b_updates, e.wallclock_time, + e.step_props); fflush(e.file_timesteps); /* Print information to the SFH logger */ diff --git a/src/cell.c b/src/cell.c index 30fd9031e159b2dab033623fc2adef34cf2d5bbf..2a947f6b6ed32080a19b08a87b71fdf5a12bb8b9 100644 --- a/src/cell.c +++ b/src/cell.c @@ -2065,6 +2065,7 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset, /* Store the counts and offsets. */ for (int k = 0; k < 8; k++) { c->progeny[k]->sinks.count = bucket_count[k]; + c->progeny[k]->sinks.count_total = c->progeny[k]->sinks.count; c->progeny[k]->sinks.parts = &c->sinks.parts[bucket_offset[k]]; } @@ -2294,6 +2295,44 @@ void cell_check_gpart_drift_point(struct cell *c, void *data) { #endif } +/** + * @brief Checks that the #sink in a cell are at the + * current point in time + * + * Calls error() if the cell is not at the current time. + * + * @param c Cell to act upon + * @param data The current time on the integer time-line + */ +void cell_check_sink_drift_point(struct cell *c, void *data) { +#ifdef SWIFT_DEBUG_CHECKS + + const integertime_t ti_drift = *(integertime_t *)data; + + /* Only check local cells */ + if (c->nodeID != engine_rank) return; + + /* Only check cells with content */ + if (c->sinks.count == 0) return; + + if (c->sinks.ti_old_part != ti_drift) + error( + "Cell in an incorrect time-zone! c->sinks.ti_old_part=%lld " + "ti_drift=%lld", + c->sinks.ti_old_part, ti_drift); + + for (int i = 0; i < c->sinks.count; ++i) + if (c->sinks.parts[i].ti_drift != ti_drift && + c->sinks.parts[i].time_bin != time_bin_inhibited) + error( + "sink-part in an incorrect time-zone! sink->ti_drift=%lld " + "ti_drift=%lld", + c->sinks.parts[i].ti_drift, ti_drift); +#else + error("Calling debugging code without debugging flag activated."); +#endif +} + /** * @brief Checks that the #spart in a cell are at the * current point in time @@ -2633,7 +2672,8 @@ void cell_clear_drift_flags(struct cell *c, void *data) { cell_flag_do_grav_drift | cell_flag_do_grav_sub_drift | cell_flag_do_bh_drift | cell_flag_do_bh_sub_drift | cell_flag_do_stars_drift | - cell_flag_do_stars_sub_drift); + cell_flag_do_stars_sub_drift | + cell_flag_do_sink_drift | cell_flag_do_sink_sub_drift); } /** @@ -3027,6 +3067,44 @@ void cell_activate_drift_bpart(struct cell *c, struct scheduler *s) { } } +/** + * @brief Activate the #sink drifts on the given cell. + */ +void cell_activate_drift_sink(struct cell *c, struct scheduler *s) { + + /* If this cell is already marked for drift, quit early. */ + if (cell_get_flag(c, cell_flag_do_sink_drift)) return; + + /* Mark this cell for drifting. */ + cell_set_flag(c, cell_flag_do_sink_drift); + + /* Set the do_sink_sub_drifts all the way up and activate the super + drift if this has not yet been done. */ + if (c == c->hydro.super) { +#ifdef SWIFT_DEBUG_CHECKS + if (c->sinks.drift == NULL) + error("Trying to activate un-existing c->sinks.drift"); +#endif + scheduler_activate(s, c->sinks.drift); + } else { + for (struct cell *parent = c->parent; + parent != NULL && !cell_get_flag(parent, cell_flag_do_sink_sub_drift); + parent = parent->parent) { + /* Mark this cell for drifting */ + cell_set_flag(parent, cell_flag_do_sink_sub_drift); + + if (parent == c->hydro.super) { +#ifdef SWIFT_DEBUG_CHECKS + if (parent->sinks.drift == NULL) + error("Trying to activate un-existing parent->sinks.drift"); +#endif + scheduler_activate(s, parent->sinks.drift); + break; + } + } + } +} + /** * @brief Activate the drifts on the given cell. */ @@ -3514,6 +3592,102 @@ void cell_activate_subcell_black_holes_tasks(struct cell *ci, struct cell *cj, } /* Otherwise, pair interation */ } +/** + * @brief Traverse a sub-cell task and activate the sinks drift tasks that + * are required by a sinks task + * + * @param ci The first #cell we recurse in. + * @param cj The second #cell we recurse in. + * @param s The task #scheduler. + * @param with_timestep_sync Are we running with time-step synchronization on? + */ +void cell_activate_subcell_sinks_tasks(struct cell *ci, struct cell *cj, + struct scheduler *s, + const int with_timestep_sync) { + const struct engine *e = s->space->e; + + /* Store the current dx_max and h_max values. */ + ci->sinks.dx_max_part_old = ci->sinks.dx_max_part; + ci->hydro.dx_max_part_old = ci->hydro.dx_max_part; + ci->hydro.h_max_old = ci->hydro.h_max; + + if (cj != NULL) { + cj->sinks.dx_max_part_old = cj->sinks.dx_max_part; + cj->hydro.dx_max_part_old = cj->hydro.dx_max_part; + cj->hydro.h_max_old = cj->hydro.h_max; + } + + /* Self interaction? */ + if (cj == NULL) { + /* Do anything? */ + if (!cell_is_active_sinks(ci, e) || ci->hydro.count == 0 || + ci->sinks.count == 0) + return; + + /* Recurse? */ + if (cell_can_recurse_in_self_sinks_task(ci)) { + /* Loop over all progenies and pairs of progenies */ + for (int j = 0; j < 8; j++) { + if (ci->progeny[j] != NULL) { + cell_activate_subcell_sinks_tasks(ci->progeny[j], NULL, s, + with_timestep_sync); + for (int k = j + 1; k < 8; k++) + if (ci->progeny[k] != NULL) + cell_activate_subcell_sinks_tasks(ci->progeny[j], ci->progeny[k], + s, with_timestep_sync); + } + } + } else { + /* We have reached the bottom of the tree: activate drift */ + cell_activate_drift_sink(ci, s); + cell_activate_drift_part(ci, s); + } + } + + /* Otherwise, pair interation */ + else { + error("Not implemented yet."); + /* /\* Should we even bother? *\/ */ + /* if (!cell_is_active_sinks(ci, e) && */ + /* !cell_is_active_sinks(cj, e)) */ + /* return; */ + + /* /\* Get the orientation of the pair. *\/ */ + /* double shift[3]; */ + /* const int sid = space_getsid(s->space, &ci, &cj, shift); */ + + /* /\* recurse? *\/ */ + /* if (cell_can_recurse_in_pair_sinks_task(ci, cj) && */ + /* cell_can_recurse_in_pair_sinks_task(cj, ci)) { */ + /* const struct cell_split_pair *csp = &cell_split_pairs[sid]; */ + /* for (int k = 0; k < csp->count; k++) { */ + /* const int pid = csp->pairs[k].pid; */ + /* const int pjd = csp->pairs[k].pjd; */ + /* if (ci->progeny[pid] != NULL && cj->progeny[pjd] != NULL) */ + /* cell_activate_subcell_sinks_tasks( */ + /* ci->progeny[pid], cj->progeny[pjd], s, with_timestep_sync); */ + /* } */ + /* } */ + + /* /\* Otherwise, activate the drifts. *\/ */ + /* else if (cell_is_active_sinks(ci, e) || */ + /* cell_is_active_sinks(cj, e)) { */ + + /* /\* Activate the drifts if the cells are local. *\/ */ + /* if (ci->nodeID == engine_rank) cell_activate_drift_sinks(ci, s); */ + /* if (cj->nodeID == engine_rank) cell_activate_drift_part(cj, s); */ + /* if (cj->nodeID == engine_rank && with_timestep_sync) */ + /* cell_activate_sync_part(cj, s); */ + + /* /\* Activate the drifts if the cells are local. *\/ */ + /* if (ci->nodeID == engine_rank) cell_activate_drift_part(ci, s); */ + /* if (cj->nodeID == engine_rank) cell_activate_drift_sinks(cj, s); */ + /* if (ci->nodeID == engine_rank && with_timestep_sync) */ + /* cell_activate_sync_part(ci, s); */ + /* } */ + } /* Otherwise, pair interation */ +} + /** * @brief Traverse a sub-cell task and activate the gravity drift tasks that * are required by a self gravity task. @@ -4609,6 +4783,38 @@ int cell_unskip_black_holes_tasks(struct cell *c, struct scheduler *s) { return rebuild; } +/** + * @brief Un-skips all the sinks tasks associated with a given cell and + * checks if the space needs to be rebuilt. + * + * @param c the #cell. + * @param s the #scheduler. + * + * @return 1 If the space needs rebuilding. 0 otherwise. + */ +int cell_unskip_sinks_tasks(struct cell *c, struct scheduler *s) { + + struct engine *e = s->space->e; + const int nodeID = e->nodeID; + int rebuild = 0; + + if (c->sinks.drift != NULL && cell_is_active_sinks(c, e)) { + cell_activate_drift_sink(c, s); + } + + /* Unskip all the other task types. */ + if (c->nodeID == nodeID && cell_is_active_sinks(c, e)) { + if (c->kick1 != NULL) scheduler_activate(s, c->kick1); + if (c->kick2 != NULL) scheduler_activate(s, c->kick2); + if (c->timestep != NULL) scheduler_activate(s, c->timestep); +#ifdef WITH_LOGGER + if (c->logger != NULL) scheduler_activate(s, c->logger); +#endif + } + + return rebuild; +} + /** * @brief Set the super-cell pointers for all cells in a hierarchy. * @@ -5439,6 +5645,156 @@ void cell_drift_bpart(struct cell *c, const struct engine *e, int force) { cell_clear_flag(c, cell_flag_do_bh_drift | cell_flag_do_bh_sub_drift); } +/** + * @brief Recursively drifts the #sinks in a cell hierarchy. + * + * @param c The #cell. + * @param e The #engine (to get ti_current). + * @param force Drift the particles irrespective of the #cell flags. + */ +void cell_drift_sink(struct cell *c, const struct engine *e, int force) { + + const int periodic = e->s->periodic; + const double dim[3] = {e->s->dim[0], e->s->dim[1], e->s->dim[2]}; + const int with_cosmology = (e->policy & engine_policy_cosmology); + const integertime_t ti_old_bpart = c->sinks.ti_old_part; + const integertime_t ti_current = e->ti_current; + struct sink *const sinks = c->sinks.parts; + + float dx_max = 0.f, dx2_max = 0.f; + + /* Drift irrespective of cell flags? */ + force = (force || cell_get_flag(c, cell_flag_do_sink_drift)); + +#ifdef SWIFT_DEBUG_CHECKS + /* Check that we only drift local cells. */ + if (c->nodeID != engine_rank) error("Drifting a foreign cell is nope."); + + /* Check that we are actually going to move forward. */ + if (ti_current < ti_old_bpart) error("Attempt to drift to the past"); +#endif + + /* Early abort? */ + if (c->sinks.count == 0) { + + /* Clear the drift flags. */ + cell_clear_flag(c, cell_flag_do_sink_drift | cell_flag_do_sink_sub_drift); + + /* Update the time of the last drift */ + c->sinks.ti_old_part = ti_current; + + return; + } + + /* Ok, we have some particles somewhere in the hierarchy to drift */ + + /* Are we not in a leaf ? */ + if (c->split && (force || cell_get_flag(c, cell_flag_do_sink_sub_drift))) { + + /* Loop over the progeny and collect their data. */ + for (int k = 0; k < 8; k++) { + if (c->progeny[k] != NULL) { + struct cell *cp = c->progeny[k]; + + /* Recurse */ + cell_drift_sink(cp, e, force); + + /* Update */ + dx_max = max(dx_max, cp->sinks.dx_max_part); + } + } + + /* Store the values */ + c->sinks.dx_max_part = dx_max; + + /* Update the time of the last drift */ + c->sinks.ti_old_part = ti_current; + + } else if (!c->split && force && ti_current > ti_old_bpart) { + + /* Drift from the last time the cell was drifted to the current time */ + double dt_drift; + if (with_cosmology) { + dt_drift = + cosmology_get_drift_factor(e->cosmology, ti_old_bpart, ti_current); + } else { + dt_drift = (ti_current - ti_old_bpart) * e->time_base; + } + + /* Loop over all the star particles in the cell */ + const size_t nr_sinks = c->sinks.count; + for (size_t k = 0; k < nr_sinks; k++) { + + /* Get a handle on the sink. */ + struct sink *const sink = &sinks[k]; + + /* Ignore inhibited particles */ + if (sink_is_inhibited(sink, e)) continue; + + /* Drift... */ + drift_sink(sink, dt_drift, ti_old_bpart, ti_current); + +#ifdef SWIFT_DEBUG_CHECKS + /* Make sure the particle does not drift by more than a box length. */ + if (fabs(sink->v[0] * dt_drift) > e->s->dim[0] || + fabs(sink->v[1] * dt_drift) > e->s->dim[1] || + fabs(sink->v[2] * dt_drift) > e->s->dim[2]) { + error("Particle drifts by more than a box length!"); + } +#endif + + /* In non-periodic BC runs, remove particles that crossed the border */ + if (!periodic) { + + /* Did the particle leave the box? */ + if ((sink->x[0] > dim[0]) || (sink->x[0] < 0.) || // x + (sink->x[1] > dim[1]) || (sink->x[1] < 0.) || // y + (sink->x[2] > dim[2]) || (sink->x[2] < 0.)) { // z + + lock_lock(&e->s->lock); + + /* Re-check that the particle has not been removed + * by another thread before we do the deed. */ + if (!sink_is_inhibited(sink, e)) { + + /* Remove the particle entirely */ + // cell_remove_sink(e, c, bp); + error("TODO: loic implement cell_remove_sink"); + } + + if (lock_unlock(&e->s->lock) != 0) + error("Failed to unlock the space!"); + + continue; + } + } + + /* Compute (square of) motion since last cell construction */ + const float dx2 = sink->x_diff[0] * sink->x_diff[0] + + sink->x_diff[1] * sink->x_diff[1] + + sink->x_diff[2] * sink->x_diff[2]; + dx2_max = max(dx2_max, dx2); + + /* Get ready for a density calculation */ + if (sink_is_active(sink, e)) { + sink_init_sink(sink); + } + } + + /* Now, get the maximal particle motion from its square */ + dx_max = sqrtf(dx2_max); + + /* Store the values */ + c->sinks.dx_max_part = dx_max; + + /* Update the time of the last drift */ + c->sinks.ti_old_part = ti_current; + } + + /* Clear the drift flags. */ + cell_clear_flag(c, cell_flag_do_sink_drift | cell_flag_do_sink_sub_drift); +} + /** * @brief Recursively drifts all multipoles in a cell hierarchy. * @@ -5587,7 +5943,7 @@ void cell_check_timesteps(const struct cell *c, const integertime_t ti_current, if (c->hydro.ti_end_min == 0 && c->grav.ti_end_min == 0 && c->stars.ti_end_min == 0 && c->black_holes.ti_end_min == 0 && - c->nr_tasks > 0) + c->sinks.ti_end_min == 0 && c->nr_tasks > 0) error("Cell without assigned time-step"); if (c->split) { diff --git a/src/cell.h b/src/cell.h index c8c0d664a0798d310e8579a74a4000a0b54a18e9..55e2c89387ce42078f42c753c516da15542b8b96 100644 --- a/src/cell.h +++ b/src/cell.h @@ -304,10 +304,12 @@ enum cell_flags { cell_flag_do_stars_sub_drift = (1UL << 10), cell_flag_do_bh_drift = (1UL << 11), cell_flag_do_bh_sub_drift = (1UL << 12), - cell_flag_do_stars_resort = (1UL << 13), - cell_flag_has_tasks = (1UL << 14), - cell_flag_do_hydro_sync = (1UL << 15), - cell_flag_do_hydro_sub_sync = (1UL << 16) + cell_flag_do_sink_drift = (1UL << 13), + cell_flag_do_sink_sub_drift = (1UL << 14), + cell_flag_do_stars_resort = (1UL << 15), + cell_flag_has_tasks = (1UL << 16), + cell_flag_do_hydro_sync = (1UL << 17), + cell_flag_do_hydro_sub_sync = (1UL << 18) }; /** @@ -317,7 +319,7 @@ enum cell_flags { */ struct cell { - /*! The cell location on the grid. */ + /*! The cell location on the grid (corner nearest to the origin). */ double loc[3]; /*! The cell dimensions. */ @@ -764,12 +766,21 @@ struct cell { /*! Nr of #sink this cell can hold after addition of new one. */ int count_total; + /*! Number of #sink updated in this cell. */ + int updated; + /*! Is the #sink data of this cell being used in a sub-cell? */ int hold; /*! Spin lock for various uses (#sink case). */ swift_lock_type lock; + /*! Maximum part movement in this cell since last construction. */ + float dx_max_part; + + /*! Values of dx_max before the drifts, used for sub-cell tasks. */ + float dx_max_part_old; + /*! Last (integer) time the cell's sink were drifted forward in time. */ integertime_t ti_old_part; @@ -783,6 +794,10 @@ struct cell { * tasks. */ integertime_t ti_beg_max; + + /*! The drift task for sinks */ + struct task *drift; + } sinks; #ifdef WITH_MPI @@ -940,16 +955,19 @@ void cell_clean(struct cell *c); void cell_check_part_drift_point(struct cell *c, void *data); void cell_check_gpart_drift_point(struct cell *c, void *data); void cell_check_spart_drift_point(struct cell *c, void *data); +void cell_check_sink_drift_point(struct cell *c, void *data); void cell_check_multipole_drift_point(struct cell *c, void *data); void cell_reset_task_counters(struct cell *c); int cell_unskip_hydro_tasks(struct cell *c, struct scheduler *s); int cell_unskip_stars_tasks(struct cell *c, struct scheduler *s, const int with_star_formation); +int cell_unskip_sinks_tasks(struct cell *c, struct scheduler *s); int cell_unskip_black_holes_tasks(struct cell *c, struct scheduler *s); int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s); void cell_drift_part(struct cell *c, const struct engine *e, int force); void cell_drift_gpart(struct cell *c, const struct engine *e, int force); void cell_drift_spart(struct cell *c, const struct engine *e, int force); +void cell_drift_sink(struct cell *c, const struct engine *e, int force); void cell_drift_bpart(struct cell *c, const struct engine *e, int force); void cell_drift_multipole(struct cell *c, const struct engine *e); void cell_drift_all_multipoles(struct cell *c, const struct engine *e); @@ -977,6 +995,7 @@ void cell_activate_super_spart_drifts(struct cell *c, struct scheduler *s); void cell_activate_drift_part(struct cell *c, struct scheduler *s); void cell_activate_drift_gpart(struct cell *c, struct scheduler *s); void cell_activate_drift_spart(struct cell *c, struct scheduler *s); +void cell_activate_drift_sink(struct cell *c, struct scheduler *s); void cell_activate_drift_bpart(struct cell *c, struct scheduler *s); void cell_activate_sync_part(struct cell *c, struct scheduler *s); void cell_activate_hydro_sorts(struct cell *c, int sid, struct scheduler *s); @@ -1185,6 +1204,22 @@ cell_can_recurse_in_self_black_holes_task(const struct cell *c) { (kernel_gamma * c->hydro.h_max_old < 0.5f * c->dmin); } +/** + * @brief Can a sub-self sinks task recurse to a lower level based + * on the status of the particles in the cell. + * + * @param c The #cell. + */ +__attribute__((always_inline)) INLINE static int +cell_can_recurse_in_self_sinks_task(const struct cell *c) { + + /* Is the cell split and not smaller than the smoothing length? */ + // loic TODO: add cut off radius + return c->split && + //(kernel_gamma * c->sinks.h_max_old < 0.5f * c->dmin) && + (kernel_gamma * c->hydro.h_max_old < 0.5f * c->dmin); +} + /** * @brief Can a pair hydro task associated with a cell be split into smaller * sub-tasks. diff --git a/src/collectgroup.c b/src/collectgroup.c index 6aa120a5708df486229773c8ff9dde4f24180ccf..1c75d8c152472ff52b7e706cf6fd50469e0e80b1 100644 --- a/src/collectgroup.c +++ b/src/collectgroup.c @@ -37,19 +37,22 @@ /* Local collections for MPI reduces. */ struct mpicollectgroup1 { - long long updated, g_updated, s_updated, b_updated; - long long inhibited, g_inhibited, s_inhibited, b_inhibited; + long long updated, g_updated, s_updated, sink_updated, b_updated; + long long inhibited, g_inhibited, s_inhibited, sink_inhibited, b_inhibited; integertime_t ti_hydro_end_min; integertime_t ti_gravity_end_min; integertime_t ti_stars_end_min; + integertime_t ti_sinks_end_min; integertime_t ti_black_holes_end_min; integertime_t ti_hydro_end_max; integertime_t ti_gravity_end_max; integertime_t ti_stars_end_max; + integertime_t ti_sinks_end_max; integertime_t ti_black_holes_end_max; integertime_t ti_hydro_beg_max; integertime_t ti_gravity_beg_max; integertime_t ti_stars_beg_max; + integertime_t ti_sinks_beg_max; integertime_t ti_black_holes_beg_max; int forcerebuild; long long total_nr_cells; @@ -106,20 +109,30 @@ void collectgroup1_apply(const struct collectgroup1 *grp1, struct engine *e) { e->ti_black_holes_end_min = grp1->ti_black_holes_end_min; e->ti_black_holes_end_max = grp1->ti_black_holes_end_max; e->ti_black_holes_beg_max = grp1->ti_black_holes_beg_max; - e->ti_end_min = min4(e->ti_hydro_end_min, e->ti_gravity_end_min, - e->ti_stars_end_min, e->ti_black_holes_end_min); - e->ti_end_max = max4(e->ti_hydro_end_max, e->ti_gravity_end_max, - e->ti_stars_end_max, e->ti_black_holes_end_max); - e->ti_beg_max = max4(e->ti_hydro_beg_max, e->ti_gravity_beg_max, - e->ti_stars_beg_max, e->ti_black_holes_beg_max); + e->ti_sinks_end_min = grp1->ti_sinks_end_min; + e->ti_sinks_end_max = grp1->ti_sinks_end_max; + e->ti_sinks_beg_max = grp1->ti_sinks_beg_max; + + e->ti_end_min = + min5(e->ti_hydro_end_min, e->ti_gravity_end_min, e->ti_sinks_end_min, + e->ti_stars_end_min, e->ti_black_holes_end_min); + e->ti_end_max = + max5(e->ti_hydro_end_max, e->ti_gravity_end_max, e->ti_sinks_end_max, + e->ti_stars_end_max, e->ti_black_holes_end_max); + e->ti_beg_max = + max5(e->ti_hydro_beg_max, e->ti_gravity_beg_max, e->ti_sinks_beg_max, + e->ti_stars_beg_max, e->ti_black_holes_beg_max); + e->updates = grp1->updated; e->g_updates = grp1->g_updated; e->s_updates = grp1->s_updated; e->b_updates = grp1->b_updated; + e->sink_updates = grp1->sink_updated; e->nr_inhibited_parts = grp1->inhibited; e->nr_inhibited_gparts = grp1->g_inhibited; e->nr_inhibited_sparts = grp1->s_inhibited; e->nr_inhibited_bparts = grp1->b_inhibited; + e->nr_inhibited_sinks = grp1->sink_inhibited; e->forcerebuild = grp1->forcerebuild; e->total_nr_cells = grp1->total_nr_cells; e->total_nr_tasks = grp1->total_nr_tasks; @@ -138,6 +151,8 @@ void collectgroup1_apply(const struct collectgroup1 *grp1, struct engine *e) { * @param g_updated the number of updated gravity particles on this node this * step. * @param s_updated the number of updated star particles on this node this step. + * @param sink_updated the number of updated sink particles on this node this + * step. * @param b_updated the number of updated black hole particles on this node this * step. * @param inhibited the number of inhibited hydro particles on this node this @@ -146,6 +161,8 @@ void collectgroup1_apply(const struct collectgroup1 *grp1, struct engine *e) { * this step. * @param s_inhibited the number of inhibited star particles on this node this * step. + * @param sink_inhibited the number of inhibited sink particles on this node + * this step. * @param b_inhibited the number of inhibited black hole particles on this node * this step. * @param ti_hydro_end_min the minimum end time for next hydro time step after @@ -166,6 +183,12 @@ void collectgroup1_apply(const struct collectgroup1 *grp1, struct engine *e) { * after this step. * @param ti_stars_beg_max the maximum begin time for next stars time step * after this step. + * @param ti_sinks_end_min the minimum end time for next sinks time step + * after this step. + * @param ti_sinks_end_max the maximum end time for next sinks time step + * after this step. + * @param ti_sinks_beg_max the maximum begin time for next sinks time step + * after this step. * @param ti_black_holes_end_min the minimum end time for next black holes time * step after this step. * @param ti_black_holes_end_max the maximum end time for next black holes time @@ -181,25 +204,30 @@ void collectgroup1_apply(const struct collectgroup1 *grp1, struct engine *e) { */ void collectgroup1_init( struct collectgroup1 *grp1, size_t updated, size_t g_updated, - size_t s_updated, size_t b_updated, size_t inhibited, size_t g_inhibited, - size_t s_inhibited, size_t b_inhibited, integertime_t ti_hydro_end_min, + size_t s_updated, size_t sink_updated, size_t b_updated, size_t inhibited, + size_t g_inhibited, size_t s_inhibited, size_t b_inhibited, + size_t sink_inhibited, integertime_t ti_hydro_end_min, integertime_t ti_hydro_end_max, integertime_t ti_hydro_beg_max, integertime_t ti_gravity_end_min, integertime_t ti_gravity_end_max, integertime_t ti_gravity_beg_max, integertime_t ti_stars_end_min, integertime_t ti_stars_end_max, integertime_t ti_stars_beg_max, - integertime_t ti_black_holes_end_min, integertime_t ti_black_holes_end_max, - integertime_t ti_black_holes_beg_max, int forcerebuild, - long long total_nr_cells, long long total_nr_tasks, float tasks_per_cell, - const struct star_formation_history sfh, float runtime) { + integertime_t ti_sinks_end_min, integertime_t ti_sinks_end_max, + integertime_t ti_sinks_beg_max, integertime_t ti_black_holes_end_min, + integertime_t ti_black_holes_end_max, integertime_t ti_black_holes_beg_max, + int forcerebuild, long long total_nr_cells, long long total_nr_tasks, + float tasks_per_cell, const struct star_formation_history sfh, + float runtime) { grp1->updated = updated; grp1->g_updated = g_updated; grp1->s_updated = s_updated; grp1->b_updated = b_updated; + grp1->sink_updated = sink_updated; grp1->inhibited = inhibited; grp1->g_inhibited = g_inhibited; grp1->s_inhibited = s_inhibited; grp1->b_inhibited = b_inhibited; + grp1->sink_inhibited = sink_inhibited; grp1->ti_hydro_end_min = ti_hydro_end_min; grp1->ti_hydro_end_max = ti_hydro_end_max; grp1->ti_hydro_beg_max = ti_hydro_beg_max; @@ -212,6 +240,9 @@ void collectgroup1_init( grp1->ti_black_holes_end_min = ti_black_holes_end_min; grp1->ti_black_holes_end_max = ti_black_holes_end_max; grp1->ti_black_holes_beg_max = ti_black_holes_beg_max; + grp1->ti_sinks_end_min = ti_sinks_end_min; + grp1->ti_sinks_end_max = ti_sinks_end_max; + grp1->ti_sinks_beg_max = ti_sinks_beg_max; grp1->forcerebuild = forcerebuild; grp1->total_nr_cells = total_nr_cells; grp1->total_nr_tasks = total_nr_tasks; @@ -237,22 +268,27 @@ void collectgroup1_reduce(struct collectgroup1 *grp1) { mpigrp11.updated = grp1->updated; mpigrp11.g_updated = grp1->g_updated; mpigrp11.s_updated = grp1->s_updated; + mpigrp11.sink_updated = grp1->sink_updated; mpigrp11.b_updated = grp1->b_updated; mpigrp11.inhibited = grp1->inhibited; mpigrp11.g_inhibited = grp1->g_inhibited; mpigrp11.s_inhibited = grp1->s_inhibited; + mpigrp11.sink_inhibited = grp1->sink_inhibited; mpigrp11.b_inhibited = grp1->b_inhibited; mpigrp11.ti_hydro_end_min = grp1->ti_hydro_end_min; mpigrp11.ti_gravity_end_min = grp1->ti_gravity_end_min; mpigrp11.ti_stars_end_min = grp1->ti_stars_end_min; + mpigrp11.ti_sinks_end_min = grp1->ti_sinks_end_min; mpigrp11.ti_black_holes_end_min = grp1->ti_black_holes_end_min; mpigrp11.ti_hydro_end_max = grp1->ti_hydro_end_max; mpigrp11.ti_gravity_end_max = grp1->ti_gravity_end_max; mpigrp11.ti_stars_end_max = grp1->ti_stars_end_max; + mpigrp11.ti_sinks_end_max = grp1->ti_sinks_end_max; mpigrp11.ti_black_holes_end_max = grp1->ti_black_holes_end_max; mpigrp11.ti_hydro_beg_max = grp1->ti_hydro_beg_max; mpigrp11.ti_gravity_beg_max = grp1->ti_gravity_beg_max; mpigrp11.ti_stars_beg_max = grp1->ti_stars_beg_max; + mpigrp11.ti_sinks_beg_max = grp1->ti_sinks_beg_max; mpigrp11.ti_black_holes_beg_max = grp1->ti_black_holes_beg_max; mpigrp11.forcerebuild = grp1->forcerebuild; mpigrp11.total_nr_cells = grp1->total_nr_cells; @@ -269,23 +305,28 @@ void collectgroup1_reduce(struct collectgroup1 *grp1) { /* And update. */ grp1->updated = mpigrp12.updated; grp1->g_updated = mpigrp12.g_updated; + grp1->sink_updated = mpigrp12.sink_updated; grp1->s_updated = mpigrp12.s_updated; grp1->b_updated = mpigrp12.b_updated; grp1->inhibited = mpigrp12.inhibited; grp1->g_inhibited = mpigrp12.g_inhibited; grp1->s_inhibited = mpigrp12.s_inhibited; + grp1->sink_inhibited = mpigrp12.sink_inhibited; grp1->b_inhibited = mpigrp12.b_inhibited; grp1->ti_hydro_end_min = mpigrp12.ti_hydro_end_min; grp1->ti_gravity_end_min = mpigrp12.ti_gravity_end_min; grp1->ti_stars_end_min = mpigrp12.ti_stars_end_min; + grp1->ti_sinks_end_min = mpigrp12.ti_sinks_end_min; grp1->ti_black_holes_end_min = mpigrp12.ti_black_holes_end_min; grp1->ti_hydro_end_max = mpigrp12.ti_hydro_end_max; grp1->ti_gravity_end_max = mpigrp12.ti_gravity_end_max; grp1->ti_stars_end_max = mpigrp12.ti_stars_end_max; + grp1->ti_sinks_end_max = mpigrp12.ti_sinks_end_max; grp1->ti_black_holes_end_max = mpigrp12.ti_black_holes_end_max; grp1->ti_hydro_beg_max = mpigrp12.ti_hydro_beg_max; grp1->ti_gravity_beg_max = mpigrp12.ti_gravity_beg_max; grp1->ti_stars_beg_max = mpigrp12.ti_stars_beg_max; + grp1->ti_sinks_beg_max = mpigrp12.ti_sinks_beg_max; grp1->ti_black_holes_beg_max = mpigrp12.ti_black_holes_beg_max; grp1->forcerebuild = mpigrp12.forcerebuild; grp1->total_nr_cells = mpigrp12.total_nr_cells; @@ -312,12 +353,14 @@ static void doreduce1(struct mpicollectgroup1 *mpigrp11, mpigrp11->updated += mpigrp12->updated; mpigrp11->g_updated += mpigrp12->g_updated; mpigrp11->s_updated += mpigrp12->s_updated; + mpigrp11->sink_updated += mpigrp12->sink_updated; mpigrp11->b_updated += mpigrp12->b_updated; /* Sum of inhibited */ mpigrp11->inhibited += mpigrp12->inhibited; mpigrp11->g_inhibited += mpigrp12->g_inhibited; mpigrp11->s_inhibited += mpigrp12->s_inhibited; + mpigrp11->sink_inhibited += mpigrp12->sink_inhibited; mpigrp11->b_inhibited += mpigrp12->b_inhibited; /* Minimum end time. */ @@ -327,6 +370,8 @@ static void doreduce1(struct mpicollectgroup1 *mpigrp11, min(mpigrp11->ti_gravity_end_min, mpigrp12->ti_gravity_end_min); mpigrp11->ti_stars_end_min = min(mpigrp11->ti_stars_end_min, mpigrp12->ti_stars_end_min); + mpigrp11->ti_sinks_end_min = + min(mpigrp11->ti_sinks_end_min, mpigrp12->ti_sinks_end_min); mpigrp11->ti_black_holes_end_min = min(mpigrp11->ti_black_holes_end_min, mpigrp12->ti_black_holes_end_min); @@ -337,6 +382,8 @@ static void doreduce1(struct mpicollectgroup1 *mpigrp11, max(mpigrp11->ti_gravity_end_max, mpigrp12->ti_gravity_end_max); mpigrp11->ti_stars_end_max = max(mpigrp11->ti_stars_end_max, mpigrp12->ti_stars_end_max); + mpigrp11->ti_sinks_end_max = + max(mpigrp11->ti_sinks_end_max, mpigrp12->ti_sinks_end_max); mpigrp11->ti_black_holes_end_max = max(mpigrp11->ti_black_holes_end_max, mpigrp12->ti_black_holes_end_max); @@ -347,6 +394,8 @@ static void doreduce1(struct mpicollectgroup1 *mpigrp11, max(mpigrp11->ti_gravity_beg_max, mpigrp12->ti_gravity_beg_max); mpigrp11->ti_stars_beg_max = max(mpigrp11->ti_stars_beg_max, mpigrp12->ti_stars_beg_max); + mpigrp11->ti_sinks_beg_max = + max(mpigrp11->ti_sinks_beg_max, mpigrp12->ti_sinks_beg_max); mpigrp11->ti_black_holes_beg_max = max(mpigrp11->ti_black_holes_beg_max, mpigrp12->ti_black_holes_beg_max); diff --git a/src/collectgroup.h b/src/collectgroup.h index fcb49fe0596b23125525c944fa9bfa80418f5b80..99229a257f8544bac749dc330a6255698a12f3da 100644 --- a/src/collectgroup.h +++ b/src/collectgroup.h @@ -36,10 +36,10 @@ struct engine; struct collectgroup1 { /* Number of particles updated */ - long long updated, g_updated, s_updated, b_updated; + long long updated, g_updated, s_updated, b_updated, sink_updated; /* Number of particles inhibited */ - long long inhibited, g_inhibited, s_inhibited, b_inhibited; + long long inhibited, g_inhibited, s_inhibited, b_inhibited, sink_inhibited; /* SFH logger */ struct star_formation_history sfh; @@ -50,6 +50,7 @@ struct collectgroup1 { integertime_t ti_stars_end_min, ti_stars_end_max, ti_stars_beg_max; integertime_t ti_black_holes_end_min, ti_black_holes_end_max, ti_black_holes_beg_max; + integertime_t ti_sinks_end_min, ti_sinks_end_max, ti_sinks_beg_max; /* Force the engine to rebuild? */ int forcerebuild; @@ -69,16 +70,19 @@ void collectgroup_init(void); void collectgroup1_apply(const struct collectgroup1 *grp1, struct engine *e); void collectgroup1_init( struct collectgroup1 *grp1, size_t updated, size_t g_updated, - size_t s_updated, size_t b_updated, size_t inhibited, size_t g_inhibited, - size_t s_inhibited, size_t b_inhibited, integertime_t ti_hydro_end_min, + size_t s_updated, size_t b_updated, size_t sink_updated, size_t inhibited, + size_t g_inhibited, size_t s_inhibited, size_t sink_inhibited, + size_t b_inhibited, integertime_t ti_hydro_end_min, integertime_t ti_hydro_end_max, integertime_t ti_hydro_beg_max, integertime_t ti_gravity_end_min, integertime_t ti_gravity_end_max, integertime_t ti_gravity_beg_max, integertime_t ti_stars_end_min, integertime_t ti_stars_end_max, integertime_t ti_stars_beg_max, - integertime_t ti_black_holes_end_min, integertime_t ti_black_holes_end_max, - integertime_t ti_black_holes_beg_max, int forcerebuild, - long long total_nr_cells, long long total_nr_tasks, float tasks_per_cell, - const struct star_formation_history sfh, float runtime); + integertime_t ti_sinks_end_min, integertime_t ti_sinks_end_max, + integertime_t ti_sinks_beg_max, integertime_t ti_black_holes_end_min, + integertime_t ti_black_holes_end_max, integertime_t ti_black_holes_beg_max, + int forcerebuild, long long total_nr_cells, long long total_nr_tasks, + float tasks_per_cell, const struct star_formation_history sfh, + float runtime); void collectgroup1_reduce(struct collectgroup1 *grp1); #ifdef WITH_MPI void mpicollect_free_MPI_type(void); diff --git a/src/common_io.c b/src/common_io.c index 5db398c71e081ef34fd89240fbd66fe38266e923..8bc4cdc803709642d3e81c1e4b50a63ee3a2c554 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -2883,9 +2883,6 @@ int get_ptype_fields(const int ptype, struct io_props* list, num_fields += velociraptor_write_gparts(NULL, list + num_fields); break; - case 3: - break; - case swift_type_stars: stars_write_particles(NULL, list, &num_fields, with_cosmology); num_fields += chemistry_write_sparticles(NULL, list + num_fields); @@ -2897,6 +2894,10 @@ int get_ptype_fields(const int ptype, struct io_props* list, num_fields += velociraptor_write_sparts(NULL, list + num_fields); break; + case swift_type_sink: + sink_write_particles(NULL, list, &num_fields, with_cosmology); + 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); diff --git a/src/engine.c b/src/engine.c index bfd5a542ec19eae11f24dbaa35569480cde81cce..662979c3cd49e214fb1b5a436d90626d67a90632 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1591,6 +1591,10 @@ int engine_estimate_nr_tasks(const struct engine *e) { n1 += 6; #endif } + if (e->policy & engine_policy_sinks) { + /* 1 drift, 2 kicks, 1 time-step */ + n1 += 4; + } if (e->policy & engine_policy_fof) { n1 += 2; } @@ -1697,46 +1701,52 @@ void engine_rebuild(struct engine *e, const int repartitioned, /* Report the number of particles and memory */ if (e->verbose) message( - "Space has memory for %zd/%zd/%zd/%zd part/gpart/spart/bpart " - "(%zd/%zd/%zd/%zd MB)", + "Space has memory for %zd/%zd/%zd/%zd/%zd part/gpart/spart/sink/bpart " + "(%zd/%zd/%zd/%zd/%zd MB)", e->s->size_parts, e->s->size_gparts, e->s->size_sparts, - e->s->size_bparts, + e->s->size_sinks, e->s->size_bparts, e->s->size_parts * sizeof(struct part) / (1024 * 1024), e->s->size_gparts * sizeof(struct gpart) / (1024 * 1024), e->s->size_sparts * sizeof(struct spart) / (1024 * 1024), + e->s->size_sinks * sizeof(struct sink) / (1024 * 1024), e->s->size_bparts * sizeof(struct bpart) / (1024 * 1024)); if (e->verbose) message( - "Space holds %zd/%zd/%zd/%zd part/gpart/spart/bpart (fracs: " - "%f/%f/%f/%f)", - e->s->nr_parts, e->s->nr_gparts, e->s->nr_sparts, e->s->nr_bparts, + "Space holds %zd/%zd/%zd/%zd/%zd part/gpart/spart/sink/bpart (fracs: " + "%f/%f/%f/%f/%f)", + e->s->nr_parts, e->s->nr_gparts, e->s->nr_sparts, e->s->nr_sinks, + e->s->nr_bparts, e->s->nr_parts ? e->s->nr_parts / ((double)e->s->size_parts) : 0., e->s->nr_gparts ? e->s->nr_gparts / ((double)e->s->size_gparts) : 0., e->s->nr_sparts ? e->s->nr_sparts / ((double)e->s->size_sparts) : 0., + e->s->nr_sinks ? e->s->nr_sinks / ((double)e->s->size_sinks) : 0., e->s->nr_bparts ? e->s->nr_bparts / ((double)e->s->size_bparts) : 0.); const ticks tic2 = getticks(); /* Update the global counters of particles */ - long long num_particles[4] = { + long long num_particles[5] = { (long long)(e->s->nr_parts - e->s->nr_extra_parts), (long long)(e->s->nr_gparts - e->s->nr_extra_gparts), (long long)(e->s->nr_sparts - e->s->nr_extra_sparts), + (long long)(e->s->nr_sinks - e->s->nr_extra_sinks), (long long)(e->s->nr_bparts - e->s->nr_extra_bparts)}; #ifdef WITH_MPI - MPI_Allreduce(MPI_IN_PLACE, num_particles, 4, MPI_LONG_LONG, MPI_SUM, + MPI_Allreduce(MPI_IN_PLACE, num_particles, 5, MPI_LONG_LONG, MPI_SUM, MPI_COMM_WORLD); #endif e->total_nr_parts = num_particles[0]; e->total_nr_gparts = num_particles[1]; e->total_nr_sparts = num_particles[2]; - e->total_nr_bparts = num_particles[3]; + e->total_nr_sinks = num_particles[3]; + e->total_nr_bparts = num_particles[4]; /* Flag that there are no inhibited particles */ e->nr_inhibited_parts = 0; e->nr_inhibited_gparts = 0; e->nr_inhibited_sparts = 0; + e->nr_inhibited_sinks = 0; e->nr_inhibited_bparts = 0; if (e->verbose) @@ -1822,6 +1832,7 @@ void engine_rebuild(struct engine *e, const int repartitioned, e->updates_since_rebuild = 0; e->g_updates_since_rebuild = 0; e->s_updates_since_rebuild = 0; + e->sink_updates_since_rebuild = 0; e->b_updates_since_rebuild = 0; /* Flag that a rebuild has taken place */ @@ -2031,8 +2042,8 @@ void engine_skip_force_and_kick(struct engine *e) { /* Skip everything that updates the particles */ if (t->type == task_type_drift_part || t->type == task_type_drift_gpart || t->type == task_type_drift_spart || t->type == task_type_drift_bpart || - t->type == task_type_kick1 || t->type == task_type_kick2 || - t->type == task_type_timestep || + t->type == task_type_drift_sink || t->type == task_type_kick1 || + t->type == task_type_kick2 || t->type == task_type_timestep || t->type == task_type_timestep_limiter || t->type == task_type_timestep_sync || t->type == task_type_end_hydro_force || t->type == task_type_cooling || @@ -2061,6 +2072,7 @@ void engine_skip_force_and_kick(struct engine *e) { t->subtype == task_subtype_tend_part || t->subtype == task_subtype_tend_gpart || t->subtype == task_subtype_tend_spart || + t->subtype == task_subtype_tend_sink || t->subtype == task_subtype_tend_bpart || t->subtype == task_subtype_rho || t->subtype == task_subtype_sf_counts) t->skip = 1; @@ -2087,7 +2099,8 @@ void engine_skip_drift(struct engine *e) { /* Skip everything that moves the particles */ if (t->type == task_type_drift_part || t->type == task_type_drift_gpart || - t->type == task_type_drift_spart || t->type == task_type_drift_bpart) + t->type == task_type_drift_spart || t->type == task_type_drift_bpart || + t->type == task_type_drift_sink) t->skip = 1; } @@ -2473,10 +2486,11 @@ void engine_step(struct engine *e) { /* Print some information to the screen */ printf( " %6d %14e %12.7f %12.7f %14e %4d %4d %12lld %12lld %12lld " - "%12lld %21.3f %6d\n", + "%12lld %12lld %21.3f %6d\n", e->step, e->time, e->cosmology->a, e->cosmology->z, e->time_step, e->min_active_bin, e->max_active_bin, e->updates, e->g_updates, - e->s_updates, e->b_updates, e->wallclock_time, e->step_props); + e->s_updates, e->sink_updates, e->b_updates, e->wallclock_time, + e->step_props); #ifdef SWIFT_DEBUG_CHECKS fflush(stdout); #endif @@ -2499,10 +2513,11 @@ void engine_step(struct engine *e) { fprintf( e->file_timesteps, " %6d %14e %12.7f %12.7f %14e %4d %4d %12lld %12lld %12lld %12lld " - "%21.3f %6d\n", + "%12lld %21.3f %6d\n", e->step, e->time, e->cosmology->a, e->cosmology->z, e->time_step, e->min_active_bin, e->max_active_bin, e->updates, e->g_updates, - e->s_updates, e->b_updates, e->wallclock_time, e->step_props); + e->s_updates, e->sink_updates, e->b_updates, e->wallclock_time, + e->step_props); #ifdef SWIFT_DEBUG_CHECKS fflush(e->file_timesteps); #endif @@ -2731,6 +2746,7 @@ void engine_step(struct engine *e) { e->updates_since_rebuild += e->collect_group1.updated; e->g_updates_since_rebuild += e->collect_group1.g_updated; e->s_updates_since_rebuild += e->collect_group1.s_updated; + e->sink_updates_since_rebuild += e->collect_group1.sink_updated; e->b_updates_since_rebuild += e->collect_group1.b_updated; #ifdef SWIFT_DEBUG_CHECKS @@ -4323,12 +4339,12 @@ void engine_config(int restart, int fof, struct engine *e, engine_step_prop_stf, engine_step_prop_fof, engine_step_prop_logger_index); - fprintf( - e->file_timesteps, - "# %6s %14s %12s %12s %14s %9s %12s %12s %12s %12s %16s [%s] %6s\n", - "Step", "Time", "Scale-factor", "Redshift", "Time-step", "Time-bins", - "Updates", "g-Updates", "s-Updates", "b-Updates", "Wall-clock time", - clocks_getunit(), "Props"); + fprintf(e->file_timesteps, + "# %6s %14s %12s %12s %14s %9s %12s %12s %12s %12s %12s %16s " + "[%s] %6s\n", + "Step", "Time", "Scale-factor", "Redshift", "Time-step", + "Time-bins", "Updates", "g-Updates", "s-Updates", "Sink-Updates", + "b-Updates", "Wall-clock time", clocks_getunit(), "Props"); fflush(e->file_timesteps); } @@ -5214,8 +5230,8 @@ void engine_recompute_displacement_constraint(struct engine *e) { /* Start by reducing the minimal mass of each particle type */ float min_mass[swift_type_count] = { - e->s->min_part_mass, e->s->min_gpart_mass, FLT_MAX, FLT_MAX, - e->s->min_spart_mass, e->s->min_bpart_mass}; + e->s->min_part_mass, e->s->min_gpart_mass, FLT_MAX, + e->s->min_sink_mass, e->s->min_spart_mass, e->s->min_bpart_mass}; #ifdef WITH_MPI MPI_Allreduce(MPI_IN_PLACE, min_mass, swift_type_count, MPI_FLOAT, MPI_MIN, @@ -5235,9 +5251,12 @@ void engine_recompute_displacement_constraint(struct engine *e) { #endif /* Do the same for the velocity norm sum */ - float vel_norm[swift_type_count] = { - e->s->sum_part_vel_norm, e->s->sum_gpart_vel_norm, 0.f, 0.f, - e->s->sum_spart_vel_norm, e->s->sum_spart_vel_norm}; + float vel_norm[swift_type_count] = {e->s->sum_part_vel_norm, + e->s->sum_gpart_vel_norm, + 0.f, + e->s->sum_sink_vel_norm, + e->s->sum_spart_vel_norm, + e->s->sum_spart_vel_norm}; #ifdef WITH_MPI MPI_Allreduce(MPI_IN_PLACE, vel_norm, swift_type_count, MPI_FLOAT, MPI_SUM, MPI_COMM_WORLD); @@ -5252,17 +5271,19 @@ void engine_recompute_displacement_constraint(struct engine *e) { (float)e->total_nr_parts, (float)total_nr_dm_gparts, (float)e->total_nr_DM_background_gparts, - 0.f, + (float)e->total_nr_sinks, (float)e->total_nr_sparts, (float)e->total_nr_bparts}; /* Count of particles for the two species */ const float N_dm = count_parts[1]; - const float N_b = count_parts[0] + count_parts[4] + count_parts[5]; + const float N_b = + count_parts[0] + count_parts[3] + count_parts[4] + count_parts[5]; /* Peculiar motion norm for the two species */ const float vel_norm_dm = vel_norm[1]; - const float vel_norm_b = vel_norm[0] + vel_norm[4] + vel_norm[5]; + const float vel_norm_b = + vel_norm[0] + vel_norm[3] + vel_norm[4] + vel_norm[5]; /* Mesh forces smoothing scale */ float r_s; @@ -5293,7 +5314,8 @@ void engine_recompute_displacement_constraint(struct engine *e) { if (N_b > 0.f) { /* Minimal mass for the baryons */ - const float min_mass_b = min3(min_mass[0], min_mass[4], min_mass[5]); + const float min_mass_b = + min4(min_mass[0], min_mass[3], min_mass[4], min_mass[5]); /* Inter-particle sepration for the baryons */ const float d_b = cbrtf(min_mass_b / (Ob * rho_crit0)); diff --git a/src/engine.h b/src/engine.h index 9dae02eef75004b4afc1e347a8453b0a465e8307..9f9c04fa20d4029db726e66ec340a7f56ad08381 100644 --- a/src/engine.h +++ b/src/engine.h @@ -81,7 +81,7 @@ enum engine_policy { engine_policy_timestep_sync = (1 << 22), engine_policy_logger = (1 << 23), engine_policy_line_of_sight = (1 << 24), - engine_policy_sink = (1 << 25), + engine_policy_sinks = (1 << 25), engine_policy_rt = (1 << 26), }; #define engine_maxpolicy 27 @@ -224,6 +224,15 @@ struct engine { /* Maximal black holes ti_beg for the next time-step */ integertime_t ti_black_holes_beg_max; + /* Minimal sinks ti_end for the next time-step */ + integertime_t ti_sinks_end_min; + + /* Maximal sinks ti_end for the next time-step */ + integertime_t ti_sinks_end_max; + + /* Maximal sinks ti_beg for the next time-step */ + integertime_t ti_sinks_beg_max; + /* Minimal overall ti_end for the next time-step */ integertime_t ti_end_min; @@ -234,12 +243,13 @@ struct engine { integertime_t ti_beg_max; /* Number of particles updated in the previous step */ - long long updates, g_updates, s_updates, b_updates; + long long updates, g_updates, s_updates, b_updates, sink_updates; /* Number of updates since the last rebuild */ long long updates_since_rebuild; long long g_updates_since_rebuild; long long s_updates_since_rebuild; + long long sink_updates_since_rebuild; long long b_updates_since_rebuild; /* Star formation logger information */ @@ -252,6 +262,7 @@ struct engine { long long total_nr_parts; long long total_nr_gparts; long long total_nr_sparts; + long long total_nr_sinks; long long total_nr_bparts; long long total_nr_DM_background_gparts; @@ -265,6 +276,7 @@ struct engine { long long nr_inhibited_parts; long long nr_inhibited_gparts; long long nr_inhibited_sparts; + long long nr_inhibited_sinks; long long nr_inhibited_bparts; #ifdef SWIFT_DEBUG_CHECKS @@ -510,9 +522,6 @@ struct engine { integertime_t ti_next_los; int los_output_count; - /* Total number of sink particles in the system. */ - long long total_nr_sinks; - #ifdef SWIFT_GRAVITY_FORCE_CHECKS /* Run brute force checks only on steps when all gparts active? */ int force_checks_only_all_active; diff --git a/src/engine_collect_end_of_step.c b/src/engine_collect_end_of_step.c index 0973399c11146baef3b3be60b3635426021b23cb..4281379f98b70b8f3ce169822fa435aad2557708 100644 --- a/src/engine_collect_end_of_step.c +++ b/src/engine_collect_end_of_step.c @@ -35,11 +35,12 @@ */ struct end_of_step_data { - size_t updated, g_updated, s_updated, b_updated; - size_t inhibited, g_inhibited, s_inhibited, b_inhibited; + size_t updated, g_updated, s_updated, sink_updated, b_updated; + size_t inhibited, g_inhibited, s_inhibited, sink_inhibited, b_inhibited; integertime_t ti_hydro_end_min, ti_hydro_end_max, ti_hydro_beg_max; integertime_t ti_gravity_end_min, ti_gravity_end_max, ti_gravity_beg_max; integertime_t ti_stars_end_min, ti_stars_end_max, ti_stars_beg_max; + integertime_t ti_sinks_end_min, ti_sinks_end_max, ti_sinks_beg_max; integertime_t ti_black_holes_end_min, ti_black_holes_end_max, ti_black_holes_beg_max; struct engine *e; @@ -273,6 +274,61 @@ void engine_collect_end_of_step_recurse_black_holes(struct cell *c, c->black_holes.updated = updated; } +/** + * @brief Recursive function gathering end-of-step data. + * + * We recurse until we encounter a timestep or time-step MPI recv task + * as the values will have been set at that level. We then bring these + * values upwards. + * + * @param c The #cell to recurse into. + * @param e The #engine. + */ +void engine_collect_end_of_step_recurse_sinks(struct cell *c, + const struct engine *e) { + + /* Skip super-cells (Their values are already set) */ + if (c->timestep != NULL) return; +#ifdef WITH_MPI + if (cell_get_recv(c, task_subtype_tend_sink) != NULL) return; +#endif /* WITH_MPI */ + +#ifdef SWIFT_DEBUG_CHECKS + // if (!c->split) error("Reached a leaf without finding a time-step task!"); +#endif + + /* Counters for the different quantities. */ + size_t updated = 0; + integertime_t ti_sinks_end_min = max_nr_timesteps, ti_sinks_end_max = 0, + ti_sinks_beg_max = 0; + + /* Collect the values from the progeny. */ + for (int k = 0; k < 8; k++) { + struct cell *cp = c->progeny[k]; + if (cp != NULL && cp->sinks.count > 0) { + + /* Recurse */ + engine_collect_end_of_step_recurse_sinks(cp, e); + + /* And update */ + ti_sinks_end_min = min(ti_sinks_end_min, cp->sinks.ti_end_min); + ti_sinks_end_max = max(ti_sinks_end_max, cp->sinks.ti_end_max); + ti_sinks_beg_max = max(ti_sinks_beg_max, cp->sinks.ti_beg_max); + + updated += cp->sinks.updated; + + /* Collected, so clear for next time. */ + cp->sinks.updated = 0; + } + } + + /* Store the collected values in the cell. */ + c->sinks.ti_end_min = ti_sinks_end_min; + c->sinks.ti_end_max = ti_sinks_end_max; + c->sinks.ti_beg_max = ti_sinks_beg_max; + c->sinks.updated = updated; +} + /** * @brief Mapping function to collect the data from the end of the step * @@ -294,19 +350,23 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, const int with_ext_grav = (e->policy & engine_policy_external_gravity); const int with_grav = (with_self_grav || with_ext_grav); const int with_stars = (e->policy & engine_policy_stars); + const int with_sinks = (e->policy & engine_policy_sinks); const int with_black_holes = (e->policy & engine_policy_black_holes); struct space *s = e->s; int *local_cells = (int *)map_data; struct star_formation_history *sfh_top = &data->sfh; /* Local collectible */ - size_t updated = 0, g_updated = 0, s_updated = 0, b_updated = 0; + size_t updated = 0, g_updated = 0, s_updated = 0, sink_updated = 0, + b_updated = 0; integertime_t ti_hydro_end_min = max_nr_timesteps, ti_hydro_end_max = 0, ti_hydro_beg_max = 0; integertime_t ti_gravity_end_min = max_nr_timesteps, ti_gravity_end_max = 0, ti_gravity_beg_max = 0; integertime_t ti_stars_end_min = max_nr_timesteps, ti_stars_end_max = 0, ti_stars_beg_max = 0; + integertime_t ti_sinks_end_min = max_nr_timesteps, ti_sinks_end_max = 0, + ti_sinks_beg_max = 0; integertime_t ti_black_holes_end_min = max_nr_timesteps, ti_black_holes_end_max = 0, ti_black_holes_beg_max = 0; @@ -320,7 +380,7 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, struct cell *c = &s->cells_top[local_cells[ind]]; if (c->hydro.count > 0 || c->grav.count > 0 || c->stars.count > 0 || - c->black_holes.count > 0) { + c->black_holes.count > 0 || c->sinks.count > 0) { /* Make the top-cells recurse */ if (with_hydro) { @@ -332,6 +392,9 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, if (with_stars) { engine_collect_end_of_step_recurse_stars(c, e); } + if (with_sinks) { + engine_collect_end_of_step_recurse_sinks(c, e); + } if (with_black_holes) { engine_collect_end_of_step_recurse_black_holes(c, e); } @@ -352,6 +415,11 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, ti_stars_end_max = max(ti_stars_end_max, c->stars.ti_end_max); ti_stars_beg_max = max(ti_stars_beg_max, c->stars.ti_beg_max); + if (c->sinks.ti_end_min > e->ti_current) + ti_sinks_end_min = min(ti_sinks_end_min, c->sinks.ti_end_min); + ti_sinks_end_max = max(ti_sinks_end_max, c->sinks.ti_end_max); + ti_sinks_beg_max = max(ti_sinks_beg_max, c->sinks.ti_beg_max); + if (c->black_holes.ti_end_min > e->ti_current) ti_black_holes_end_min = min(ti_black_holes_end_min, c->black_holes.ti_end_min); @@ -363,6 +431,7 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, updated += c->hydro.updated; g_updated += c->grav.updated; s_updated += c->stars.updated; + sink_updated += c->sinks.updated; b_updated += c->black_holes.updated; /* Check if the cell was inactive and in that case reorder the SFH */ @@ -378,6 +447,7 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, c->hydro.updated = 0; c->grav.updated = 0; c->stars.updated = 0; + c->sinks.updated = 0; c->black_holes.updated = 0; } } @@ -388,6 +458,7 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, data->updated += updated; data->g_updated += g_updated; data->s_updated += s_updated; + data->sink_updated += sink_updated; data->b_updated += b_updated; /* Add the SFH information from this engine to the global data */ @@ -411,6 +482,11 @@ void engine_collect_end_of_step_mapper(void *map_data, int num_elements, data->ti_stars_end_max = max(ti_stars_end_max, data->ti_stars_end_max); data->ti_stars_beg_max = max(ti_stars_beg_max, data->ti_stars_beg_max); + if (ti_sinks_end_min > e->ti_current) + data->ti_sinks_end_min = min(ti_sinks_end_min, data->ti_sinks_end_min); + data->ti_sinks_end_max = max(ti_sinks_end_max, data->ti_sinks_end_max); + data->ti_sinks_beg_max = max(ti_sinks_beg_max, data->ti_sinks_beg_max); + if (ti_black_holes_end_min > e->ti_current) data->ti_black_holes_end_min = min(ti_black_holes_end_min, data->ti_black_holes_end_min); @@ -446,12 +522,15 @@ void engine_collect_end_of_step(struct engine *e, int apply) { struct space *s = e->s; struct end_of_step_data data; data.updated = 0, data.g_updated = 0, data.s_updated = 0, data.b_updated = 0; + data.sink_updated = 0; data.ti_hydro_end_min = max_nr_timesteps, data.ti_hydro_end_max = 0, data.ti_hydro_beg_max = 0; data.ti_gravity_end_min = max_nr_timesteps, data.ti_gravity_end_max = 0, data.ti_gravity_beg_max = 0; data.ti_stars_end_min = max_nr_timesteps, data.ti_stars_end_max = 0, data.ti_stars_beg_max = 0; + data.ti_sinks_end_min = max_nr_timesteps, data.ti_sinks_end_max = 0, + data.ti_sinks_beg_max = 0; data.ti_black_holes_end_min = max_nr_timesteps, data.ti_black_holes_end_max = 0, data.ti_black_holes_beg_max = 0; data.e = e; @@ -472,20 +551,22 @@ void engine_collect_end_of_step(struct engine *e, int apply) { data.inhibited = s->nr_inhibited_parts; data.g_inhibited = s->nr_inhibited_gparts; data.s_inhibited = s->nr_inhibited_sparts; + data.sink_inhibited = s->nr_inhibited_sinks; data.b_inhibited = s->nr_inhibited_bparts; /* Store these in the temporary collection group. */ collectgroup1_init( &e->collect_group1, data.updated, data.g_updated, data.s_updated, - data.b_updated, data.inhibited, data.g_inhibited, data.s_inhibited, - data.b_inhibited, data.ti_hydro_end_min, data.ti_hydro_end_max, - data.ti_hydro_beg_max, data.ti_gravity_end_min, data.ti_gravity_end_max, - data.ti_gravity_beg_max, data.ti_stars_end_min, data.ti_stars_end_max, - data.ti_stars_beg_max, data.ti_black_holes_end_min, - data.ti_black_holes_end_max, data.ti_black_holes_beg_max, e->forcerebuild, - e->s->tot_cells, e->sched.nr_tasks, - (float)e->sched.nr_tasks / (float)e->s->tot_cells, data.sfh, - data.runtime); + data.sink_updated, data.b_updated, data.inhibited, data.g_inhibited, + data.s_inhibited, data.sink_inhibited, data.b_inhibited, + data.ti_hydro_end_min, data.ti_hydro_end_max, data.ti_hydro_beg_max, + data.ti_gravity_end_min, data.ti_gravity_end_max, data.ti_gravity_beg_max, + data.ti_stars_end_min, data.ti_stars_end_max, data.ti_stars_beg_max, + data.ti_sinks_end_min, data.ti_sinks_end_max, data.ti_sinks_beg_max, + data.ti_black_holes_end_min, data.ti_black_holes_end_max, + data.ti_black_holes_beg_max, e->forcerebuild, e->s->tot_cells, + e->sched.nr_tasks, (float)e->sched.nr_tasks / (float)e->s->tot_cells, + data.sfh, data.runtime); /* Aggregate collective data from the different nodes for this step. */ #ifdef WITH_MPI diff --git a/src/engine_drift.c b/src/engine_drift.c index 0e447d6235b6e3f4b1f71dfea173daa8971d56f7..ccabb07575afc638e8162d96516c380619d95422 100644 --- a/src/engine_drift.c +++ b/src/engine_drift.c @@ -220,6 +220,54 @@ void engine_do_drift_all_bpart_mapper(void *map_data, int num_elements, } } +/** + * @brief Mapper function to drift *all* the #sink to the current time. + * + * @param map_data An array of #cell%s. + * @param num_elements Chunk size. + * @param extra_data Pointer to an #engine. + */ +void engine_do_drift_all_sink_mapper(void *map_data, int num_elements, + void *extra_data) { + + const struct engine *e = (const struct engine *)extra_data; + const int restarting = e->restarting; + struct space *s = e->s; + struct cell *cells_top; + int *local_cells_top; + + if (restarting) { + + /* When restarting, we loop over all top-level cells */ + cells_top = (struct cell *)map_data; + local_cells_top = NULL; + + } else { + + /* In any other case, we use the list of local cells with tasks */ + cells_top = s->cells_top; + local_cells_top = (int *)map_data; + } + + for (int ind = 0; ind < num_elements; ind++) { + + struct cell *c; + + /* When restarting, the list of local cells does not + yet exist. We use the raw list of top-level cells instead */ + if (restarting) + c = &cells_top[ind]; + else + c = &cells_top[local_cells_top[ind]]; + + if (c->nodeID == e->nodeID) { + + /* Drift all the particles */ + cell_drift_sink(c, e, /* force the drift=*/1); + } + } +} + /** * @brief Mapper function to drift *all* the multipoles to the current time. * @@ -305,6 +353,11 @@ void engine_drift_all(struct engine *e, const int drift_mpoles) { e->s->local_cells_top, e->s->nr_local_cells, sizeof(int), threadpool_auto_chunk_size, e); } + if (e->s->nr_sinks > 0) { + threadpool_map(&e->threadpool, engine_do_drift_all_sink_mapper, + e->s->local_cells_top, e->s->nr_local_cells, sizeof(int), + threadpool_auto_chunk_size, e); + } if (e->s->nr_bparts > 0) { threadpool_map(&e->threadpool, engine_do_drift_all_bpart_mapper, e->s->local_cells_top, e->s->nr_local_cells, sizeof(int), @@ -332,6 +385,11 @@ void engine_drift_all(struct engine *e, const int drift_mpoles) { e->s->cells_top, e->s->nr_cells, sizeof(struct cell), threadpool_auto_chunk_size, e); } + if (e->s->nr_sinks > 0) { + threadpool_map(&e->threadpool, engine_do_drift_all_sink_mapper, + e->s->cells_top, e->s->nr_cells, sizeof(struct cell), + threadpool_auto_chunk_size, e); + } if (e->s->nr_bparts > 0) { threadpool_map(&e->threadpool, engine_do_drift_all_bpart_mapper, e->s->cells_top, e->s->nr_cells, sizeof(struct cell), diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c index b38cfca652f7685d943a772f334ed4e5636fff7a..f04d74261213b0290c06cceaab2a41d70192429a 100644 --- a/src/engine_maketasks.c +++ b/src/engine_maketasks.c @@ -1096,6 +1096,7 @@ void engine_make_hierarchical_tasks_hydro(struct engine *e, struct cell *c, struct scheduler *s = &e->sched; const int with_stars = (e->policy & engine_policy_stars); + const int with_sinks = (e->policy & engine_policy_sinks); const int with_feedback = (e->policy & engine_policy_feedback); const int with_cooling = (e->policy & engine_policy_cooling); const int with_star_formation = (e->policy & engine_policy_star_formation); @@ -1174,6 +1175,13 @@ void engine_make_hierarchical_tasks_hydro(struct engine *e, struct cell *c, scheduler_addunlock(s, c->stars.drift, c->super->kick2); } + /* Sinks */ + if (with_sinks) { + c->sinks.drift = scheduler_addtask(s, task_type_drift_sink, + task_subtype_none, 0, 0, c, NULL); + scheduler_addunlock(s, c->sinks.drift, c->super->kick2); + } + /* Black holes */ if (with_black_holes) { c->black_holes.drift = scheduler_addtask( @@ -2878,6 +2886,7 @@ void engine_make_hydroloop_tasks_mapper(void *map_data, int num_elements, const int periodic = e->s->periodic; const int with_feedback = (e->policy & engine_policy_feedback); const int with_stars = (e->policy & engine_policy_stars); + const int with_sinks = (e->policy & engine_policy_sinks); const int with_black_holes = (e->policy & engine_policy_black_holes); struct space *s = e->s; @@ -2902,6 +2911,7 @@ void engine_make_hydroloop_tasks_mapper(void *map_data, int num_elements, /* Skip cells without hydro or star particles */ if ((ci->hydro.count == 0) && (!with_stars || ci->stars.count == 0) && + (!with_sinks || ci->sinks.count == 0) && (!with_black_holes || ci->black_holes.count == 0)) continue; @@ -2933,6 +2943,7 @@ void engine_make_hydroloop_tasks_mapper(void *map_data, int num_elements, if ((cid >= cjd) || ((cj->hydro.count == 0) && (!with_feedback || cj->stars.count == 0) && + (!with_sinks || cj->sinks.count == 0) && (!with_black_holes || cj->black_holes.count == 0)) || (ci->nodeID != nodeID && cj->nodeID != nodeID)) continue; diff --git a/src/engine_marktasks.c b/src/engine_marktasks.c index 3fb51038b6296d39c70ab740c69b88eca50b5659..115725602a93abecc89abba35a8ae57b5c7e6e54 100644 --- a/src/engine_marktasks.c +++ b/src/engine_marktasks.c @@ -878,11 +878,17 @@ void engine_marktasks_mapper(void *map_data, int num_elements, else if (t_type == task_type_kick1 || t_type == task_type_kick2) { if (cell_is_active_hydro(t->ci, e) || cell_is_active_gravity(t->ci, e) || - cell_is_active_stars(t->ci, e) || + cell_is_active_stars(t->ci, e) || cell_is_active_sinks(t->ci, e) || cell_is_active_black_holes(t->ci, e)) scheduler_activate(s, t); } + /* Sink drift ? */ + else if (t_type == task_type_drift_sink) { + + if (cell_is_active_sinks(t->ci, e)) cell_activate_drift_sink(t->ci, s); + } + /* Hydro ghost tasks ? */ else if (t_type == task_type_ghost || t_type == task_type_extra_ghost || t_type == task_type_ghost_in || t_type == task_type_ghost_out) { @@ -959,9 +965,10 @@ void engine_marktasks_mapper(void *map_data, int num_elements, t->ci->hydro.updated = 0; t->ci->grav.updated = 0; t->ci->stars.updated = 0; + t->ci->sinks.updated = 0; t->ci->black_holes.updated = 0; if (cell_is_active_hydro(t->ci, e) || cell_is_active_gravity(t->ci, e) || - cell_is_active_stars(t->ci, e) || + cell_is_active_stars(t->ci, e) || cell_is_active_sinks(t->ci, e) || cell_is_active_black_holes(t->ci, e)) scheduler_activate(s, t); } diff --git a/src/engine_redistribute.c b/src/engine_redistribute.c index 35354ec848d8890b9157c5c3a6825f84094cdd89..a7d954655f6dce4b18d16814106dde3098785c30 100644 --- a/src/engine_redistribute.c +++ b/src/engine_redistribute.c @@ -521,7 +521,7 @@ void engine_redistribute(struct engine *e) { #ifdef SWIFT_DEBUG_CHECKS const int nr_sinks_new = 0; #endif - if (e->policy & engine_policy_sink) { + if (e->policy & engine_policy_sinks) { error("Not implemented yet"); } diff --git a/src/engine_unskip.c b/src/engine_unskip.c index 9142ff447ac023d0428d466029110233cef37149..bff3bf842b746b8b618b27a42dcf0d3a6bd19f18 100644 --- a/src/engine_unskip.c +++ b/src/engine_unskip.c @@ -44,6 +44,7 @@ enum task_broad_types { task_broad_types_hydro = 1, task_broad_types_gravity, task_broad_types_stars, + task_broad_types_sinks, task_broad_types_black_holes, task_broad_types_count, }; @@ -174,6 +175,38 @@ static void engine_do_unskip_black_holes(struct cell *c, struct engine *e) { if (forcerebuild) atomic_inc(&e->forcerebuild); } +/** + * @brief Unskip any sink tasks associated with active cells. + * + * @param c The cell. + * @param e The engine. + */ +static void engine_do_unskip_sinks(struct cell *c, struct engine *e) { + + /* Early abort (are we below the level where tasks are)? */ + if (!cell_get_flag(c, cell_flag_has_tasks)) return; + + /* Ignore empty cells. */ + if (c->sinks.count == 0) return; + + /* Skip inactive cells. */ + if (!cell_is_active_sinks(c, e)) return; + + /* Recurse */ + if (c->split) { + for (int k = 0; k < 8; k++) { + if (c->progeny[k] != NULL) { + struct cell *cp = c->progeny[k]; + engine_do_unskip_sinks(cp, e); + } + } + } + + /* Unskip any active tasks. */ + const int forcerebuild = cell_unskip_sinks_tasks(c, &e->sched); + if (forcerebuild) atomic_inc(&e->forcerebuild); +} + /** * @brief Unskip any gravity tasks associated with active cells. * @@ -269,6 +302,13 @@ void engine_do_unskip_mapper(void *map_data, int num_elements, #endif engine_do_unskip_stars(c, e, with_star_formation); break; + case task_broad_types_sinks: +#ifdef SWIFT_DEBUG_CHECKS + if (!(e->policy & engine_policy_sinks)) + error("Trying to unskip sink tasks in a non-sinks run!"); +#endif + engine_do_unskip_sinks(c, e); + break; case task_broad_types_black_holes: #ifdef SWIFT_DEBUG_CHECKS if (!(e->policy & engine_policy_black_holes)) @@ -300,6 +340,7 @@ void engine_unskip(struct engine *e) { const int with_self_grav = e->policy & engine_policy_self_gravity; const int with_ext_grav = e->policy & engine_policy_external_gravity; const int with_stars = e->policy & engine_policy_stars; + const int with_sinks = e->policy & engine_policy_sinks; const int with_feedback = e->policy & engine_policy_feedback; const int with_black_holes = e->policy & engine_policy_black_holes; @@ -322,6 +363,7 @@ void engine_unskip(struct engine *e) { cell_is_active_gravity(c, e)) || (with_feedback && cell_is_active_stars(c, e)) || (with_stars && c->nodeID == nodeID && cell_is_active_stars(c, e)) || + (with_sinks && cell_is_active_sinks(c, e)) || (with_black_holes && cell_is_active_black_holes(c, e))) { if (num_active_cells != k) @@ -346,6 +388,10 @@ void engine_unskip(struct engine *e) { data.task_types[multiplier] = task_broad_types_stars; multiplier++; } + if (with_sinks) { + data.task_types[multiplier] = task_broad_types_sinks; + multiplier++; + } if (with_black_holes) { data.task_types[multiplier] = task_broad_types_black_holes; multiplier++; diff --git a/src/gravity/MultiSoftening/gravity.h b/src/gravity/MultiSoftening/gravity.h index 6ed0c38b7ee90807cc412efeb765167ded77e70c..e6dfccd81e129a8dfde316e76d3b54f119ed0a62 100644 --- a/src/gravity/MultiSoftening/gravity.h +++ b/src/gravity/MultiSoftening/gravity.h @@ -238,6 +238,9 @@ __attribute__((always_inline)) INLINE static void gravity_predict_extra( case swift_type_dark_matter: gp->epsilon = grav_props->epsilon_DM_cur; break; + case swift_type_sink: + gp->epsilon = grav_props->epsilon_baryon_cur; + break; case swift_type_stars: gp->epsilon = grav_props->epsilon_baryon_cur; break; @@ -298,6 +301,9 @@ __attribute__((always_inline)) INLINE static void gravity_first_init_gpart( case swift_type_stars: gp->epsilon = grav_props->epsilon_baryon_cur; break; + case swift_type_sink: + gp->epsilon = grav_props->epsilon_baryon_cur; + break; case swift_type_gas: gp->epsilon = grav_props->epsilon_baryon_cur; break; diff --git a/src/runner.h b/src/runner.h index 6990dacd46938c4ff16de0e95e3d74155d0d5f72..0b22f1710301c43ca148a002864d3f35a660f237 100644 --- a/src/runner.h +++ b/src/runner.h @@ -98,6 +98,7 @@ void runner_do_all_stars_sort(struct runner *r, struct cell *c); void runner_do_drift_part(struct runner *r, struct cell *c, int timer); void runner_do_drift_gpart(struct runner *r, struct cell *c, int timer); void runner_do_drift_spart(struct runner *r, struct cell *c, int timer); +void runner_do_drift_sink(struct runner *r, struct cell *c, int timer); void runner_do_drift_bpart(struct runner *r, struct cell *c, int timer); void runner_do_kick1(struct runner *r, struct cell *c, int timer); void runner_do_kick2(struct runner *r, struct cell *c, int timer); diff --git a/src/runner_drift.c b/src/runner_drift.c index 8c4376743cd50ffea4709cb471959864cedcc4b7..db1918de8c7012de6780e5e2afa2fd44f1c2dc16 100644 --- a/src/runner_drift.c +++ b/src/runner_drift.c @@ -94,3 +94,19 @@ void runner_do_drift_bpart(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_drift_bpart); } + +/** + * @brief Drift all sink in a cell. + * + * @param r The runner thread. + * @param c The cell. + * @param timer Are we timing this ? + */ +void runner_do_drift_sink(struct runner *r, struct cell *c, int timer) { + + TIMER_TIC; + + cell_drift_sink(c, r->e, 0); + + if (timer) TIMER_TOC(timer_drift_sink); +} diff --git a/src/runner_main.c b/src/runner_main.c index effcdf3cda94c5b74276af40f69c0e384aecadf4..6be1405e6a5503a0f197a45f489be25c0a1218d0 100644 --- a/src/runner_main.c +++ b/src/runner_main.c @@ -340,6 +340,9 @@ void *runner_main(void *data) { case task_type_drift_spart: runner_do_drift_spart(r, ci, 1); break; + case task_type_drift_sink: + runner_do_drift_sink(r, ci, 1); + break; case task_type_drift_bpart: runner_do_drift_bpart(r, ci, 1); break; diff --git a/src/runner_others.c b/src/runner_others.c index 4fd380be04bdc23b598bcceae8223107cc9c48ec..738353ab4f733e7120daf7786973cd8124e6cd4e 100644 --- a/src/runner_others.c +++ b/src/runner_others.c @@ -570,6 +570,8 @@ void runner_do_end_grav_force(struct runner *r, struct cell *c, int timer) { id = e->s->parts[-gp->id_or_neg_offset].id; else if (gp->type == swift_type_stars) id = e->s->sparts[-gp->id_or_neg_offset].id; + else if (gp->type == swift_type_sink) + id = e->s->sinks[-gp->id_or_neg_offset].id; else if (gp->type == swift_type_black_hole) id = e->s->bparts[-gp->id_or_neg_offset].id; else @@ -604,6 +606,8 @@ void runner_do_end_grav_force(struct runner *r, struct cell *c, int timer) { my_id = e->s->parts[-gp->id_or_neg_offset].id; else if (gp->type == swift_type_stars) my_id = e->s->sparts[-gp->id_or_neg_offset].id; + else if (gp->type == swift_type_sink) + my_id = e->s->sinks[-gp->id_or_neg_offset].id; else if (gp->type == swift_type_black_hole) error("Unexisting type"); else @@ -660,6 +664,9 @@ void runner_do_logger(struct runner *r, struct cell *c, int timer) { if (c->black_holes.count != 0) { error("Black holes are not implemented in the logger."); } + if (c->sinks.count != 0) { + error("Sink particles are not implemented in the logger."); + } /* Anything to do here? */ if (!cell_is_active_hydro(c, e) && !cell_is_active_gravity(c, e) && diff --git a/src/runner_time_integration.c b/src/runner_time_integration.c index 0e14524aedda6276bd3e280e2c50040e9210a7fb..16d7267fa55ccd8b7444f5c518766a4f237b4dab 100644 --- a/src/runner_time_integration.c +++ b/src/runner_time_integration.c @@ -91,10 +91,12 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { struct xpart *restrict xparts = c->hydro.xparts; struct gpart *restrict gparts = c->grav.parts; struct spart *restrict sparts = c->stars.parts; + struct sink *restrict sinks = c->sinks.parts; struct bpart *restrict bparts = c->black_holes.parts; const int count = c->hydro.count; const int gcount = c->grav.count; const int scount = c->stars.count; + const int sink_count = c->sinks.count; const int bcount = c->black_holes.count; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; @@ -103,7 +105,8 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { /* Anything to do here? */ if (!cell_is_starting_hydro(c, e) && !cell_is_starting_gravity(c, e) && - !cell_is_starting_stars(c, e) && !cell_is_starting_black_holes(c, e)) + !cell_is_starting_stars(c, e) && !cell_is_starting_sinks(c, e) && + !cell_is_starting_black_holes(c, e)) return; /* Recurse? */ @@ -183,10 +186,7 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { /* If the g-particle has no counterpart and needs to be kicked */ if ((gp->type == swift_type_dark_matter || - gp->type == swift_type_dark_matter_background || - gp->type == swift_type_sink) && - // TODO loic remove this - + gp->type == swift_type_dark_matter_background) && gpart_is_starting(gp, e)) { const integertime_t ti_step = get_integer_timestep(gp->time_bin); @@ -256,6 +256,44 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { } } + /* Loop over the sink particles in this cell. */ + for (int k = 0; k < sink_count; k++) { + + /* Get a handle on the s-part. */ + struct sink *restrict sink = &sinks[k]; + + /* If particle needs to be kicked */ + if (sink_is_starting(sink, e)) { + + const integertime_t ti_step = get_integer_timestep(sink->time_bin); + const integertime_t ti_begin = + get_integer_time_begin(ti_current + 1, sink->time_bin); + +#ifdef SWIFT_DEBUG_CHECKS + const integertime_t ti_end = + get_integer_time_end(ti_current + 1, sink->time_bin); + + if (ti_begin != ti_current) + error( + "Sink-particle in wrong time-bin, ti_end=%lld, ti_begin=%lld, " + "ti_step=%lld time_bin=%d ti_current=%lld", + ti_end, ti_begin, ti_step, sink->time_bin, ti_current); +#endif + + /* Time interval for this half-kick */ + double dt_kick_grav; + if (with_cosmology) { + dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_begin, + ti_begin + ti_step / 2); + } else { + dt_kick_grav = (ti_step / 2) * time_base; + } + + /* do the kick */ + kick_sink(sink, dt_kick_grav, ti_begin, ti_begin + ti_step / 2); + } + } + /* Loop over the black hole particles in this cell. */ for (int k = 0; k < bcount; k++) { @@ -317,11 +355,13 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const int count = c->hydro.count; const int gcount = c->grav.count; const int scount = c->stars.count; + const int sink_count = c->sinks.count; const int bcount = c->black_holes.count; struct part *restrict parts = c->hydro.parts; struct xpart *restrict xparts = c->hydro.xparts; struct gpart *restrict gparts = c->grav.parts; struct spart *restrict sparts = c->stars.parts; + struct sink *restrict sinks = c->sinks.parts; struct bpart *restrict bparts = c->black_holes.parts; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; @@ -330,7 +370,8 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* Anything to do here? */ if (!cell_is_active_hydro(c, e) && !cell_is_active_gravity(c, e) && - !cell_is_active_stars(c, e) && !cell_is_active_black_holes(c, e)) + !cell_is_active_stars(c, e) && !cell_is_active_sinks(c, e) && + !cell_is_active_black_holes(c, e)) return; /* Recurse? */ @@ -410,10 +451,7 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* If the g-particle has no counterpart and needs to be kicked */ if ((gp->type == swift_type_dark_matter || - gp->type == swift_type_dark_matter_background || - gp->type == swift_type_sink) && - // TODO loic remove this - + gp->type == swift_type_dark_matter_background) && gpart_is_active(gp, e)) { const integertime_t ti_step = get_integer_timestep(gp->time_bin); @@ -491,6 +529,48 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { } } + /* Loop over the sink particles in this cell. */ + for (int k = 0; k < sink_count; k++) { + + /* Get a handle on the part. */ + struct sink *restrict sink = &sinks[k]; + + /* If particle needs to be kicked */ + if (sink_is_active(sink, e)) { + + const integertime_t ti_step = get_integer_timestep(sink->time_bin); + const integertime_t ti_begin = + get_integer_time_begin(ti_current, sink->time_bin); + +#ifdef SWIFT_DEBUG_CHECKS + if (ti_begin + ti_step != ti_current) + error("Particle in wrong time-bin"); +#endif + + /* Time interval for this half-kick */ + double dt_kick_grav; + if (with_cosmology) { + dt_kick_grav = cosmology_get_grav_kick_factor( + cosmo, ti_begin + ti_step / 2, ti_begin + ti_step); + } else { + dt_kick_grav = (ti_step / 2) * time_base; + } + + /* Finish the time-step with a second half-kick */ + kick_sink(sink, dt_kick_grav, ti_begin + ti_step / 2, + ti_begin + ti_step); + +#ifdef SWIFT_DEBUG_CHECKS + /* Check that kick and the drift are synchronized */ + if (sink->ti_drift != sink->ti_kick) + error("Error integrating sink-part in time."); +#endif + + /* Prepare the values to be drifted */ + sink_reset_predicted_values(sink); + } + } + /* Loop over the particles in this cell. */ for (int k = 0; k < bcount; k++) { @@ -553,32 +633,39 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { const int count = c->hydro.count; const int gcount = c->grav.count; const int scount = c->stars.count; + const int sink_count = c->sinks.count; const int bcount = c->black_holes.count; struct part *restrict parts = c->hydro.parts; struct xpart *restrict xparts = c->hydro.xparts; struct gpart *restrict gparts = c->grav.parts; struct spart *restrict sparts = c->stars.parts; + struct sink *restrict sinks = c->sinks.parts; struct bpart *restrict bparts = c->black_holes.parts; TIMER_TIC; /* Anything to do here? */ if (!cell_is_active_hydro(c, e) && !cell_is_active_gravity(c, e) && - !cell_is_active_stars(c, e) && !cell_is_active_black_holes(c, e)) { + !cell_is_active_stars(c, e) && !cell_is_active_sinks(c, e) && + !cell_is_active_black_holes(c, e)) { c->hydro.updated = 0; c->grav.updated = 0; c->stars.updated = 0; + c->sinks.updated = 0; c->black_holes.updated = 0; return; } - int updated = 0, g_updated = 0, s_updated = 0, b_updated = 0; + int updated = 0, g_updated = 0, s_updated = 0, sink_updated = 0, + b_updated = 0; integertime_t ti_hydro_end_min = max_nr_timesteps, ti_hydro_end_max = 0, ti_hydro_beg_max = 0; integertime_t ti_gravity_end_min = max_nr_timesteps, ti_gravity_end_max = 0, ti_gravity_beg_max = 0; integertime_t ti_stars_end_min = max_nr_timesteps, ti_stars_end_max = 0, ti_stars_beg_max = 0; + integertime_t ti_sinks_end_min = max_nr_timesteps, ti_sinks_end_max = 0, + ti_sinks_beg_max = 0; integertime_t ti_black_holes_end_min = max_nr_timesteps, ti_black_holes_end_max = 0, ti_black_holes_beg_max = 0; @@ -678,9 +765,7 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { /* If the g-particle has no counterpart */ if (gp->type == swift_type_dark_matter || - gp->type == swift_type_dark_matter_background || - gp->type == swift_type_sink) { - // Loic TODO remove sink + gp->type == swift_type_dark_matter_background) { /* need to be updated ? */ if (gpart_is_active(gp, e)) { @@ -712,13 +797,6 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { /* What is the next starting point for this cell ? */ ti_gravity_beg_max = max(ti_current, ti_gravity_beg_max); - // Loic TODO remove this - /* Synchronize the time step */ - if (gp->type == swift_type_sink) { - struct sink *sink = &e->s->sinks[-gp->id_or_neg_offset]; - sink->time_bin = gp->time_bin; - } - } else { /* gpart is inactive */ if (!gpart_is_inhibited(gp, e)) { @@ -805,7 +883,67 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { } } - /* Loop over the star particles in this cell. */ + /* Loop over the sink particles in this cell. */ + for (int k = 0; k < sink_count; k++) { + + /* Get a handle on the part. */ + struct sink *restrict sink = &sinks[k]; + + /* need to be updated ? */ + if (sink_is_active(sink, e)) { + +#ifdef SWIFT_DEBUG_CHECKS + /* Current end of time-step */ + const integertime_t ti_end = + get_integer_time_end(ti_current, sink->time_bin); + + if (ti_end != ti_current) + error("Computing time-step of rogue particle."); +#endif + /* Get new time-step */ + const integertime_t ti_new_step = get_sink_timestep(sink, e); + + /* Update particle */ + sink->time_bin = get_time_bin(ti_new_step); + sink->gpart->time_bin = get_time_bin(ti_new_step); + + /* Number of updated sink-particles */ + sink_updated++; + g_updated++; + + ti_sinks_end_min = min(ti_current + ti_new_step, ti_sinks_end_min); + ti_sinks_end_max = max(ti_current + ti_new_step, ti_sinks_end_max); + ti_gravity_end_min = min(ti_current + ti_new_step, ti_gravity_end_min); + ti_gravity_end_max = max(ti_current + ti_new_step, ti_gravity_end_max); + + /* What is the next starting point for this cell ? */ + ti_sinks_beg_max = max(ti_current, ti_sinks_beg_max); + ti_gravity_beg_max = max(ti_current, ti_gravity_beg_max); + + /* sink particle is inactive but not inhibited */ + } else { + + if (!sink_is_inhibited(sink, e)) { + + const integertime_t ti_end = + get_integer_time_end(ti_current, sink->time_bin); + + const integertime_t ti_beg = + get_integer_time_begin(ti_current + 1, sink->time_bin); + + ti_sinks_end_min = min(ti_end, ti_sinks_end_min); + ti_sinks_end_max = max(ti_end, ti_sinks_end_max); + ti_gravity_end_min = min(ti_end, ti_gravity_end_min); + ti_gravity_end_max = max(ti_end, ti_gravity_end_max); + + /* What is the next starting point for this cell ? */ + ti_sinks_beg_max = max(ti_beg, ti_sinks_beg_max); + ti_gravity_beg_max = max(ti_beg, ti_gravity_beg_max); + } + } + } + + /* Loop over the black hole particles in this cell. */ for (int k = 0; k < bcount; k++) { /* Get a handle on the part. */ @@ -880,6 +1018,7 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { /* And aggregate */ updated += cp->hydro.updated; g_updated += cp->grav.updated; + sink_updated += cp->sinks.updated; s_updated += cp->stars.updated; b_updated += cp->black_holes.updated; @@ -895,6 +1034,10 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { ti_stars_end_max = max(cp->stars.ti_end_max, ti_stars_end_max); ti_stars_beg_max = max(cp->stars.ti_beg_max, ti_stars_beg_max); + ti_sinks_end_min = min(cp->sinks.ti_end_min, ti_sinks_end_min); + ti_sinks_end_max = max(cp->sinks.ti_end_max, ti_sinks_end_max); + ti_sinks_beg_max = max(cp->sinks.ti_beg_max, ti_sinks_beg_max); + ti_black_holes_end_min = min(cp->black_holes.ti_end_min, ti_black_holes_end_min); ti_black_holes_end_max = @@ -909,6 +1052,7 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { c->hydro.updated = updated; c->grav.updated = g_updated; c->stars.updated = s_updated; + c->sinks.updated = sink_updated; c->black_holes.updated = b_updated; c->hydro.ti_end_min = ti_hydro_end_min; @@ -920,6 +1064,9 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { c->stars.ti_end_min = ti_stars_end_min; c->stars.ti_end_max = ti_stars_end_max; c->stars.ti_beg_max = ti_stars_beg_max; + c->sinks.ti_end_min = ti_sinks_end_min; + c->sinks.ti_end_max = ti_sinks_end_max; + c->sinks.ti_beg_max = ti_sinks_beg_max; c->black_holes.ti_end_min = ti_black_holes_end_min; c->black_holes.ti_end_max = ti_black_holes_end_max; c->black_holes.ti_beg_max = ti_black_holes_beg_max; @@ -934,6 +1081,9 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { if (c->stars.ti_end_min == e->ti_current && c->stars.ti_end_min < max_nr_timesteps) error("End of next stars step is current time!"); + if (c->sinks.ti_end_min == e->ti_current && + c->sinks.ti_end_min < max_nr_timesteps) + error("End of next sinks step is current time!"); if (c->black_holes.ti_end_min == e->ti_current && c->black_holes.ti_end_min < max_nr_timesteps) error("End of next black holes step is current time!"); diff --git a/src/scheduler.c b/src/scheduler.c index bb380e5a51f478fb53762e805ef1bbbdb0fceec7..165c3d2fe99ce7dbb9734fd9f82d5805a244027e 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -545,6 +545,7 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) { access the engine... */ const int with_feedback = (s->space->e->policy & engine_policy_feedback); const int with_stars = (s->space->e->policy & engine_policy_stars); + const int with_sinks = (s->space->e->policy & engine_policy_sinks); const int with_black_holes = (s->space->e->policy & engine_policy_black_holes); @@ -558,6 +559,7 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) { const int is_self = (t->type == task_type_self) && (t->ci != NULL) && ((t->ci->hydro.count > 0) || (with_stars && t->ci->stars.count > 0) || + (with_sinks && t->ci->sinks.count > 0) || (with_black_holes && t->ci->black_holes.count > 0)); /* Is this a non-empty pair-task? */ @@ -565,9 +567,11 @@ static void scheduler_splittask_hydro(struct task *t, struct scheduler *s) { (t->cj != NULL) && ((t->ci->hydro.count > 0) || (with_feedback && t->ci->stars.count > 0) || + (with_sinks && t->ci->sinks.count > 0) || (with_black_holes && t->ci->black_holes.count > 0)) && ((t->cj->hydro.count > 0) || (with_feedback && t->cj->stars.count > 0) || + (with_sinks && t->cj->sinks.count > 0) || (with_black_holes && t->cj->black_holes.count > 0)); /* Empty task? */ @@ -1356,6 +1360,7 @@ void scheduler_reweight(struct scheduler *s, int verbose) { const float gcount_j = (t->cj != NULL) ? t->cj->grav.count : 0.f; const float scount_i = (t->ci != NULL) ? t->ci->stars.count : 0.f; const float scount_j = (t->cj != NULL) ? t->cj->stars.count : 0.f; + const float sink_count_i = (t->ci != NULL) ? t->ci->sinks.count : 0.f; const float bcount_i = (t->ci != NULL) ? t->ci->black_holes.count : 0.f; const float bcount_j = (t->cj != NULL) ? t->cj->black_holes.count : 0.f; @@ -1545,6 +1550,9 @@ void scheduler_reweight(struct scheduler *s, int verbose) { case task_type_drift_spart: cost = wscale * scount_i; break; + case task_type_drift_sink: + cost = wscale * sink_count_i; + break; case task_type_drift_bpart: cost = wscale * bcount_i; break; @@ -1576,13 +1584,16 @@ void scheduler_reweight(struct scheduler *s, int verbose) { cost = wscale * (count_i + scount_i); break; case task_type_kick1: - cost = wscale * (count_i + gcount_i + scount_i + bcount_i); + cost = + wscale * (count_i + gcount_i + scount_i + sink_count_i + bcount_i); break; case task_type_kick2: - cost = wscale * (count_i + gcount_i + scount_i + bcount_i); + cost = + wscale * (count_i + gcount_i + scount_i + sink_count_i + bcount_i); break; case task_type_timestep: - cost = wscale * (count_i + gcount_i + scount_i + bcount_i); + cost = + wscale * (count_i + gcount_i + scount_i + sink_count_i + bcount_i); break; case task_type_timestep_limiter: cost = wscale * count_i; diff --git a/src/space.c b/src/space.c index da840cd83c437f55778cb3b6666d12c61bd6f888..d9a13d92922aa9b9bb2331f02a319d0db03dc419 100644 --- a/src/space.c +++ b/src/space.c @@ -206,6 +206,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->grav.mm = NULL; c->hydro.dx_max_part = 0.0f; c->hydro.dx_max_sort = 0.0f; + c->sinks.dx_max_part = 0.f; c->stars.dx_max_part = 0.f; c->stars.dx_max_sort = 0.f; c->black_holes.dx_max_part = 0.f; @@ -252,6 +253,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->timestep_sync = NULL; c->hydro.end_force = NULL; c->hydro.drift = NULL; + c->sinks.drift = NULL; c->stars.drift = NULL; c->stars.stars_in = NULL; c->stars.stars_out = NULL; @@ -285,6 +287,8 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->hydro.ti_end_max = -1; c->grav.ti_end_min = -1; c->grav.ti_end_max = -1; + c->sinks.ti_end_min = -1; + c->sinks.ti_end_max = -1; c->stars.ti_end_min = -1; c->stars.ti_end_max = -1; c->black_holes.ti_end_min = -1; @@ -621,6 +625,7 @@ void space_regrid(struct space *s, int verbose) { c->hydro.count = 0; c->grav.count = 0; c->stars.count = 0; + c->sinks.count = 0; c->top = c; c->super = c; c->hydro.super = c; @@ -628,6 +633,7 @@ void space_regrid(struct space *s, int verbose) { c->hydro.ti_old_part = ti_current; c->grav.ti_old_part = ti_current; c->stars.ti_old_part = ti_current; + c->sinks.ti_old_part = ti_current; c->black_holes.ti_old_part = ti_current; c->grav.ti_old_multipole = ti_current; #ifdef WITH_MPI @@ -1613,6 +1619,8 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { s->parts[-s->gparts[k].id_or_neg_offset].gpart = &s->gparts[k]; } else if (s->gparts[k].type == swift_type_stars) { s->sparts[-s->gparts[k].id_or_neg_offset].gpart = &s->gparts[k]; + } else if (s->gparts[k].type == swift_type_sink) { + s->sparts[-s->gparts[k].id_or_neg_offset].gpart = &s->gparts[k]; } else if (s->gparts[k].type == swift_type_black_hole) { s->bparts[-s->gparts[k].id_or_neg_offset].gpart = &s->gparts[k]; } @@ -1623,6 +1631,9 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { } else if (s->gparts[nr_gparts].type == swift_type_stars) { s->sparts[-s->gparts[nr_gparts].id_or_neg_offset].gpart = &s->gparts[nr_gparts]; + } else if (s->gparts[nr_gparts].type == swift_type_sink) { + s->sparts[-s->gparts[nr_gparts].id_or_neg_offset].gpart = + &s->gparts[nr_gparts]; } else if (s->gparts[nr_gparts].type == swift_type_black_hole) { s->bparts[-s->gparts[nr_gparts].id_or_neg_offset].gpart = &s->gparts[nr_gparts]; @@ -2087,6 +2098,7 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { c->grav.ti_old_part = ti_current; c->grav.ti_old_multipole = ti_current; c->stars.ti_old_part = ti_current; + c->sinks.ti_old_part = ti_current; c->black_holes.ti_old_part = ti_current; #if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) @@ -2114,6 +2126,7 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { c->hydro.count_total = c->hydro.count + space_extra_parts; c->grav.count_total = c->grav.count + space_extra_gparts; c->stars.count_total = c->stars.count + space_extra_sparts; + c->sinks.count_total = c->sinks.count + space_extra_sinks; c->black_holes.count_total = c->black_holes.count + space_extra_bparts; finger = &finger[c->hydro.count_total]; @@ -2991,7 +3004,7 @@ void space_sinks_get_cell_index_mapper(void *map_data, int nr_sinks, if (cell_counts[k]) atomic_add(&data->cell_counts[k], cell_counts[k]); free(cell_counts); - /* Write the count of inhibited and extra bparts */ + /* Write the count of inhibited and extra sinks */ if (count_inhibited_sink) atomic_add(&data->count_inhibited_sink, count_inhibited_sink); if (count_extra_sink) atomic_add(&data->count_extra_sink, count_extra_sink); @@ -3167,6 +3180,10 @@ void space_sinks_get_cell_index(struct space *s, int *sink_ind, const ticks tic = getticks(); + /* Re-set the counters */ + s->min_sink_mass = FLT_MAX; + s->sum_sink_vel_norm = 0.f; + /* Pack the extra information */ struct index_data data; data.s = s; @@ -3757,6 +3774,8 @@ void space_split_recursive(struct space *s, struct cell *c, ti_gravity_beg_max = 0; integertime_t ti_stars_end_min = max_nr_timesteps, ti_stars_end_max = 0, ti_stars_beg_max = 0; + integertime_t ti_sinks_end_min = max_nr_timesteps, ti_sinks_end_max = 0, + ti_sinks_beg_max = 0; integertime_t ti_black_holes_end_min = max_nr_timesteps, ti_black_holes_end_max = 0, ti_black_holes_beg_max = 0; struct part *parts = c->hydro.parts; @@ -3895,6 +3914,7 @@ void space_split_recursive(struct space *s, struct cell *c, cp->grav.ti_old_part = c->grav.ti_old_part; cp->grav.ti_old_multipole = c->grav.ti_old_multipole; cp->stars.ti_old_part = c->stars.ti_old_part; + cp->sinks.ti_old_part = c->sinks.ti_old_part; cp->black_holes.ti_old_part = c->black_holes.ti_old_part; cp->loc[0] = c->loc[0]; cp->loc[1] = c->loc[1]; @@ -3914,6 +3934,7 @@ void space_split_recursive(struct space *s, struct cell *c, cp->stars.h_max = 0.f; cp->stars.dx_max_part = 0.f; cp->stars.dx_max_sort = 0.f; + cp->sinks.dx_max_part = 0.f; cp->black_holes.h_max = 0.f; cp->black_holes.dx_max_part = 0.f; cp->nodeID = c->nodeID; @@ -3981,6 +4002,9 @@ void space_split_recursive(struct space *s, struct cell *c, ti_stars_end_min = min(ti_stars_end_min, cp->stars.ti_end_min); ti_stars_end_max = max(ti_stars_end_max, cp->stars.ti_end_max); ti_stars_beg_max = max(ti_stars_beg_max, cp->stars.ti_beg_max); + ti_sinks_end_min = min(ti_sinks_end_min, cp->sinks.ti_end_min); + ti_sinks_end_max = max(ti_sinks_end_max, cp->sinks.ti_end_max); + ti_sinks_beg_max = max(ti_sinks_beg_max, cp->sinks.ti_beg_max); ti_black_holes_end_min = min(ti_black_holes_end_min, cp->black_holes.ti_end_min); ti_black_holes_end_max = @@ -4204,6 +4228,30 @@ void space_split_recursive(struct space *s, struct cell *c, sparts[k].x_diff[2] = 0.f; } + /* sinks: Get dt_min/dt_max */ + for (int k = 0; k < sink_count; k++) { +#ifdef SWIFT_DEBUG_CHECKS + if (sinks[k].time_bin == time_bin_not_created) + error("Extra sink-particle present in space_split()"); + if (sinks[k].time_bin == time_bin_inhibited) + error("Inhibited sink-particle present in space_split()"); +#endif + + /* When does this particle's time-step start and end? */ + const timebin_t time_bin = sinks[k].time_bin; + const integertime_t ti_end = get_integer_time_end(ti_current, time_bin); + const integertime_t ti_beg = get_integer_time_begin(ti_current, time_bin); + + ti_sinks_end_min = min(ti_sinks_end_min, ti_end); + ti_sinks_end_max = max(ti_sinks_end_max, ti_end); + ti_sinks_beg_max = max(ti_sinks_beg_max, ti_beg); + + /* Reset x_diff */ + sinks[k].x_diff[0] = 0.f; + sinks[k].x_diff[1] = 0.f; + sinks[k].x_diff[2] = 0.f; + } + /* bparts: Get dt_min/dt_max */ for (int k = 0; k < bcount; k++) { #ifdef SWIFT_DEBUG_CHECKS @@ -4274,6 +4322,9 @@ void space_split_recursive(struct space *s, struct cell *c, c->stars.ti_end_max = ti_stars_end_max; c->stars.ti_beg_max = ti_stars_beg_max; c->stars.h_max = stars_h_max; + c->sinks.ti_end_min = ti_sinks_end_min; + c->sinks.ti_end_max = ti_sinks_end_max; + c->sinks.ti_beg_max = ti_sinks_beg_max; c->black_holes.ti_end_min = ti_black_holes_end_min; c->black_holes.ti_end_max = ti_black_holes_end_max; c->black_holes.ti_beg_max = ti_black_holes_beg_max; @@ -5460,10 +5511,12 @@ void space_init(struct space *s, struct swift_params *params, s->sinks = sinks; s->min_part_mass = FLT_MAX; s->min_gpart_mass = FLT_MAX; + s->min_sink_mass = FLT_MAX; s->min_spart_mass = FLT_MAX; s->min_bpart_mass = FLT_MAX; s->sum_part_vel_norm = 0.f; s->sum_gpart_vel_norm = 0.f; + s->sum_sink_vel_norm = 0.f; s->sum_spart_vel_norm = 0.f; s->sum_bpart_vel_norm = 0.f; s->nr_queues = 1; /* Temporary value until engine construction */ diff --git a/src/space.h b/src/space.h index f597db6421fe39db1fad17e0201597efdba060f8..3b942a03d653f2b0e7d6255698b2e8c1439f5bf2 100644 --- a/src/space.h +++ b/src/space.h @@ -262,6 +262,9 @@ struct space { /*! Minimal mass of all the #spart */ float min_spart_mass; + /*! Minimal mass of all the #sink */ + float min_sink_mass; + /*! Minimal mass of all the #bpart */ float min_bpart_mass; @@ -274,6 +277,9 @@ struct space { /*! Sum of the norm of the velocity of all the #spart */ float sum_spart_vel_norm; + /*! Sum of the norm of the velocity of all the #sink */ + float sum_sink_vel_norm; + /*! Sum of the norm of the velocity of all the #bpart */ float sum_bpart_vel_norm; diff --git a/src/task.c b/src/task.c index a766d5b36392df4b3a0a472be0e1dcee77cf5a28..e978d6f23e0526524dd83e3a22b04b9302e6a603 100644 --- a/src/task.c +++ b/src/task.c @@ -63,6 +63,7 @@ const char *taskID_names[task_type_count] = {"none", "extra_ghost", "drift_part", "drift_spart", + "drift_sink", "drift_bpart", "drift_gpart", "drift_gpart_out", @@ -104,15 +105,37 @@ const char *taskID_names[task_type_count] = {"none", "fof_pair"}; /* Sub-task type names. */ -const char *subtaskID_names[task_subtype_count] = { - "none", "density", "gradient", "force", - "limiter", "grav", "external_grav", "tend_part", - "tend_gpart", "tend_spart", "tend_bpart", "xv", - "rho", "part_swallow", "bpart_merger", "gpart", - "multipole", "spart", "stars_density", "stars_feedback", - "sf_count", "bpart_rho", "bpart_swallow", "bpart_feedback", - "bh_density", "bh_swallow", "do_gas_swallow", "do_bh_swallow", - "bh_feedback"}; +const char *subtaskID_names[task_subtype_count] = {"none", + "density", + "gradient", + "force", + "limiter", + "grav", + "external_grav", + "tend_part", + "tend_gpart", + "tend_spart", + "tend_sink", + "tend_bpart", + "xv", + "rho", + "part_swallow", + "bpart_merger", + "gpart", + "multipole", + "spart", + "stars_density", + "stars_feedback", + "sf_count", + "bpart_rho", + "bpart_swallow", + "bpart_feedback", + "bh_density", + "bh_swallow", + "do_gas_swallow", + "do_bh_swallow", + "bh_feedback", + "sink"}; const char *task_category_names[task_category_count] = { "drift", "sort", "hydro", "gravity", "feedback", @@ -152,6 +175,7 @@ MPI_Comm subtaskMPI_comms[task_subtype_count]; TASK_CELL_OVERLAP(part, hydro.parts, hydro.count); TASK_CELL_OVERLAP(gpart, grav.parts, grav.count); TASK_CELL_OVERLAP(spart, stars.parts, stars.count); +TASK_CELL_OVERLAP(sink, sinks.parts, sinks.count); TASK_CELL_OVERLAP(bpart, black_holes.parts, black_holes.count); /** @@ -187,6 +211,10 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on( return task_action_spart; break; + case task_type_drift_sink: + return task_action_sink; + break; + case task_type_drift_bpart: case task_type_bh_density_ghost: case task_type_bh_swallow_ghost3: @@ -314,6 +342,7 @@ float task_overlap(const struct task *restrict ta, (ta_act == task_action_gpart || ta_act == task_action_all); const int ta_spart = (ta_act == task_action_spart || ta_act == task_action_all); + const int ta_sink = (ta_act == task_action_sink || ta_act == task_action_all); const int ta_bpart = (ta_act == task_action_bpart || ta_act == task_action_all); const int tb_part = (tb_act == task_action_part || tb_act == task_action_all); @@ -321,6 +350,7 @@ float task_overlap(const struct task *restrict ta, (tb_act == task_action_gpart || tb_act == task_action_all); const int tb_spart = (tb_act == task_action_spart || tb_act == task_action_all); + const int tb_sink = (tb_act == task_action_sink || tb_act == task_action_all); const int tb_bpart = (tb_act == task_action_bpart || tb_act == task_action_all); @@ -387,6 +417,27 @@ float task_overlap(const struct task *restrict ta, return ((float)size_intersect) / (size_union - size_intersect); } + /* In the case where both tasks act on sink */ + else if (ta_sink && tb_sink) { + + /* Compute the union of the cell data. */ + size_t size_union = 0; + if (ta->ci != NULL) size_union += ta->ci->sinks.count; + if (ta->cj != NULL) size_union += ta->cj->sinks.count; + if (tb->ci != NULL) size_union += tb->ci->sinks.count; + if (tb->cj != NULL) size_union += tb->cj->sinks.count; + + if (size_union == 0) return 0.f; + + /* Compute the intersection of the cell data. */ + const size_t size_intersect = task_cell_overlap_spart(ta->ci, tb->ci) + + task_cell_overlap_sink(ta->ci, tb->cj) + + task_cell_overlap_sink(ta->cj, tb->ci) + + task_cell_overlap_sink(ta->cj, tb->cj); + + return ((float)size_intersect) / (size_union - size_intersect); + } + /* In the case where both tasks act on bparts */ else if (ta_bpart && tb_bpart) { @@ -1354,6 +1405,7 @@ enum task_categories task_get_category(const struct task *t) { case task_type_drift_part: case task_type_drift_spart: + case task_type_drift_sink: case task_type_drift_bpart: case task_type_drift_gpart: return task_category_drift; diff --git a/src/task.h b/src/task.h index c8b7e587c8afe24875fb4568de6d8963920f680c..2fdc4ba2b1774256eca225c0e1997a66dc332109 100644 --- a/src/task.h +++ b/src/task.h @@ -57,6 +57,7 @@ enum task_types { task_type_extra_ghost, task_type_drift_part, task_type_drift_spart, + task_type_drift_sink, task_type_drift_bpart, task_type_drift_gpart, task_type_drift_gpart_out, /* Implicit */ @@ -113,6 +114,7 @@ enum task_subtypes { task_subtype_tend_part, task_subtype_tend_gpart, task_subtype_tend_spart, + task_subtype_tend_sink, task_subtype_tend_bpart, task_subtype_xv, task_subtype_rho, @@ -132,6 +134,7 @@ enum task_subtypes { task_subtype_do_gas_swallow, task_subtype_do_bh_swallow, task_subtype_bh_feedback, + task_subtype_sink, task_subtype_count } __attribute__((packed)); @@ -143,6 +146,7 @@ enum task_actions { task_action_part, task_action_gpart, task_action_spart, + task_action_sink, task_action_bpart, task_action_all, task_action_multipole, diff --git a/src/timers.c b/src/timers.c index cc4ebc90d491832178f1e48e96960f489c73f4c1..23f2b9e8b69d201104d0f6354990db83488e9d4b 100644 --- a/src/timers.c +++ b/src/timers.c @@ -123,6 +123,7 @@ const char* timers_names[timer_count] = { "do_stars_resort", "fof_self", "fof_pair", + "drift_sink", }; /* File to store the timers */ diff --git a/src/timers.h b/src/timers.h index 96742567f549c156944333fafd4342dba14a4bee..68cea16ff9629e95760325d3b333745b732f27d5 100644 --- a/src/timers.h +++ b/src/timers.h @@ -124,6 +124,7 @@ enum { timer_do_stars_resort, timer_fof_self, timer_fof_pair, + timer_drift_sink, timer_count, };