MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
Classes | Functions
cooling.h File Reference
#include "cosmology.h"
Include dependency graph for cooling.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  UVBG
 
struct  cooling_units
 

Functions

void init_cooling (const char *TreeCoolFile, const char *MetalCoolFile, char *reion_hist_file, struct cooling_units cu, Cosmology *CP)
 
void init_uvf_table (const char *UVFluctuationFile, const int UVFlucLen, const double BoxSize, const double UnitLength_in_cm)
 
double GetCoolingTime (double redshift, double u_old, double rho, struct UVBG *uvbg, double *ne_guess, double Z)
 
double DoCooling (double redshift, double u_old, double rho, double dt, struct UVBG *uvbg, double *ne_guess, double Z, double MinEgySpec, int isHeIIIionized)
 
struct UVBG get_global_UVBG (double redshift)
 
struct UVBG get_local_UVBG (double redshift, const struct UVBG *const GlobalUVBG, const double *const Pos, const double *const PosOffset)
 
double get_temp (double density, double ienergy, double helium, const struct UVBG *uvbg, double *ne_init)
 
double GetNeutralFraction (double u_old, double rho, const struct UVBG *uvbg, double ne)
 
double GetHeliumIonFraction (int ion, double u_old, double rho, const struct UVBG *uvbg, double ne_init)
 

Function Documentation

◆ DoCooling()

double DoCooling ( double  redshift,
double  u_old,
double  rho,
double  dt,
struct UVBG uvbg,
double *  ne_guess,
double  Z,
double  MinEgySpec,
int  isHeIIIionized 
)

Definition at line 71 of file cooling.c.

72 {
73  if(!coolunits.CoolingOn) return 0;
74 
75  double u, du;
76  double u_lower, u_upper;
77  double LambdaNet;
78  int iter = 0;
79 
80  rho *= coolunits.density_in_phys_cgs / PROTONMASS; /* convert to (physical) protons/cm^3 */
81  u_old *= coolunits.uu_in_cgs;
82  MinEgySpec *= coolunits.uu_in_cgs;
83  if(u_old < MinEgySpec)
84  u_old = MinEgySpec;
85  dt *= coolunits.tt_in_s;
86 
87  u = u_old;
88  u_lower = u;
89  u_upper = u;
90 
91  LambdaNet = get_lambdanet(rho, u, redshift, Z, uvbg, ne_guess, isHeIIIionized);
92 
93  /* bracketing */
94  if(u - u_old - LambdaNet * dt < 0) /* heating */
95  {
96  do
97  {
98  u_lower = u_upper;
99  u_upper *= 1.1;
100  } while(u_upper - u_old - get_lambdanet(rho, u_upper, redshift, Z, uvbg, ne_guess, isHeIIIionized) * dt < 0);
101  }
102  else
103  {
104  do {
105  u_upper = u_lower;
106  u_lower /= 1.1;
107  /* This means that we don't need an initial bracket*/
108  if(u_upper <= MinEgySpec) {
109  break;
110  }
111  } while(u_lower - u_old - get_lambdanet(rho, u_lower, redshift, Z, uvbg, ne_guess, isHeIIIionized) * dt > 0);
112  }
113 
114  do
115  {
116  u = 0.5 * (u_lower + u_upper);
117  /* If we know that the new energy
118  * is below the minimum gas internal energy, we are done here.*/
119  if(u_upper <= MinEgySpec) {
120  u = MinEgySpec;
121  break;
122  }
123 
124  LambdaNet = get_lambdanet(rho, u, redshift, Z, uvbg, ne_guess, isHeIIIionized);
125 
126  if(u - u_old - LambdaNet * dt > 0)
127  {
128  u_upper = u;
129  }
130  else
131  {
132  u_lower = u;
133  }
134 
135  du = u_upper - u_lower;
136 
137  iter++;
138 
139  if(iter >= (MAXITER - 10))
140  message(1, "u= %g\n", u);
141  }
142  while(fabs(du / u) > 1.0e-6 && iter < MAXITER);
143 
144  if(iter >= MAXITER)
145  {
146  endrun(10, "failed to converge in DoCooling()\n");
147  }
148 
149  u /= coolunits.uu_in_cgs; /*convert back to internal units */
150 
151  return u;
152 }
static double get_lambdanet(double rho, double u, double redshift, double Z, struct UVBG *uvbg, double *ne_guess, int isHeIIIionized)
Definition: cooling.c:57
#define MAXITER
Definition: cooling.c:46
static struct cooling_units coolunits
Definition: cooling.c:33
void message(int where, const char *fmt,...)
Definition: endrun.c:175
void endrun(int where, const char *fmt,...)
Definition: endrun.c:147
#define PROTONMASS
Definition: physconst.h:21
int CoolingOn
Definition: cooling.h:23
double density_in_phys_cgs
Definition: cooling.h:25
double tt_in_s
Definition: cooling.h:29
double uu_in_cgs
Definition: cooling.h:27

