MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
Functions | Variables
cooling_uvfluc.c File Reference
#include <mpi.h>
#include <string.h>
#include <math.h>
#include "cooling_rates.h"
#include "physconst.h"
#include "bigfile.h"
#include "bigfile-mpi.h"
#include "utils/mymalloc.h"
#include "utils/interp.h"
#include "utils/endrun.h"
Include dependency graph for cooling_uvfluc.c:

Go to the source code of this file.

Functions

static double * read_big_array (const char *filename, const char *dataset, int *Nread)
 
void init_uvf_table (const char *UVFluctuationFile, const int UVFlucLen, const double BoxSize, const double UnitLength_in_cm)
 
struct UVBG get_local_UVBG (double redshift, const struct UVBG *const GlobalUVBG, const double *const Pos, const double *const PosOffset)
 
void InitMetalCooling (const char *MetalCoolFile)
 
double TableMetalCoolingRate (double redshift, double temp, double nHcgs)
 

Variables

struct {
   int   enabled
 
   Interp   interp
 
   double *   Table
 
   ptrdiff_t   Nside
 
UVF
 
struct {
   int   CoolingNoMetal
 
   int   NRedshift_bins
 
   double *   Redshift_bins
 
   int   NHydrogenNumberDensity_bins
 
   double *   HydrogenNumberDensity_bins
 
   int   NTemperature_bins
 
   double *   Temperature_bins
 
   double *   Lmet_table
 
