MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
powerspectrum.c
Go to the documentation of this file.
1 #include <mpi.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <stdint.h>
5 #include <string.h>
6 #include <math.h>
7 
8 #include "types.h"
9 #include "powerspectrum.h"
10 #include "physconst.h"
11 #include "utils.h"
12 
13 /*Power spectrum related functions*/
14 
15 /*Allocate memory for the power spectrum*/
16 void powerspectrum_alloc(Power * ps, const int nbins, const int nthreads, const int MassiveNuLinResp, const double BoxSize_in_cm)
17 {
18  ps->size = nbins;
19  const int nalloc = nbins*nthreads;
20  ps->nalloc = nalloc;
21  ps->kk = (double *) mymalloc("Powerspectrum", sizeof(double) * 2*nalloc);
22  ps->Power = ps->kk + nalloc;
23  ps->BoxSize_in_MPC = BoxSize_in_cm / CM_PER_MPC;
24  ps->logknu = NULL;
25  if(MassiveNuLinResp) {
26  /*These arrays are stored separately to make interpolation more accurate*/
27  ps->logknu = (double *) mymalloc("PowerNu", sizeof(double) * 2*nbins);
28  ps->delta_nu_ratio = ps-> logknu + nbins;
29  }
30  ps->Nmodes = (int64_t *) mymalloc("Powermodes", sizeof(int64_t) * nalloc);
32 }
33 
34 /*Zero memory for the power spectrum*/
36 {
37  memset(ps->kk, 0, sizeof(double) * ps->nalloc);
38  memset(ps->Power, 0, sizeof(double) * ps->nalloc);
39  memset(ps->Nmodes, 0, sizeof(int64_t) * ps->nalloc);
40  ps->Norm = 0;
41 }
42 
43 /*Free power spectrum memory*/
45 {
46  myfree(ps->Nmodes);
47  if(ps->logknu)
48  myfree(ps->logknu);
49  myfree(ps->kk);
50 }
51 
52 /* Sum the different modes on each thread and processor together to get a power spectrum,
53  * and fix the units. */
55 {
56  /*Sum power spectrum thread-local storage*/
57  int i,j;
58  for(i = 0; i < ps->size; i ++) {
59  for(j = 1; j < ps->nalloc/ps->size; j++) {
60  ps->Power[i] += ps->Power[i+ ps->size*j];
61  ps->kk[i] += ps->kk[i+ ps->size*j];
62  ps->Nmodes[i] += ps->Nmodes[i +ps->size*j];
63  }
64  }
65 
66  /*Now sum power spectrum MPI storage*/
67  MPI_Allreduce(MPI_IN_PLACE, &(ps->Norm), 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
68  MPI_Allreduce(MPI_IN_PLACE, ps->kk, ps->size, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
69  MPI_Allreduce(MPI_IN_PLACE, ps->Power, ps->size, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
70  MPI_Allreduce(MPI_IN_PLACE, ps->Nmodes, ps->size, MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
71 
72  int nk_nz = 0;
73  /*Now fix power spectrum units and remove zero entries.*/
74  for(i = 0; i < ps->size; i ++) {
75  if(ps->Nmodes[i] == 0) continue;
76  ps->Power[i] /= ps->Nmodes[i];
77  ps->Power[i] /= ps->Norm;
78  ps->kk[i] /= ps->Nmodes[i];
79  /* Mpc/h units */
80  ps->kk[i] *= 2 * M_PI / (ps->BoxSize_in_MPC);
81  ps->Power[i] *= pow(ps->BoxSize_in_MPC , 3.0);
82  /*Move the power spectrum earlier, removing zero modes*/
83  ps->Power[nk_nz] = ps->Power[i];
84  ps->kk[nk_nz] = ps->kk[i];
85  ps->Nmodes[nk_nz] = ps->Nmodes[i];
86  nk_nz++;
87  }
88  ps->nonzero = nk_nz;
89 }
90 
91 /*Save the power spectrum to a file*/
92 void powerspectrum_save(Power * ps, const char * OutputDir, const char * filename, const double Time, const double D1)
93 {
94  int i;
95  int ThisTask;
96  MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask);
97  if(ThisTask != 0)
98  return;
99  char * fname = fastpm_strdup_printf("%s/%s-%0.4f.txt", OutputDir, filename, Time);
100  /* Avoid -0.0000.txt at high z*/
101  if(Time <= 1e-4) {
102  myfree(fname);
103  fname = fastpm_strdup_printf("%s/%s-%0.4e.txt", OutputDir, filename, Time);
104  }
105  message(1, "Writing Power Spectrum to %s\n", fname);
106  FILE * fp = fopen(fname, "w");
107  if(!fp)
108  message(1, "Could not open %s for writing\n", fname);
109  else {
110  fprintf(fp, "# in Mpc/h Units \n");
111  fprintf(fp, "# D1 = %g \n", D1);
112  fprintf(fp, "# k P N P(z=0)\n");
113  for(i = 0; i < ps->nonzero; i ++) {
114  fprintf(fp, "%g %g %ld %g\n", ps->kk[i], ps->Power[i], ps->Nmodes[i],
115  ps->Power[i] / (D1 * D1));
116  }
117  fclose(fp);
118  }
119  myfree(fname);
120 }
void message(int where, const char *fmt,...)
Definition: endrun.c:175
#define mymalloc(name, size)
Definition: mymalloc.h:15
#define myfree(x)
Definition: mymalloc.h:19
#define CM_PER_MPC
Definition: physconst.h:20
void powerspectrum_save(Power *ps, const char *OutputDir, const char *filename, const double Time, const double D1)
Definition: powerspectrum.c:92
void powerspectrum_free(Power *ps)
Definition: powerspectrum.c:44
void powerspectrum_sum(Power *ps)
Definition: powerspectrum.c:54
void powerspectrum_zero(Power *ps)
Definition: powerspectrum.c:35
void powerspectrum_alloc(Power *ps, const int nbins, const int nthreads, const int MassiveNuLinResp, const double BoxSize_in_cm)
Definition: powerspectrum.c:16
char * fastpm_strdup_printf(const char *fmt,...)
Definition: string.c:41
double * logknu
Definition: powerspectrum.h:20
double * delta_nu_ratio
Definition: powerspectrum.h:21
double * Power
Definition: powerspectrum.h:10
double BoxSize_in_MPC
Definition: powerspectrum.h:17
int64_t * Nmodes
Definition: powerspectrum.h:11
#define MPI_INT64
Definition: system.h:12
int ThisTask
Definition: test_exchange.c:23