References cooling_units::CoolingOn, coolunits, cooling_units::density_in_phys_cgs, endrun(), get_lambdanet(), MAXITER, message(), PROTONMASS, cooling_units::tt_in_s, and cooling_units::uu_in_cgs.

Referenced by cooling_direct(), and test_DoCooling().

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

◆ get_global_UVBG()

struct UVBG get_global_UVBG ( double  redshift)

Definition at line 244 of file cooling_rates.c.

264 {
265  struct UVBG GlobalUVBG = {0};
266 
268  return GlobalUVBG;
269 
270  /* Set the homogeneous reionization redshift as the point when the UVB switches on.*/
271  GlobalUVBG.zreion = pow(10,Gamma_log1z[NTreeCool - 1])-1;
272 
275 
276  /* if a threshold is set, disable UV bg above that redshift */
278  return GlobalUVBG;
279 
280 
281  GlobalUVBG.gJH0 = get_photo_rate(redshift, &Gamma_HI);
282  GlobalUVBG.gJHe0 = get_photo_rate(redshift, &Gamma_HeI);
283  GlobalUVBG.gJHep = get_photo_rate(redshift, &Gamma_HeII);
284 
285  GlobalUVBG.epsH0 = get_photo_rate(redshift, &Eps_HI);
286  GlobalUVBG.epsHe0 = get_photo_rate(redshift, &Eps_HeI);
287  /* During helium reionization we have a model for the inhomogeneous non-equilibrium heating.
288  * To avoid double counting, remove the heating in the existing UVB*/
289  if(during_helium_reionization(redshift))
290  GlobalUVBG.epsHep = 0;
291  else
292  GlobalUVBG.epsHep = get_photo_rate(redshift, &Eps_HeII);
293  GlobalUVBG.self_shield_dens = self_shield_dens(redshift, &GlobalUVBG);
294  return GlobalUVBG;
295 }
int during_helium_reionization(double redshift)
static double self_shield_dens(double redshift, const struct UVBG *uvbg)
static double * Gamma_log1z
Definition: cooling_rates.c:88
static struct itp_type Eps_HI Eps_HeI Eps_HeII
Definition: cooling_rates.c:92
static double get_photo_rate(double redshift, struct itp_type *Gamma_tab)
static int NTreeCool
Definition: cooling_rates.c:86
static struct itp_type Gamma_HI Gamma_HeI Gamma_HeII
Definition: cooling_rates.c:90
static struct cooling_params CoolingParams
Definition: cooling_rates.c:68
Definition: cooling.h:8
double epsHep
Definition: cooling.h:13
double epsH0
Definition: cooling.h:12
double gJHep
Definition: cooling.h:10
double gJHe0
Definition: cooling.h:11
double gJH0
Definition: cooling.h:9
double self_shield_dens
Definition: cooling.h:15
double epsHe0
Definition: cooling.h:14
double zreion
Definition: cooling.h:16
double UVRedshiftThreshold
Definition: cooling_rates.h:47

References CoolingParams, cooling_params::fBar, UVBG::gJH0, GrayOpac, GrayOpac_ydata, GrayOpac_zz, and NGRAY.

Referenced by cooling_and_starformation(), get_helium_neutral_fraction_sfreff(), get_neutral_fraction_sfreff(), sfreff_on_eeqos(), test_DoCooling(), test_heatingcooling_rate(), test_rate_network(), and test_uvbg_loader().

Here is the caller graph for this function:

◆ 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

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:

◆ get_temp()

double get_temp ( double  density,
double  ienergy,
double  helium,
const struct UVBG uvbg,
double *  ne_init 
)

Definition at line 1172 of file cooling_rates.c.

1173 {
1174  double logt;
1175  double ne = get_equilib_ne(density, ienergy, helium, &logt, uvbg, *ne_init);
1176  double nh = density * (1 - helium);
1177  *ne_init = ne/nh;
1178  return get_temp_internal(ne/nh, ienergy, helium);
1179 }
double get_equilib_ne(double density, double ienergy, double helium, double *logt, const struct UVBG *uvbg, double ne_init)
static double get_temp_internal(double nebynh, double ienergy, double helium)
void density(const ActiveParticles *act, int update_hsml, int DoEgyDensity, int BlackHoleOn, double MinEgySpec, const DriftKickTimes times, Cosmology *CP, struct sph_pred_data *SPH_predicted, MyFloat *GradRho, const ForceTree *const tree)
Definition: density.c:203