   Interp   interp
 
MetalCool
 

Function Documentation

◆ get_local_UVBG()

struct UVBG get_local_UVBG ( double  redshift,
const struct UVBG *const  GlobalUVBG,
const double *const  Pos,
const double *const  PosOffset 
)

Definition at line 91 of file cooling_uvfluc.c.

150 {
151  if(!UVF.enabled) {
152  /* directly use the TREECOOL table if UVF is disabled */
153  return *GlobalUVBG;
154  }
155 
156  struct UVBG uvbg = {0};
157 
158  uvbg.self_shield_dens = GlobalUVBG->self_shield_dens;
159 
160  double corrpos[3];
161  int i;
162  for(i = 0; i < 3; i++)
163  corrpos[i] = Pos[i] - PosOffset[i];
164  double zreion = interp_eval_periodic(&UVF.interp, corrpos, UVF.Table);
165  if(zreion < redshift) {
166  uvbg.zreion = zreion;
167  return uvbg;
168  }
169  memcpy(&uvbg, GlobalUVBG, sizeof(struct UVBG));
170  uvbg.zreion = zreion;
171  return uvbg;
172 }
static struct @0 UVF
double interp_eval_periodic(Interp *obj, double *x, double *ydata)
Definition: interp.c:134
Definition: cooling.h:8
double self_shield_dens
Definition: cooling.h:15
double zreion
Definition: cooling.h:16

References CM_PER_MPC, endrun(), interp_init(), interp_init_dim(), message(), read_big_array(), UnitLength_in_cm, and UVF.

Referenced by cooling_direct(), get_helium_neutral_fraction_sfreff(), get_neutral_fraction_sfreff(), and get_sfr_eeqos().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_uvf_table()

void init_uvf_table ( const char *  UVFluctuationFile,
const int  UVFlucLen,
const double  BoxSize,
const double  UnitLength_in_cm 
)

Definition at line 91 of file cooling_uvfluc.c.

92 {
93  if(strnlen(UVFluctuationFile, UVFlucLen) == 0) {
94  UVF.enabled = 0;
95  return;
96  }
97 
98  /* Open and validate the UV fluctuation file*/
99  BigFile bf;
100  BigBlock bh;
101  if(0 != big_file_mpi_open(&bf, UVFluctuationFile, MPI_COMM_WORLD)) {
102  endrun(0, "Failed to open snapshot at %s:%s\n", UVFluctuationFile,
103  big_file_get_error_message());
104  }
105 
106  if(0 != big_file_mpi_open_block(&bf, &bh, "Zreion_Table", MPI_COMM_WORLD)) {
107  endrun(0, "Failed to create block at %s:%s\n", "Header",
108  big_file_get_error_message());
109  }
110  double TableBoxSize;
111  double ReionRedshift;
112  if ((0 != big_block_get_attr(&bh, "Nmesh", &UVF.Nside, "u8", 1)) ||
113  (0 != big_block_get_attr(&bh, "BoxSize", &TableBoxSize, "f8", 1)) ||
114  (0 != big_block_get_attr(&bh, "Redshift", &ReionRedshift, "f8", 1)) ||
115  (0 != big_block_mpi_close(&bh, MPI_COMM_WORLD))) {
116  endrun(0, "Failed to close block: %s\n",
117  big_file_get_error_message());
118  }
119  big_file_mpi_close(&bf, MPI_COMM_WORLD);
120  double BoxMpc = BoxSize * UnitLength_in_cm / CM_PER_MPC;
121  if(fabs(TableBoxSize - BoxMpc) > BoxMpc * 1e-5)
122  endrun(0, "Wrong UV fluctuation file! %s is for box size %g Mpc/h, but current box is %g Mpc/h\n", UVFluctuationFile, TableBoxSize, BoxMpc);
123 
124  message(0, "Using NON-UNIFORM UV BG fluctuations from %s. Median reionization redshift is %g\n", UVFluctuationFile, ReionRedshift);
125  UVF.enabled = 1;
126 
127  int size;
128  UVF.Table = read_big_array(UVFluctuationFile, "Zreion_Table", &size);
129 
130  if(UVF.Nside * UVF.Nside * UVF.Nside != size)
131  endrun(0, "Corrupt UV Fluctuation table: Nside = %ld, but table is %ld != %ld^3\n", UVF.Nside, size, UVF.Nside);
132 
133  int64_t dims[] = {UVF.Nside, UVF.Nside, UVF.Nside};
134  interp_init(&UVF.interp, 3, dims);
135  interp_init_dim(&UVF.interp, 0, 0, BoxSize);
136  interp_init_dim(&UVF.interp, 1, 0, BoxSize);
137  interp_init_dim(&UVF.interp, 2, 0, BoxSize);
138 
139  if(UVF.Table[0] < 0.01 || UVF.Table[0] > 100.0) {
140  endrun(0, "UV Fluctuation out of range: %g\n", UVF.Table[0]);
141  }
142 }
static double * read_big_array(const char *filename, const char *dataset, int *Nread)
void message(int where, const char *fmt,...)
Definition: endrun.c:175
void endrun(int where, const char *fmt,...)
Definition: endrun.c:147
void interp_init(Interp *obj, int Ndim, int64_t *dims)
Definition: interp.c:9
void interp_init_dim(Interp *obj, int d, double Min, double Max)
Definition: interp.c:50
#define CM_PER_MPC
Definition: physconst.h:20
static double UnitLength_in_cm
Definition: power.c:26

Referenced by init_cooling_and_star_formation().

Here is the caller graph for this function:

◆ InitMetalCooling()

void InitMetalCooling ( const char *  MetalCoolFile)

Definition at line 193 of file cooling_uvfluc.c.

194 {
195  /* now initialize the metal cooling table from cloudy; we got this file
196  * from vogelsberger's Arepo simulations; it is supposed to be
197  * cloudy + UVB - H and He; look so.
198  * the table contains only 1 Z_sun values. Need to be scaled to the
199  * metallicity.
200  *
201  * */
202  /* let's see if the Metal Cool File is magic NoMetal */
203  if(strlen(MetalCoolFile) == 0) {
204  MetalCool.CoolingNoMetal = 1;
205  return;
206  } else {
207  MetalCool.CoolingNoMetal = 0;
208  }
209 
210  int size;
211  //This is never used if MetalCoolFile == ""
212  double * tabbedmet = read_big_array(MetalCoolFile, "MetallicityInSolar_bins", &size);
213 
214  if(size != 1 || tabbedmet[0] != 0.0) {
215  endrun(123, "MetalCool file %s is wrongly tabulated\n", MetalCoolFile);
216  }
217  myfree(tabbedmet);
218 
219  MetalCool.Redshift_bins = read_big_array(MetalCoolFile, "Redshift_bins", &MetalCool.NRedshift_bins);
220  MetalCool.HydrogenNumberDensity_bins = read_big_array(MetalCoolFile, "HydrogenNumberDensity_bins", &MetalCool.NHydrogenNumberDensity_bins);
221  MetalCool.Temperature_bins = read_big_array(MetalCoolFile, "Temperature_bins", &MetalCool.NTemperature_bins);
222  MetalCool.Lmet_table = read_big_array(MetalCoolFile, "NetCoolingRate", &size);
223 
224  int64_t dims[] = {MetalCool.NRedshift_bins, MetalCool.NHydrogenNumberDensity_bins, MetalCool.NTemperature_bins};
225 
226  interp_init(&MetalCool.interp, 3, dims);
227  interp_init_dim(&MetalCool.interp, 0, MetalCool.Redshift_bins[0], MetalCool.Redshift_bins[MetalCool.NRedshift_bins - 1]);
228  interp_init_dim(&MetalCool.interp, 1, MetalCool.HydrogenNumberDensity_bins[0],
229  MetalCool.HydrogenNumberDensity_bins[MetalCool.NHydrogenNumberDensity_bins - 1]);
230  interp_init_dim(&MetalCool.interp, 2, MetalCool.Temperature_bins[0],
231  MetalCool.Temperature_bins[MetalCool.NTemperature_bins - 1]);
232 }
struct @1 MetalCool
#define myfree(x)
Definition: mymalloc.h:19

References endrun(), interp_init(), interp_init_dim(), MetalCool, myfree, and read_big_array().

Referenced by init_cooling_rates().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_big_array()

static double* read_big_array ( const char *  filename,
const char *  dataset,
int *  Nread 
)
static

Definition at line 27 of file cooling_uvfluc.c.

28 {
29  int N;
30  double * buffer=NULL;
31  int ThisTask;
32  MPI_Comm_rank(MPI_COMM_WORLD, &ThisTask);
33 
34  if(ThisTask == 0) {
35  BigFile bf[1];
36  BigBlockPtr ptr;
37  BigBlock bb[1];
38  BigArray array[1];
39  size_t dims[2];
40  big_file_open(bf, filename);
41  if(0 != big_file_open_block(bf, bb, dataset)) {
42  endrun(1, "Cannot open %s %s: %s\n", filename, dataset, big_file_get_error_message());
43  }
44 
45  N = bb->size;
46 
47  if(dtype_itemsize(bb->dtype) != sizeof(double))
48  endrun(1, "UVflucatuation file %s should contain double-precision data, contains %s\n", filename, bb->dtype);
49 
50  buffer = (double *) mymalloc("cooling_data", N * dtype_itemsize(bb->dtype) * bb->nmemb);
51  dims[0] = N;
52  dims[1] = bb->nmemb;
53 
54  big_array_init(array, buffer, bb->dtype, 2, dims, NULL);
55  if(0 != big_block_seek(bb, &ptr, 0))
56  endrun(1, "Failed to seek block %s %s: %s\n", filename, dataset, big_file_get_error_message());
57 
58  if(0 != big_block_read(bb, &ptr, array))
59  endrun(1, "Failed to read %s %s: %s", filename, dataset, big_file_get_error_message());
60  /* steal the buffer */
61  big_block_close(bb);
62  big_file_close(bf);
63  }
64 
65  MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
66  if(ThisTask != 0)
67  buffer = (double *) mymalloc("cooling_data",N * sizeof(double));
68 
69  MPI_Bcast(buffer, N, MPI_DOUBLE, 0, MPI_COMM_WORLD);
70 
71  *Nread = N;
72  return buffer;
73 }
#define mymalloc(name, size)
Definition: mymalloc.h:15
int ThisTask
Definition: test_exchange.c:23

References endrun(), mymalloc, and ThisTask.

Referenced by get_local_UVBG(), and InitMetalCooling().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TableMetalCoolingRate()

double TableMetalCoolingRate ( double  redshift,
double  temp,
double  nHcgs 
)

Definition at line 235 of file cooling_uvfluc.c.

236 {
237  if(MetalCool.CoolingNoMetal)
238  return 0;
239 
240  double lognH = log10(nHcgs);
241  double logT = log10(temp);
242 
243  double x[] = {redshift, lognH, logT};
244  int status[3];
245  double rate = interp_eval(&MetalCool.interp, x, MetalCool.Lmet_table, status);
246  /* XXX: in case of very hot / very dense we just use whatever the table says at
247  * the limit. should be OK. */
248  return rate;
249 }
double interp_eval(Interp *obj, double *x, double *ydata, int *status)
Definition: interp.c:72

References interp_eval(), and MetalCool.

Referenced by get_heatingcooling_rate().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ CoolingNoMetal

int CoolingNoMetal

Definition at line 177 of file cooling_uvfluc.c.

◆ enabled

int enabled

Definition at line 18 of file cooling_uvfluc.c.

◆ HydrogenNumberDensity_bins

double* HydrogenNumberDensity_bins

Definition at line 182 of file cooling_uvfluc.c.

◆ interp

Interp interp

◆ Lmet_table

double* Lmet_table

Definition at line 187 of file cooling_uvfluc.c.

◆ 

struct { ... } MetalCool

◆ NHydrogenNumberDensity_bins

int NHydrogenNumberDensity_bins

Definition at line 181 of file cooling_uvfluc.c.

◆ NRedshift_bins

int NRedshift_bins

Definition at line 178 of file cooling_uvfluc.c.

◆ Nside

ptrdiff_t Nside

Definition at line 21 of file cooling_uvfluc.c.

◆ NTemperature_bins

int NTemperature_bins

Definition at line 184 of file cooling_uvfluc.c.

◆ Redshift_bins

double* Redshift_bins

Definition at line 179 of file cooling_uvfluc.c.

◆ Table

double* Table

Definition at line 20 of file cooling_uvfluc.c.

◆ Temperature_bins

double* Temperature_bins

Definition at line 185 of file cooling_uvfluc.c.

◆ 

struct { ... } UVF

Referenced by get_local_UVBG().