diff --git a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml index 43c04c9db8e9531abdee43ba6856957bfae30255..0067311c413a670ec6696ae5f6f85bc61e2c83b3 100644 --- a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml +++ b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml @@ -54,7 +54,8 @@ SPH: # Parameters for the Friends-Of-Friends algorithm FOF: basename: fof_output # Common part of the name of output files - min_group_size: 20 # (Optional) The minimum no. of particles required for a group. Defaults to 20 if unspecified. + run_freq: 50 + min_group_size: 256 # (Optional) The minimum no. of particles required for a group. Defaults to 20 if unspecified. linking_length_scale: 0.2 # (Optional) Scales the linking length. Defaults to 0.2 if unspecified. group_links_size_default: 20000 # (Optional) Sets the initial size of the group_links array, which is used to store links across MPI domains. Defaults to 20000 if unspecified. group_id_default: 2147483647 # (Optional) Sets the group ID of particles in groups below the minimum size. Defaults to 2^31 - 1 if unspecified. Has to be positive. @@ -67,7 +68,11 @@ InitialConditions: periodic: 1 cleanup_h_factors: 1 # Remove the h-factors inherited from Gadget cleanup_velocity_factors: 1 # Remove the sqrt(a) factor in the velocities inherited from Gadget + +EAGLEBlackHoles: + seed_halo_mass: 1.5 + EAGLEChemistry: # Solar abundances init_abundance_metal: 0.014 init_abundance_Hydrogen: 0.70649785 diff --git a/src/engine.c b/src/engine.c index 23be9a1eaf8c3c0db76982d22644e3fcc5272fff..72db264e3543845881d9d1bf8a08ef278c45175f 100644 --- a/src/engine.c +++ b/src/engine.c @@ -6279,7 +6279,7 @@ void engine_fof(struct engine *e) { ticks tic = getticks(); /* Initialise FOF parameters and allocate FOF arrays. */ - fof_init(e->s); + fof_allocate(e->s); /* Make FOF tasks and activate them. */ engine_make_fof_tasks(e); @@ -6294,7 +6294,7 @@ void engine_fof(struct engine *e) { /* Reset flag. */ e->run_fof = 0; - if (e->verbose && engine_rank == 0) + if (engine_rank == 0) message("Complete FOF search took: %.3f %s.", clocks_from_ticks(getticks() - tic), clocks_getunit()); } diff --git a/src/engine.h b/src/engine.h index 32217428e1b878dff14c6325ea3eef9ec48f1612..791487dd7653a65b44df59926930c55e82ed6746 100644 --- a/src/engine.h +++ b/src/engine.h @@ -428,6 +428,9 @@ struct engine { /* Properties of the chemistry model */ const struct chemistry_global_data *chemistry; + /*! The FOF properties data. */ + struct fof_props *fof_properties; + /* The (parsed) parameter file */ struct swift_params *parameter_file; diff --git a/src/fof.c b/src/fof.c index e443befdbfbb773205ad7977e57635878910f03e..8883ee74df515a52a7d6e23236ab054414e4ab19 100644 --- a/src/fof.c +++ b/src/fof.c @@ -49,115 +49,111 @@ MPI_Datatype fof_final_mass_type; #endif size_t node_offset; -/* Initialises parameters for the FOF search. */ void fof_init(struct space *s) { - static int first_init = 1; - - /* Only read parameter file once. */ - if (first_init) { - - first_init = 0; - - struct engine *e = s->e; - - /* Check that we can write outputs by testing if the output - * directory exists and is searchable and writable. */ - parser_get_param_string(e->parameter_file, "FOF:basename", - s->fof_data.base_name); - - const char *dirp = dirname(s->fof_data.base_name); - if (access(dirp, W_OK | X_OK) != 0) { - error("Cannot write FOF outputs in directory %s (%s)", dirp, - strerror(errno)); - } - - /* Read the minimum group size. */ - s->fof_data.min_group_size = - parser_get_opt_param_int(e->parameter_file, "FOF:min_group_size", 20); - - /* Read the default group ID of particles in groups below the minimum group - * size. */ - const int default_id = parser_get_opt_param_int( - e->parameter_file, "FOF:group_id_default", 2147483647); - - /* Make sure default group ID is positive. */ - if (default_id < 0) - error("The default group ID set: %d, has to be positive.", default_id); - - s->fof_data.group_id_default = default_id; - - /* Read the starting group ID. */ - s->fof_data.group_id_offset = - parser_get_opt_param_int(e->parameter_file, "FOF:group_id_offset", 1); - - /* Read the linking length scale. */ - const double l_x_scale = parser_get_opt_param_double( - e->parameter_file, "FOF:linking_length_scale", 0.2); - - /* Calculate the particle linking length based upon the mean inter-particle - * spacing of the DM particles. */ - const long long total_nr_dmparts = - e->total_nr_gparts - e->total_nr_parts - e->total_nr_sparts; - double l_x = l_x_scale * (s->dim[0] / cbrt(total_nr_dmparts)); - - l_x = parser_get_opt_param_double(e->parameter_file, - "FOF:absolute_linking_length", l_x); - - s->fof_data.l_x2 = l_x * l_x; - - s->fof_data.extra_bh_seed_count = 0; - s->fof_data.seed_halo_mass = parser_get_param_double( - e->parameter_file, "EAGLEBlackHoles:seed_halo_mass"); - ; - - /* Read the initial group_links array size. */ - s->fof_data.group_links_size_default = parser_get_opt_param_double( - e->parameter_file, "FOF:group_links_size_default", 20000); - -#ifdef WITH_MPI - /* Check size of linking length against the top-level cell dimensions. */ - if (l_x > s->width[0]) - error( - "Linking length greater than the width of a top-level cell. Need to " - "check more than one layer of top-level cells for links."); - - if (MPI_Type_contiguous(sizeof(struct fof_mpi) / sizeof(unsigned char), - MPI_BYTE, &fof_mpi_type) != MPI_SUCCESS || - MPI_Type_commit(&fof_mpi_type) != MPI_SUCCESS) { - error("Failed to create MPI type for fof."); - } - if (MPI_Type_contiguous(sizeof(struct group_length) / sizeof(unsigned char), - MPI_BYTE, &group_length_mpi_type) != MPI_SUCCESS || - MPI_Type_commit(&group_length_mpi_type) != MPI_SUCCESS) { - error("Failed to create MPI type for group_length."); - } - /* Define type for sending fof_final_index struct */ - if (MPI_Type_contiguous(sizeof(struct fof_final_index), MPI_BYTE, - &fof_final_index_type) != MPI_SUCCESS || - MPI_Type_commit(&fof_final_index_type) != MPI_SUCCESS) { - error("Failed to create MPI type for fof_final_index."); - } - /* Define type for sending fof_final_mass struct */ - if (MPI_Type_contiguous(sizeof(struct fof_final_mass), MPI_BYTE, - &fof_final_mass_type) != MPI_SUCCESS || - MPI_Type_commit(&fof_final_mass_type) != MPI_SUCCESS) { - error("Failed to create MPI type for fof_final_mass."); + const struct engine *e = s->e; + + /* Check that we can write outputs by testing if the output + * directory exists and is searchable and writable. */ + parser_get_param_string(e->parameter_file, "FOF:basename", + s->fof_data.base_name); + + const char *dirp = dirname(s->fof_data.base_name); + if (access(dirp, W_OK | X_OK) != 0) { + error("Cannot write FOF outputs in directory %s (%s)", dirp, + strerror(errno)); + } + + /* Read the minimum group size. */ + s->fof_data.min_group_size = + parser_get_opt_param_int(e->parameter_file, "FOF:min_group_size", 20); + + /* Read the default group ID of particles in groups below the minimum group + * size. */ + const int default_id = parser_get_opt_param_int( + e->parameter_file, "FOF:group_id_default", 2147483647); + + /* Make sure default group ID is positive. */ + if (default_id < 0) + error("The default group ID set: %d, has to be positive.", default_id); + + s->fof_data.group_id_default = default_id; + + /* Read the starting group ID. */ + s->fof_data.group_id_offset = + parser_get_opt_param_int(e->parameter_file, "FOF:group_id_offset", 1); + + /* Read the linking length scale. */ + const double l_x_scale = parser_get_opt_param_double( + e->parameter_file, "FOF:linking_length_scale", 0.2); + + /* Calculate the particle linking length based upon the mean inter-particle + * spacing of the DM particles. */ + const long long total_nr_dmparts = + e->total_nr_gparts - e->total_nr_parts - e->total_nr_sparts; + double l_x = l_x_scale * (s->dim[0] / cbrt(total_nr_dmparts)); + + l_x = parser_get_opt_param_double(e->parameter_file, + "FOF:absolute_linking_length", l_x); + + s->fof_data.l_x2 = l_x * l_x; + + s->fof_data.extra_bh_seed_count = 0; + s->fof_data.seed_halo_mass = parser_get_param_double( + e->parameter_file, "EAGLEBlackHoles:seed_halo_mass"); + ; + + /* Read the initial group_links array size. */ + s->fof_data.group_links_size_default = parser_get_opt_param_double( + e->parameter_file, "FOF:group_links_size_default", 20000); +#ifdef WITH_MPI + if (MPI_Type_contiguous(sizeof(struct fof_mpi) / sizeof(unsigned char), + MPI_BYTE, &fof_mpi_type) != MPI_SUCCESS || + MPI_Type_commit(&fof_mpi_type) != MPI_SUCCESS) { + error("Failed to create MPI type for fof."); + } + if (MPI_Type_contiguous(sizeof(struct group_length) / sizeof(unsigned char), + MPI_BYTE, &group_length_mpi_type) != MPI_SUCCESS || + MPI_Type_commit(&group_length_mpi_type) != MPI_SUCCESS) { + error("Failed to create MPI type for group_length."); } + /* Define type for sending fof_final_index struct */ + if (MPI_Type_contiguous(sizeof(struct fof_final_index), MPI_BYTE, + &fof_final_index_type) != MPI_SUCCESS || + MPI_Type_commit(&fof_final_index_type) != MPI_SUCCESS) { + error("Failed to create MPI type for fof_final_index."); + } + /* Define type for sending fof_final_mass struct */ + if (MPI_Type_contiguous(sizeof(struct fof_final_mass), MPI_BYTE, + &fof_final_mass_type) != MPI_SUCCESS || + MPI_Type_commit(&fof_final_mass_type) != MPI_SUCCESS) { + error("Failed to create MPI type for fof_final_mass."); + } #endif - + #if defined(WITH_MPI) && defined(UNION_BY_SIZE_OVER_MPI) - if (engine_rank == 0) - message( - "Performing FOF over MPI using union by size and union by rank " - "locally."); + if (engine_rank == 0) + message( + "Performing FOF over MPI using union by size and union by rank " + "locally."); #else - message("Performing FOF using union by rank."); + message("Performing FOF using union by rank."); #endif - } +} + +/* Initialises parameters for the FOF search. */ +void fof_allocate(struct space *s) { const size_t nr_local_gparts = s->nr_gparts; +#ifdef WITH_MPI + /* Check size of linking length against the top-level cell dimensions. */ + if (s->fof_data.l_x2 > s->width[0] * s->width[0]) + error( + "Linking length greater than the width of a top-level cell. Need to " + "check more than one layer of top-level cells for links."); +#endif + /* Allocate and initialise a group index array. */ if (swift_memalign("fof_group_index", (void **)&s->fof_data.group_index, 32, nr_local_gparts * sizeof(size_t)) != 0) @@ -167,7 +163,7 @@ void fof_init(struct space *s) { if (swift_memalign("fof_group_size", (void **)&s->fof_data.group_size, 32, nr_local_gparts * sizeof(size_t)) != 0) error("Failed to allocate list of group size for FOF search."); - + /* Set initial group index to particle offset into array and set default group * ID. */ for (size_t i = 0; i < nr_local_gparts; i++) { diff --git a/src/fof.h b/src/fof.h index dd318d16b35f1dfc9d395a8220036c6ec7c6500b..c6e60a2ae9d12f988459f81cd0a53dca62c810c3 100644 --- a/src/fof.h +++ b/src/fof.h @@ -54,7 +54,7 @@ struct fof_mpi { } SWIFT_STRUCT_ALIGN; -struct fof { +struct fof_props { size_t *group_index; size_t *group_size; @@ -127,6 +127,7 @@ struct cell_pair_indices { /* Function prototypes. */ void fof_init(struct space *s); +void fof_allocate(struct space *s); void fof_search_cell(struct space *s, struct cell *c); void fof_search_pair_cells(struct space *s, struct cell *ci, struct cell *cj); void fof_search_pair_cells_foreign(struct space *s, struct cell *ci, diff --git a/src/space.h b/src/space.h index 603ad3523a056f2f8d01803715e45ca1531c25db..4a2d5d8ce92d49ef129fc32c9332bc811e67f795 100644 --- a/src/space.h +++ b/src/space.h @@ -261,9 +261,6 @@ struct space { /*! The associated engine. */ struct engine *e; - /*! The FOF group data. */ - struct fof fof_data; - /*! The group information returned by VELOCIraptor for each #gpart. */ struct velociraptor_gpart_data *gpart_group_data;