References density(), get_equilib_ne(), and get_temp_internal().

Referenced by test_rate_network().

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

◆ GetCoolingTime()

double GetCoolingTime ( double  redshift,
double  u_old,
double  rho,
struct UVBG uvbg,
double *  ne_guess,
double  Z 
)

Definition at line 157 of file cooling.c.

158 {
159  if(!coolunits.CoolingOn) return 0;
160 
161  /* convert to physical cgs units */
163  u_old *= coolunits.uu_in_cgs;
164 
165  /* Note: this does not include the long mean free path heating from helium reionization*/
166  double LambdaNet = get_heatingcooling_rate(rho, u_old, 1 - HYDROGEN_MASSFRAC, redshift, Z, uvbg, ne_guess);
167 
168  if(LambdaNet >= 0) /* ups, we have actually heating due to UV background */
169  return 0;
170 
171  double coolingtime = u_old / (- LambdaNet);
172 
173  /*Convert back to internal units*/
174  coolingtime /= coolunits.tt_in_s;
175 
176  return coolingtime;
177 }
double get_heatingcooling_rate(double density, double ienergy, double helium, double redshift, double metallicity, const struct UVBG *uvbg, double *ne_equilib)
#define HYDROGEN_MASSFRAC
Definition: physconst.h:37

References cooling_units::CoolingOn, coolunits, cooling_units::density_in_phys_cgs, get_heatingcooling_rate(), HYDROGEN_MASSFRAC, PROTONMASS, cooling_units::tt_in_s, and cooling_units::uu_in_cgs.

Referenced by cooling_relaxed(), get_egyeff(), init_cooling_and_star_formation(), and test_DoCooling().

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

◆ GetHeliumIonFraction()

double GetHeliumIonFraction ( int  ion,
double  u_old,
double  rho,
const struct UVBG uvbg,
double  ne_init 
)

Definition at line 192 of file cooling.c.

193 {
194  /* convert to physical cgs units */
196  u_old *= coolunits.uu_in_cgs;
197  double helium_ion = get_helium_ion_phys_cgs(ion, rho, u_old, 1 - HYDROGEN_MASSFRAC, uvbg, ne_init);
198  return helium_ion;
199 }
double get_helium_ion_phys_cgs(int ion, double density, double ienergy, double helium, const struct UVBG *uvbg, double ne_init)

References coolunits, cooling_units::density_in_phys_cgs, get_helium_ion_phys_cgs(), HYDROGEN_MASSFRAC, PROTONMASS, and cooling_units::uu_in_cgs.

Referenced by get_helium_neutral_fraction_sfreff().

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

◆ GetNeutralFraction()

double GetNeutralFraction ( double  u_old,
double  rho,
const struct UVBG uvbg,
double  ne 
)

Definition at line 181 of file cooling.c.

182 {
183  /* convert to physical cgs units */
185  u_old *= coolunits.uu_in_cgs;
186  double nh0 = get_neutral_fraction_phys_cgs(rho, u_old, 1 - HYDROGEN_MASSFRAC, uvbg, &ne_init);
187  return nh0;
188 }
double get_neutral_fraction_phys_cgs(double density, double ienergy, double helium, const struct UVBG *uvbg, double *ne_init)

References coolunits, cooling_units::density_in_phys_cgs, get_neutral_fraction_phys_cgs(), HYDROGEN_MASSFRAC, PROTONMASS, and cooling_units::uu_in_cgs.

Referenced by get_neutral_fraction_sfreff().

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

◆ init_cooling()

void init_cooling ( const char *  TreeCoolFile,
const char *  MetalCoolFile,
char *  reion_hist_file,
struct cooling_units  cu,
Cosmology CP 
)

Definition at line 36 of file cooling.c.

37 {
38  coolunits = cu;
39  /*Initialize the cooling rates*/
41  init_cooling_rates(TreeCoolFile, MetalCoolFile, CP);
42  /* Initialize the helium reionization model*/
43  init_qso_lightup(reion_hist_file);
44 }
void init_qso_lightup(char *reion_hist_file)
void init_cooling_rates(const char *TreeCoolFile, const char *MetalCoolFile, Cosmology *CP)
static Cosmology * CP
Definition: power.c:27

References cooling_units::CoolingOn, coolunits, CP, init_cooling_rates(), and init_qso_lightup().

Referenced by init_cooling_and_star_formation(), and test_DoCooling().

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 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: