GADGET-4
io_treelinks.cc
Go to the documentation of this file.
1 /*******************************************************************************
2  * \copyright This file is part of the GADGET4 N-body/SPH code developed
3  * \copyright by Volker Springel. Copyright (C) 2014-2020 by Volker Springel
4  * \copyright (vspringel@mpa-garching.mpg.de) and all contributing authors.
5  *******************************************************************************/
6 
12 #include "gadgetconfig.h"
13 
14 #ifdef MERGERTREE
15 
16 #include <gsl/gsl_rng.h>
17 #include <hdf5.h>
18 #include <math.h>
19 #include <mpi.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 
27 #include "../data/allvars.h"
28 #include "../data/dtypes.h"
29 #include "../data/mymalloc.h"
30 #include "../fof/fof.h"
31 #include "../io/hdf5_util.h"
32 #include "../io/io.h"
33 #include "../logs/timer.h"
34 #include "../main/simulation.h"
35 #include "../mergertree/io_treelinks.h"
36 #include "../mergertree/mergertree.h"
37 #include "../mpi_utils/mpi_utils.h"
38 #include "../sort/parallel_sort.h"
39 #include "../subfind/subfind.h"
40 #include "../system/system.h"
41 
42 treelinks_io::treelinks_io(mergertree *MergerTree_ptr, MPI_Comm comm, int format) : IO_Def(comm, format)
43 {
44  MergerTree = MergerTree_ptr;
45 
46  this->N_IO_Fields = 0;
47  this->N_DataGroups = 1;
48  this->header_size = sizeof(header);
49  this->header_buf = &header;
50  this->type_of_file = FILE_IS_TREELINK;
51  sprintf(this->info, "TREELINK: writing treelink information");
52 
53  init_field("TRNR", "TreeID", MEM_INT64, FILE_INT64, READ_IF_PRESENT, 1, A_TL, &MergerTree->TreeLink[0].TreeID, NULL, TREELINK, 0, 0,
54  0, 0, 0, 0, 0, true);
55 
56  init_field("TRIX", "TreeIndex", MEM_INT, FILE_INT, READ_IF_PRESENT, 1, A_TL, &MergerTree->TreeLink[0].TreeIndex, NULL, TREELINK, 0,
57  0, 0, 0, 0, 0, 0, true);
58 }
59 
60 void treelinks_io::treelinks_save(int num)
61 {
62  char buf[MAXLEN_PATH_EXTRA];
63 
64  /* write treelink info */
65  if(All.NumFilesPerSnapshot > 1)
66  {
67  if(ThisTask == 0)
68  {
69  sprintf(buf, "%s/groups_%03d", All.OutputDir, num);
70  mkdir(buf, 02755);
71  }
72  MPI_Barrier(Communicator);
73  }
74 
75  if(All.NumFilesPerSnapshot > 1)
76  sprintf(buf, "%s/groups_%03d/%s_%03d", All.OutputDir, num, "subhalo_treelink", num);
77  else
78  sprintf(buf, "%s%s_%03d", All.OutputDir, "subhalo_treelink", num);
79 
80  write_multiple_files(buf, All.NumFilesPerSnapshot);
81 }
82 
83 void treelinks_io::fill_file_header(int writeTask, int lastTask, long long *n_type, long long *ntot_type)
84 {
85  /* determine group/id numbers of each type in file */
86 
87  n_type[0] = Nsubhalos;
88 
89  if(ThisTask == writeTask)
90  {
91  for(int n = 0; n < 1; n++)
92  ntot_type[n] = n_type[n];
93 
94  for(int task = writeTask + 1; task <= lastTask; task++)
95  {
96  long long nn[1];
97  MPI_Recv(&nn[0], 1, MPI_LONG_LONG, task, TAG_LOCALN, Communicator, MPI_STATUS_IGNORE);
98  for(int n = 0; n < 1; n++)
99  ntot_type[n] += nn[n];
100  }
101 
102  for(int task = writeTask + 1; task <= lastTask; task++)
103  MPI_Send(&ntot_type[0], 1, MPI_LONG_LONG, task, TAG_N, Communicator);
104  }
105  else
106  {
107  MPI_Send(&n_type[0], 1, MPI_LONG_LONG, writeTask, TAG_LOCALN, Communicator);
108  MPI_Recv(&ntot_type[0], 1, MPI_LONG_LONG, writeTask, TAG_N, Communicator, MPI_STATUS_IGNORE);
109  }
110 
111  /* fill file header */
112 
113  header.Nsubhalos = ntot_type[0];
114  header.TotNsubhalos = TotNsubhalos;
115  header.num_files = All.NumFilesPerSnapshot;
116 }
117 
118 void treelinks_io::read_file_header(const char *fname, int filenr, int readTask, int lastTask, long long *n_type, long long *ntot_type,
119  int *nstart)
120 {
121  /* empty */
122 }
123 
124 void treelinks_io::write_header_fields(hid_t handle)
125 {
126  write_scalar_attribute(handle, "Nsubhalos_ThisFile", &header.Nsubhalos, H5T_NATIVE_UINT64);
127 
128  write_scalar_attribute(handle, "Nsubhalos_Total", &header.TotNsubhalos, H5T_NATIVE_UINT64);
129 
130  write_scalar_attribute(handle, "NumFiles", &header.num_files, H5T_NATIVE_INT);
131 }
132 
133 void treelinks_io::read_header_fields(const char *fname)
134 { /* empty */
135 }
136 
137 int treelinks_io::get_filenr_from_header(void) { return header.num_files; }
138 
139 void treelinks_io::set_filenr_in_header(int numfiles) { header.num_files = numfiles; }
140 
141 void treelinks_io::read_increase_numbers(int type, int n_for_this_task)
142 { /* empty */
143 }
144 
145 void treelinks_io::get_datagroup_name(int type, char *buf)
146 {
147  switch(type)
148  {
149  case 0:
150  sprintf(buf, "/Subhalo");
151  break;
152  default:
153  Terminate("wrong group");
154  break;
155  }
156 }
157 
158 int treelinks_io::get_type_of_element(int index)
159 {
160  /* empty */
161  return 0;
162 }
163 
164 void treelinks_io::set_type_of_element(int index, int type)
165 { /* empty */
166 }
167 
168 void *treelinks_io::get_base_address_of_structure(enum arrays array, int index)
169 {
170  switch(array)
171  {
172  case A_TL:
173  return (void *)(MergerTree->TreeLink + index);
174  default:
175  Terminate("strange, we don't expect to get here");
176  }
177 }
178 
179 #endif
global_data_all_processes All
Definition: main.cc:40
Definition: io.h:129
#define MAXLEN_PATH_EXTRA
Definition: constants.h:301
void write_scalar_attribute(hid_t handle, const char *attr_name, const void *buf, hid_t mem_type_id)
Definition: hdf5_util.cc:621
@ READ_IF_PRESENT
Definition: io.h:124
@ TREELINK
Definition: io.h:114
arrays
Definition: io.h:30
@ A_TL
Definition: io.h:44
@ FILE_INT64
Definition: io.h:68
@ FILE_INT
Definition: io.h:67
@ MEM_INT
Definition: io.h:79
@ MEM_INT64
Definition: io.h:80
@ FILE_IS_TREELINK
Definition: io.h:58
#define Terminate(...)
Definition: macros.h:19
#define TAG_LOCALN
Definition: mpi_utils.h:52
#define TAG_N
Definition: mpi_utils.h:25
char OutputDir[MAXLEN_PATH]
Definition: allvars.h:272