8 #include <bigfile-mpi.h>
21 static void fof_write_header(BigFile * bf, int64_t TotNgroups,
const double atime,
const double * MassTable,
Cosmology *
CP, MPI_Comm Comm);
27 uint64_t * u = (uint64_t *) radix;
32 void fof_save_particles(
FOFGroups * fof,
const char * OutputDir,
const char * FOFFileBase,
int num,
int SaveParticles,
Cosmology *
CP,
double atime,
const double * MassTable,
int MetalReturnOn,
int BlackholeOn, MPI_Comm Comm) {
34 struct IOTable FOFIOTable = {0};
36 message(0,
"Saving particle groups into %s\n", fname);
44 if(0 != big_file_mpi_create(&bf, fname, Comm)) {
45 endrun(0,
"Failed to open file at %s\n", fname);
55 for(i = 0; i < FOFIOTable.
used; i ++) {
61 sprintf(blockname,
"FOFGroups/%s", FOFIOTable.
ent[i].
name);
63 message(0,
"Writing Block %s\n", blockname);
84 int * selection = (
int *)
mymalloc(
"Selection",
sizeof(
int) * halo_pman.
NumPart);
86 int ptype_offset[6]={0};
87 int ptype_count[6]={0};
97 if(ptype < 6 && ptype >= 0) {
101 message(0,
"Writing Block %s\n", blockname);
114 big_file_mpi_close(&bf, Comm);
116 message(0,
"Group catalogues saved.\n");
133 uint64_t * u = (uint64_t *) out;
138 uint64_t * u = (uint64_t *) out;
144 static int fof_select_particle(
int i) {
145 return P[i].GrNr > 0;
147 static int fof_cmp_sortkey(
const void * c1,
const void * c2) {
152 static int fof_cmp_origin(
const void * c1,
const void * c2) {
188 #pragma omp parallel for
189 for(i = 0; i < halo_pman->
NumPart; i ++) {
202 #pragma omp parallel for
203 for(i = 0; i < halo_pman->
NumPart; i ++) {
219 MPI_Comm_size(Comm, &
NTask);
220 #pragma omp parallel for
221 for(i = 0; i < halo_pman->
NumPart; i ++) {
227 #pragma omp parallel for
228 for(i = 0; i < halo_pman->
NumPart; i ++) {
229 size_t index = pi[i].
origin % task_origin_offset;
230 if(index >= (
size_t) halo_pman->
NumPart)
231 endrun(23,
"entry %d has index %lu (npiglocal %d)\n", i, index, halo_pman->
NumPart);
236 #pragma omp parallel for
237 for(i = 0; i < halo_pman->
NumPart; i ++) {
251 int64_t i, NpigLocal = 0;
252 int64_t GrNrMax = -1;
253 int64_t GrNrMaxGlobal = 0;
258 halo_sman->
Base = NULL;
259 for(i = 0; i < 6; i ++) {
264 int64_t atleast[6]={0};
266 #if (defined _OPENMP) && (_OPENMP >= 201511)
267 #pragma omp parallel for reduction(+: NpigLocal, atleast)
272 int type =
P[i].Type;
274 if(type < 6 && type >= 0 && halo_sman->
info[type].
enabled)
279 halo_pman->
MaxPart = NpigLocal * FOFPartAllocFactor;
281 halo_pman->
Base = halopart;
282 halo_pman->
NumPart = NpigLocal;
287 for(i = 0; i < 6; i ++)
288 atleast[i]*= FOFPartAllocFactor;
297 if(
P[i].GrNr > GrNrMax)
299 memcpy(&halo_pman->
Base[NpigLocal], &
P[i],
sizeof(
P[i]));
309 if(NpigLocal != halo_pman->
NumPart)
310 endrun(3,
"Error in NpigLocal %ld != %ld!\n", NpigLocal, halo_pman->
NumPart);
311 MPI_Allreduce(&GrNrMax, &GrNrMaxGlobal, 1, MPI_INT, MPI_MAX, Comm);
312 message(0,
"GrNrMax before exchange is %d\n", GrNrMaxGlobal);
315 message(1930,
"Failed to exchange and write particles for the FOF. This is non-fatal, continuing\n");
322 #pragma omp parallel for reduction(max: GrNrMax)
323 for(i = 0; i < halo_pman->
NumPart; i ++) {
324 if(halopart[i].GrNr > GrNrMax)
325 GrNrMax = halopart[i].GrNr;
328 MPI_Allreduce(&GrNrMax, &GrNrMaxGlobal, 1, MPI_INT, MPI_MAX, Comm);
329 message(0,
"GrNrMax after exchange is %d\n", GrNrMaxGlobal);
335 int64_t npartLocal = fof->
Ngroups;
339 char * p = (
char *) array->data;
341 for(i = 0; i < fof->Ngroups; i ++) {
343 p += array->strides[0];
349 if(0 != big_file_mpi_create_block(bf, &bh,
"Header", NULL, 0, 0, 0, Comm)) {
350 endrun(0,
"Failed to create header\n");
354 int64_t npartLocal[6];
355 int64_t npartTotal[6];
357 for (k = 0; k < 6; k ++) {
360 #if (defined _OPENMP) && (_OPENMP >= 201511)
361 #pragma omp parallel for reduction(+: npartLocal)
364 if(
P[i].GrNr < 0)
continue;
365 npartLocal[
P[i].Type] ++;
368 MPI_Allreduce(npartLocal, npartTotal, 6,
MPI_INT64, MPI_SUM, Comm);
372 double RSD = 1.0 / (atime * hubble);
378 big_block_set_attr(&bh,
"NumPartInGroupTotal", npartTotal,
"u8", 6);
379 big_block_set_attr(&bh,
"NumFOFGroupsTotal", &TotNgroups,
"u8", 1);
380 big_block_set_attr(&bh,
"RSDFactor", &RSD,
"f8", 1);
381 big_block_set_attr(&bh,
"MassTable", MassTable,
"f8", 6);
382 big_block_set_attr(&bh,
"Time", &atime,
"f8", 1);
384 big_block_set_attr(&bh,
"OmegaLambda", &
CP->
OmegaLambda,
"f8", 1);
385 big_block_set_attr(&bh,
"Omega0", &
CP->
Omega0,
"f8", 1);
386 big_block_set_attr(&bh,
"HubbleParam", &
CP->
HubbleParam,
"f8", 1);
388 big_block_set_attr(&bh,
"OmegaBaryon", &
CP->
OmegaBaryon,
"f8", 1);
389 big_block_set_attr(&bh,
"UsePeculiarVelocity", &pecvel,
"i4", 1);
390 big_block_mpi_close(&bh, Comm);
394 #define SIMPLE_PROPERTY_FOF(name, field, type, items) \
395 SIMPLE_GETTER(GT ## name , field, type, items, struct Group ) \
396 SIMPLE_SETTER(ST ## name , field, type, items, struct Group) \
406 struct Group * grp = (
struct Group *) baseptr;
408 for(d = 0; d < 3; d ++) {
417 struct Group * grp = (
struct Group *) baseptr;
418 for(d = 0; d < 3; d ++) {
425 struct Group * grp = (
struct Group *) baseptr;
427 for(d = 0; d < 3; d ++) {
436 struct Group * grp = (
struct Group *) baseptr;
437 for(d = 0; d < 3; d ++) {
446 fac = 1.0 / params->
atime;
452 for(d = 0; d < 3; d ++) {
double hubble_function(const Cosmology *CP, double a)
void message(int where, const char *fmt,...)
void endrun(int where, const char *fmt,...)
int domain_exchange(ExchangeLayoutFunc layoutfunc, const void *layout_userdata, int do_gc, struct DriftData *drift, struct part_manager_type *pman, struct slots_manager_type *sman, int maxiter, MPI_Comm Comm)
static void STMassCenterPosition(int i, double *out, void *baseptr, void *smanptr, const struct conversions *params)
static void build_buffer_fof(FOFGroups *fof, BigArray *array, IOTableEntry *ent, struct conversions *conv)
static void GTMassCenterVelocity(int i, float *out, void *baseptr, void *slotptr, const struct conversions *params)
static int fof_distribute_particles(struct part_manager_type *halo_pman, struct slots_manager_type *halo_sman, MPI_Comm Comm)
static void GTFirstPos(int i, float *out, void *baseptr, void *smanptr, const struct conversions *params)
static void fof_radix_sortkey(const void *c1, void *out, void *arg)
static void STFirstPos(int i, float *out, void *baseptr, void *smanptr, const struct conversions *params)
static void GTMassCenterPosition(int i, double *out, void *baseptr, void *smanptr, const struct conversions *params)
static int fof_sorted_layout(int i, const void *userdata)
static void fof_write_header(BigFile *bf, int64_t TotNgroups, const double atime, const double *MassTable, Cosmology *CP, MPI_Comm Comm)
static void fof_register_io_blocks(int MetalReturnOn, int BlackHoleOn, struct IOTable *IOTable)
#define SIMPLE_PROPERTY_FOF(name, field, type, items)
void fof_save_particles(FOFGroups *fof, const char *OutputDir, const char *FOFFileBase, int num, int SaveParticles, Cosmology *CP, double atime, const double *MassTable, int MetalReturnOn, int BlackholeOn, MPI_Comm Comm)
static int order_by_type_and_grnr(const void *a, const void *b)
static void fof_radix_Group_GrNr(const void *a, void *radix, void *arg)
static int fof_try_particle_exchange(struct part_manager_type *halo_pman, struct slots_manager_type *halo_sman, MPI_Comm Comm)
static void fof_radix_origin(const void *c1, void *out, void *arg)
#define mpsort_mpi(base, nmemb, elsize, radix, rsize, arg, comm)
#define mymalloc(name, size)
#define mymalloc2(name, size)
struct part_manager_type PartManager[1]
void petaio_destroy_buffer(BigArray *array)
void destroy_io_blocks(struct IOTable *IOTable)
void register_io_blocks(struct IOTable *IOTable, int WriteGroupID, int MetalReturnOn)
void petaio_build_selection(int *selection, int *ptype_offset, int *ptype_count, const struct particle_data *Parts, const int NumPart, int(*select_func)(int i, const struct particle_data *Parts))
void petaio_alloc_buffer(BigArray *array, IOTableEntry *ent, int64_t localsize)
int GetUsePeculiarVelocity(void)
void petaio_build_buffer(BigArray *array, IOTableEntry *ent, const int *selection, const int NumSelection, struct particle_data *Parts, struct slots_manager_type *SlotsManager, struct conversions *conv)
void petaio_save_block(BigFile *bf, const char *blockname, BigArray *array, int verbose)
#define IO_REG_WRONLY(name, dtype, items, ptype, IOTable)
#define IO_REG(name, dtype, items, ptype, IOTable)
size_t slots_reserve(int where, int64_t atleast[6], struct slots_manager_type *sman)
struct slots_manager_type SlotsManager[1]
char * fastpm_strdup_printf(const char *fmt,...)
float GasMetalElemMass[NMETALS]
float StellarMetalElemMass[NMETALS]
struct particle_data * Base
double CurrentParticleOffset[3]
#define MPIU_Barrier(comm)
#define walltime_measure(name)
static enum TransferType ptype