MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
stats.c
Go to the documentation of this file.
1 #include <mpi.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <math.h>
6 #include <omp.h>
7 
8 #include "timestep.h"
9 #include "physconst.h"
10 #include "cooling.h"
11 #include "slotsmanager.h"
12 #include "hydra.h"
13 #include "utils.h"
14 #include "stats.h"
15 #include "walltime.h"
16 #include "cooling_qso_lightup.h"
17 
18 /* global state of system
19 */
21 {
22  double Mass;
23  double EnergyKin;
24  double EnergyPot;
25  double EnergyInt;
26  double EnergyTot;
27 
28  double Momentum[4];
29  double AngMomentum[4];
30  double CenterOfMass[4];
31  double MassComp[6];
32  /* Only Gas is used */
33  double TemperatureComp[6];
34 
35  double EnergyKinComp[6];
36  double EnergyPotComp[6];
37  double EnergyIntComp[6];
38  double EnergyTotComp[6];
39  double MomentumComp[6][4];
40  double AngMomentumComp[6][4];
41  double CenterOfMassComp[6][4];
42 };
43 
44 static struct stats_params
45 {
46  /* some filenames */
47  char EnergyFile[100];
48  char CpuFile[100];
49  /*Should we store the energy to EnergyFile on PM timesteps.*/
51  int WriteBlackHoleDetails; /* write BH details every time step*/
53 
54 void
56 {
57  int ThisTask;
58  MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask);
59  if(ThisTask == 0) {
61  param_get_string2(ps, "CpuFile", StatsParams.CpuFile, sizeof(StatsParams.CpuFile));
62  StatsParams.OutputEnergyDebug = param_get_int(ps, "OutputEnergyDebug");
63  StatsParams.WriteBlackHoleDetails = param_get_int(ps,"WriteBlackHoleDetails");
64  }
65  MPI_Bcast(&StatsParams, sizeof(struct stats_params), MPI_BYTE, 0, MPI_COMM_WORLD);
66 }
67 
72 void
73 open_outputfiles(int RestartSnapNum, struct OutputFD * fds, const char * OutputDir, int BlackHoleOn, int StarformationOn)
74 {
75  const char mode[3]="a+";
76  char * buf;
77  char * postfix;
78  int ThisTask;
79  MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask);
80  memset(fds, 0, sizeof(struct OutputFD));
81  fds->FdCPU = NULL;
82  fds->FdEnergy = NULL;
83  fds->FdBlackHoles = NULL;
84  fds->FdSfr = NULL;
85  fds->FdBlackholeDetails = NULL;
86  fds->FdHelium = NULL;
87 
88  if(RestartSnapNum != -1) {
89  postfix = fastpm_strdup_printf("-R%03d", RestartSnapNum);
90  } else {
91  postfix = fastpm_strdup_printf("%s", "");
92  }
93 
94  /* all the processors write to separate files*/
95  if(BlackHoleOn && StatsParams.WriteBlackHoleDetails){
96  buf = fastpm_strdup_printf("%s/%s%s/%06X", OutputDir,"BlackholeDetails",postfix,ThisTask);
98  if(!(fds->FdBlackholeDetails = fopen(buf,"a")))
99  endrun(1, "Failed to open blackhole detail %s\n", buf);
100  myfree(buf);
101  }
102 
103  /* only the root processors writes to the log files */
104  if(ThisTask != 0) {
105  return;
106  }
107 
108  if(BlackHoleOn) {
109  buf = fastpm_strdup_printf("%s/%s%s", OutputDir, "blackholes.txt", postfix);
111  if(!(fds->FdBlackHoles = fopen(buf, mode)))
112  endrun(1, "error in opening file '%s'\n", buf);
113  myfree(buf);
114  }
115 
116  buf = fastpm_strdup_printf("%s/%s%s", OutputDir, StatsParams.CpuFile, postfix);
118  if(!(fds->FdCPU = fopen(buf, mode)))
119  endrun(1, "error in opening file '%s'\n", buf);
120  myfree(buf);
121 
123  buf = fastpm_strdup_printf("%s/%s%s", OutputDir, StatsParams.EnergyFile, postfix);
125  if(!(fds->FdEnergy = fopen(buf, mode)))
126  endrun(1, "error in opening file '%s'\n", buf);
127  myfree(buf);
128  }
129 
130  if(StarformationOn) {
131  buf = fastpm_strdup_printf("%s/%s%s", OutputDir, "sfr.txt", postfix);
133  if(!(fds->FdSfr = fopen(buf, mode)))
134  endrun(1, "error in opening file '%s'\n", buf);
135  myfree(buf);
136  }
137 
138  if(qso_lightup_on()) {
139  buf = fastpm_strdup_printf("%s/%s%s", OutputDir, "helium.txt", postfix);
141  if(!(fds->FdHelium = fopen(buf, mode)))
142  endrun(1, "error in opening file '%s'\n", buf);
143  myfree(buf);
144  }
145 }
146 
149 void
151 {
152  if(fds->FdCPU)
153  fclose(fds->FdCPU);
154  if(fds->FdEnergy)
155  fclose(fds->FdEnergy);
156  if(fds->FdSfr)
157  fclose(fds->FdSfr);
158  if(fds->FdBlackHoles)
159  fclose(fds->FdBlackHoles);
160  if(fds->FdBlackholeDetails)
161  fclose(fds->FdBlackholeDetails);
162 }
163 
164 
165 void write_cpu_log(int NumCurrentTiStep, const double atime, FILE * FdCPU, double ElapsedTime)
166 {
167  walltime_summary(0, MPI_COMM_WORLD);
168 
169  if(FdCPU)
170  {
171  int NTask;
172  MPI_Comm_size(MPI_COMM_WORLD, &NTask);
173  fprintf(FdCPU, "Step %d, Time: %g, MPIs: %d Threads: %d Elapsed: %g\n", NumCurrentTiStep, atime, NTask, omp_get_max_threads(), ElapsedTime);
174  walltime_report(FdCPU, 0, MPI_COMM_WORLD);
175  fflush(FdCPU);
176  }
177 }
178 
179 /* This routine computes various global properties of the particle
180  * distribution and stores the result in the struct `SysState'.
181  * Currently, not all the information that's computed here is
182  * actually used (e.g. momentum is not really used anywhere),
183  * just the energies are written to a log-file every once in a while.
184  */
186 {
187  int i, j;
188  struct state_of_system sys;
189  struct state_of_system SysState;
190  double a1, a2, a3;
191  int ThisTask;
192 
193  a1 = Time;
194  a2 = Time * Time;
195  a3 = Time * Time * Time;
196 
197  double redshift = 1. / Time - 1;
198  memset(&sys, 0, sizeof(sys));
199  struct UVBG GlobalUVBG = get_global_UVBG(redshift);
200 
201  #pragma omp parallel for
202  for(i = 0; i < PartManager->NumPart; i++)
203  {
204  int j;
205  double entr = 0, egyspec;
206 
207  sys.MassComp[P[i].Type] += P[i].Mass;
208 
209  sys.EnergyPotComp[P[i].Type] += 0.5 * P[i].Mass * P[i].Potential / a1;
210 
211  sys.EnergyKinComp[P[i].Type] +=
212  0.5 * P[i].Mass * (P[i].Vel[0] * P[i].Vel[0] + P[i].Vel[1] * P[i].Vel[1] + P[i].Vel[2] * P[i].Vel[2]) / a2;
213 
214  if(P[i].Type == 0)
215  {
216  struct UVBG uvbg = get_local_UVBG(redshift, &GlobalUVBG, P[i].Pos, PartManager->CurrentParticleOffset);
217  entr = SPHP(i).Entropy;
218  egyspec = entr / (GAMMA_MINUS1) * pow(SPHP(i).Density / a3, GAMMA_MINUS1);
219  sys.EnergyIntComp[0] += P[i].Mass * egyspec;
220  double ne = SPHP(i).Ne;
221  sys.TemperatureComp[0] += P[i].Mass * get_temp(SPHP(i).Density, egyspec, (1 - HYDROGEN_MASSFRAC), &uvbg, &ne);
222  }
223 
224  for(j = 0; j < 3; j++)
225  {
226  sys.MomentumComp[P[i].Type][j] += P[i].Mass * P[i].Vel[j];
227  sys.CenterOfMassComp[P[i].Type][j] += P[i].Mass * P[i].Pos[j];
228  }
229 
230  sys.AngMomentumComp[P[i].Type][0] += P[i].Mass * (P[i].Pos[1] * P[i].Vel[2] - P[i].Pos[2] * P[i].Vel[1]);
231  sys.AngMomentumComp[P[i].Type][1] += P[i].Mass * (P[i].Pos[2] * P[i].Vel[0] - P[i].Pos[0] * P[i].Vel[2]);
232  sys.AngMomentumComp[P[i].Type][2] += P[i].Mass * (P[i].Pos[0] * P[i].Vel[1] - P[i].Pos[1] * P[i].Vel[0]);
233  }
234 
235 
236  /* some the stuff over all processors */
237  MPI_Reduce(&sys.MassComp[0], &SysState.MassComp[0], 6, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
238  MPI_Reduce(&sys.EnergyPotComp[0], &SysState.EnergyPotComp[0], 6, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
239  MPI_Reduce(&sys.EnergyIntComp[0], &SysState.EnergyIntComp[0], 6, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
240  MPI_Reduce(&sys.EnergyKinComp[0], &SysState.EnergyKinComp[0], 6, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
241  MPI_Reduce(&sys.TemperatureComp[0], &SysState.TemperatureComp[0], 6, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
242  MPI_Reduce(&sys.MomentumComp[0][0], &SysState.MomentumComp[0][0], 6 * 4, MPI_DOUBLE, MPI_SUM, 0,
243  MPI_COMM_WORLD);
244  MPI_Reduce(&sys.AngMomentumComp[0][0], &SysState.AngMomentumComp[0][0], 6 * 4, MPI_DOUBLE, MPI_SUM, 0,
245  MPI_COMM_WORLD);
246  MPI_Reduce(&sys.CenterOfMassComp[0][0], &SysState.CenterOfMassComp[0][0], 6 * 4, MPI_DOUBLE, MPI_SUM, 0,
247  MPI_COMM_WORLD);
248 
249  MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask);
250  if(ThisTask == 0)
251  {
252  for(i = 0; i < 6; i++) {
253  SysState.EnergyTotComp[i] = SysState.EnergyKinComp[i] +
254  SysState.EnergyPotComp[i] + SysState.EnergyIntComp[i];
255  }
256 
257  SysState.Mass = SysState.EnergyKin = SysState.EnergyPot = SysState.EnergyInt = SysState.EnergyTot = 0;
258 
259  for(i = 0; i < 6; i++)
260  {
261  if(SysState.MassComp[i] > 0) {
262  SysState.TemperatureComp[i] /= SysState.MassComp[i];
263  }
264  }
265 
266  for(j = 0; j < 3; j++)
267  SysState.Momentum[j] = SysState.AngMomentum[j] = SysState.CenterOfMass[j] = 0;
268 
269  for(i = 0; i < 6; i++)
270  {
271  SysState.Mass += SysState.MassComp[i];
272  SysState.EnergyKin += SysState.EnergyKinComp[i];
273  SysState.EnergyPot += SysState.EnergyPotComp[i];
274  SysState.EnergyInt += SysState.EnergyIntComp[i];
275  SysState.EnergyTot += SysState.EnergyTotComp[i];
276 
277  for(j = 0; j < 3; j++)
278  {
279  SysState.Momentum[j] += SysState.MomentumComp[i][j];
280  SysState.AngMomentum[j] += SysState.AngMomentumComp[i][j];
281  SysState.CenterOfMass[j] += SysState.CenterOfMassComp[i][j];
282  }
283  }
284 
285  for(i = 0; i < 6; i++)
286  for(j = 0; j < 3; j++)
287  if(SysState.MassComp[i] > 0)
288  SysState.CenterOfMassComp[i][j] /= SysState.MassComp[i];
289 
290  for(j = 0; j < 3; j++)
291  if(SysState.Mass > 0)
292  SysState.CenterOfMass[j] /= SysState.Mass;
293 
294  for(i = 0; i < 6; i++)
295  {
296  SysState.CenterOfMassComp[i][3] = SysState.MomentumComp[i][3] = SysState.AngMomentumComp[i][3] = 0;
297  for(j = 0; j < 3; j++)
298  {
299  SysState.CenterOfMassComp[i][3] +=
300  SysState.CenterOfMassComp[i][j] * SysState.CenterOfMassComp[i][j];
301  SysState.MomentumComp[i][3] += SysState.MomentumComp[i][j] * SysState.MomentumComp[i][j];
302  SysState.AngMomentumComp[i][3] +=
303  SysState.AngMomentumComp[i][j] * SysState.AngMomentumComp[i][j];
304  }
305  SysState.CenterOfMassComp[i][3] = sqrt(SysState.CenterOfMassComp[i][3]);
306  SysState.MomentumComp[i][3] = sqrt(SysState.MomentumComp[i][3]);
307  SysState.AngMomentumComp[i][3] = sqrt(SysState.AngMomentumComp[i][3]);
308  }
309 
310  SysState.CenterOfMass[3] = SysState.Momentum[3] = SysState.AngMomentum[3] = 0;
311 
312  for(j = 0; j < 3; j++)
313  {
314  SysState.CenterOfMass[3] += SysState.CenterOfMass[j] * SysState.CenterOfMass[j];
315  SysState.Momentum[3] += SysState.Momentum[j] * SysState.Momentum[j];
316  SysState.AngMomentum[3] += SysState.AngMomentum[j] * SysState.AngMomentum[j];
317  }
318 
319  SysState.CenterOfMass[3] = sqrt(SysState.CenterOfMass[3]);
320  SysState.Momentum[3] = sqrt(SysState.Momentum[3]);
321  SysState.AngMomentum[3] = sqrt(SysState.AngMomentum[3]);
322  }
323 
324  /* give everyone the result, maybe the want to do something with it */
325  MPI_Bcast(&SysState, sizeof(struct state_of_system), MPI_BYTE, 0, MPI_COMM_WORLD);
326  return SysState;
327 }
328 
334 void energy_statistics(FILE * FdEnergy, const double Time, struct part_manager_type * PartManager)
335 {
336  if(!FdEnergy)
337  return;
338 
340 
341  message(0, "Time %g Mean Temperature of Gas %g\n",
342  Time, SysState.TemperatureComp[0]);
343 
344  fprintf(FdEnergy,
345  "%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g\n",
346  Time, SysState.TemperatureComp[0], SysState.EnergyInt, SysState.EnergyPot, SysState.EnergyKin, SysState.EnergyIntComp[0],
347  SysState.EnergyPotComp[0], SysState.EnergyKinComp[0], SysState.EnergyIntComp[1],
348  SysState.EnergyPotComp[1], SysState.EnergyKinComp[1], SysState.EnergyIntComp[2],
349  SysState.EnergyPotComp[2], SysState.EnergyKinComp[2], SysState.EnergyIntComp[3],
350  SysState.EnergyPotComp[3], SysState.EnergyKinComp[3], SysState.EnergyIntComp[4],
351  SysState.EnergyPotComp[4], SysState.EnergyKinComp[4], SysState.EnergyIntComp[5],
352  SysState.EnergyPotComp[5], SysState.EnergyKinComp[5], SysState.MassComp[0],
353  SysState.MassComp[1], SysState.MassComp[2], SysState.MassComp[3], SysState.MassComp[4],
354  SysState.MassComp[5]);
355 
356  fflush(FdEnergy);
357 }
double get_temp(double density, double ienergy, double helium, const struct UVBG *uvbg, double *ne_init)
struct UVBG get_local_UVBG(double redshift, const struct UVBG *const GlobalUVBG, const double *const Pos, const double *const PosOffset)
struct UVBG get_global_UVBG(double redshift)
int qso_lightup_on(void)
void message(int where, const char *fmt,...)
Definition: endrun.c:175
void endrun(int where, const char *fmt,...)
Definition: endrun.c:147
#define myfree(x)
Definition: mymalloc.h:19
void param_get_string2(ParameterSet *ps, const char *name, char *dst, size_t len)
Definition: paramset.c:355
int param_get_int(ParameterSet *ps, const char *name)
Definition: paramset.c:368
struct part_manager_type PartManager[1]
Definition: partmanager.c:11
#define P
Definition: partmanager.h:88
#define HYDROGEN_MASSFRAC
Definition: physconst.h:37
#define GAMMA_MINUS1
Definition: physconst.h:35
#define SPHP(i)
Definition: slotsmanager.h:124
void write_cpu_log(int NumCurrentTiStep, const double atime, FILE *FdCPU, double ElapsedTime)
Definition: stats.c:165
void close_outputfiles(struct OutputFD *fds)
Definition: stats.c:150
void energy_statistics(FILE *FdEnergy, const double Time, struct part_manager_type *PartManager)
Definition: stats.c:334
static struct stats_params StatsParams
void open_outputfiles(int RestartSnapNum, struct OutputFD *fds, const char *OutputDir, int BlackHoleOn, int StarformationOn)
Definition: stats.c:73
struct state_of_system compute_global_quantities_of_system(const double Time, struct part_manager_type *PartManager)
Definition: stats.c:185
void set_stats_params(ParameterSet *ps)
Definition: stats.c:55
void fastpm_path_ensure_dirname(const char *path)
Definition: string.c:70
char * fastpm_strdup_printf(const char *fmt,...)
Definition: string.c:41
Definition: stats.h:8
FILE * FdBlackHoles
Definition: stats.h:12
FILE * FdBlackholeDetails
Definition: stats.h:13
FILE * FdHelium
Definition: stats.h:14
FILE * FdEnergy
Definition: stats.h:9
FILE * FdSfr
Definition: stats.h:11
FILE * FdCPU
Definition: stats.h:10
Definition: cooling.h:8
double CurrentParticleOffset[3]
Definition: partmanager.h:82
double Momentum[4]
Definition: stats.c:28
double EnergyTot
Definition: stats.c:26
double EnergyTotComp[6]
Definition: stats.c:38
double AngMomentumComp[6][4]
Definition: stats.c:40
double AngMomentum[4]
Definition: stats.c:29
double MassComp[6]
Definition: stats.c:31
double MomentumComp[6][4]
Definition: stats.c:39
double CenterOfMassComp[6][4]
Definition: stats.c:41
double Mass
Definition: stats.c:22
double EnergyKinComp[6]
Definition: stats.c:35
double EnergyInt
Definition: stats.c:25
double EnergyKin
Definition: stats.c:23
double TemperatureComp[6]
Definition: stats.c:33
double CenterOfMass[4]
Definition: stats.c:30
double EnergyPot
Definition: stats.c:24
double EnergyPotComp[6]
Definition: stats.c:36
double EnergyIntComp[6]
Definition: stats.c:37
char CpuFile[100]
Definition: stats.c:48
char EnergyFile[100]
Definition: stats.c:47
int OutputEnergyDebug
Definition: stats.c:50
int WriteBlackHoleDetails
Definition: stats.c:51
int ThisTask
Definition: test_exchange.c:23
int NTask
Definition: test_exchange.c:23
void walltime_summary(int root, MPI_Comm comm)
Definition: walltime.c:55
void walltime_report(FILE *fp, int root, MPI_Comm comm)
Definition: walltime.c:220