Commit 64830af8 authored by Loic Hausammann's avatar Loic Hausammann Committed by Matthieu Schaller

Sink drift

parent b0de294f
#!/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
......@@ -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)
......@@ -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)
......
#!/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
......@@ -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 */
......
This diff is collapsed.
......@@ -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.
......
This diff is collapsed.
......@@ -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);
......
......@@ -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);
......
......@@ -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));
......
......@@ -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;
......
......@@ -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 =