113 static void cooling_direct(
int i,
const double redshift,
const double a3inv,
const double hubble,
const struct UVBG *
const GlobalUVBG);
115 static void cooling_relaxed(
int i,
double dtime,
struct UVBG * local_uvbg,
const double redshift,
const double a3inv,
struct sfr_eeqos_data sfr_data,
const struct UVBG *
const GlobalUVBG);
118 static int starformation(
int i,
double *localsfr,
MyFloat * sm_out,
MyFloat * GradRho,
const double redshift,
const double a3inv,
const double hubble,
const double GravInternal,
const struct UVBG *
const GlobalUVBG);
123 static double get_egyeff(
double redshift,
double dens,
struct UVBG * uvbg);
124 static double find_star_mass(
int i,
const double avg_baryon_mass);
132 MPI_Comm_rank(MPI_COMM_WORLD, &
ThisTask);
169 const int nthreads = omp_get_max_threads();
171 int * NewStars = NULL;
172 int * NewParents = NULL;
173 int64_t NumNewStar = 0, NumMaybeWind = 0;
174 int * MaybeWind = NULL;
177 size_t *nqthrsfr =
ta_malloc(
"nqthrsfr",
size_t, nthreads);
178 int **thrqueuesfr =
ta_malloc(
"thrqueuesfr",
int *, nthreads);
179 int **thrqueueparent =
ta_malloc(
"thrqueueparent",
int *, nthreads);
180 size_t *nqthrwind = NULL;
181 int **thrqueuewind = NULL;
186 const double a3inv = 1./(Time * Time * Time);
190 NewStars = (
int *)
mymalloc(
"NewStars", nactive *
sizeof(
int) * nthreads);
192 NewParents = (
int *)
mymalloc2(
"NewParents", nactive *
sizeof(
int) * nthreads);
197 nqthrwind =
ta_malloc(
"nqthrwind",
size_t, nthreads);
198 thrqueuewind =
ta_malloc(
"thrqueuewind",
int *, nthreads);
200 MaybeWind = (
int *)
mymalloc(
"MaybeWind", nactive *
sizeof(
int) * nthreads);
206 const double redshift = 1./Time - 1;
208 double sum_sm = 0, sum_mass_stars = 0, localsfr = 0;
213 #pragma omp parallel reduction(+:localsfr) reduction(+: sum_sm) reduction(+:sum_mass_stars)
216 const int tid = omp_get_thread_num();
217 #pragma omp for schedule(static)
218 for(i=0; i < nactive; i++)
223 if(
P[p_i].Type != 0 ||
P[p_i].IsGarbage ||
P[p_i].Mass <= 0)
226 int shall_we_star_form = 0;
237 if(shall_we_star_form) {
243 sum_sm +=
P[p_i].Mass;
247 sum_sm +=
P[p_i].Mass * (1 - exp(-sm/
P[p_i].Mass));
251 thrqueuesfr[tid][nqthrsfr[tid]] = newstar;
252 thrqueueparent[tid][nqthrsfr[tid]] = p_i;
257 if(nqthrwind && newstar < 0) {
258 thrqueuewind[tid][nqthrwind[tid]] = p_i;
259 StellarMass[
P[p_i].PI] = sm;
275 winds_subgrid(MaybeWind, NumMaybeWind, Time, hubble, tree, StellarMass);
286 if(NumNewStar != NumNewParent)
287 endrun(3,
"%lu new stars, but %lu new parents!\n",NumNewStar, NumNewParent);
289 NewStars = (
int *)
myrealloc(NewStars,
sizeof(
int) * NumNewStar);
307 NewParents = (
int *)
myrealloc(NewParents,
sizeof(
int) * NumNewStar);
312 int stars_converted=0, stars_spawned=0;
316 #pragma omp parallel for schedule(static) reduction(+:stars_converted) reduction(+:stars_spawned) reduction(+:sum_mass_stars)
317 for(i=0; i < NumNewStar; i++)
319 int child = NewStars[i];
320 int parent = NewParents[i];
322 sum_mass_stars +=
P[child].Mass;
332 int64_t tot_spawned=0, tot_converted=0;
336 double total_sum_mass_stars, total_sm, totsfrrate;
338 MPI_Reduce(&localsfr, &totsfrrate, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
339 MPI_Reduce(&sum_sm, &total_sm, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
340 MPI_Reduce(&sum_mass_stars, &total_sum_mass_stars, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
346 rate = total_sm / (
dloga / hubble);
358 fprintf(FdSfr,
"%g %g %g %g %g\n", Time, total_sm, totsfrrate, rate_in_msunperyear,
359 total_sum_mass_stars);
364 if(tot_spawned || tot_converted)
365 message(0,
"SFR: spawned %ld stars, converted %ld gas particles into stars\n", tot_spawned, tot_converted);
388 int * new_star_tmp = NULL;
390 new_star_tmp = (
int *)
mymalloc2(
"newstartmp", NumNewStar*
sizeof(
int));
391 memmove(new_star_tmp, NewStars, NumNewStar *
sizeof(
int));
395 struct NODE * nodes_base_tmp=NULL;
396 int *Father_tmp=NULL;
397 int *ActiveParticle_tmp=NULL;
414 for(i = 0; i < 6; i++)
416 atleast[4] += NumNewStar;
420 if(ActiveParticle_tmp) {
423 myfree(ActiveParticle_tmp);
436 NewStars = (
int *)
mymalloc(
"NewStars", NumNewStar*
sizeof(
int));
437 memmove(NewStars, new_star_tmp, NumNewStar *
sizeof(
int));
444 cooling_direct(
int i,
const double redshift,
const double a3inv,
const double hubble,
const struct UVBG *
const GlobalUVBG)
448 double dtime =
dloga / hubble;
450 double ne =
SPHP(i).Ne;
455 double uold =
SPHP(i).Entropy * enttou;
459 double lastred = 1/lasttime - 1;
472 unew =
DoCooling(redshift, uold,
SPHP(i).Density * a3inv, dtime, &uvbg, &ne,
SPHP(i).Metallicity, MinEgySpec,
P[i].HeIIIionized);
477 SPHP(i).Entropy = unew / enttou;
507 double redshift = pow(a3inv, 1./3.)-1;
511 double unew = sph->
Entropy * enttou;
513 if(unew >= egyeff * 3.2)
523 const double a3inv = pow(1+redshift,3);
526 double physdens = sphdata->
Density * a3inv;
530 double eomdensity = sphdata->
Density;
539 double dtime =
dloga / hubble;
550 const double a3inv = pow(1+redshift,3);
554 double physdens = sphdata->
Density * a3inv;
558 double eomdensity = sphdata->
Density;
567 double dtime =
dloga / hubble;
581 if(
P[parent].Type != 0)
582 endrun(7772,
"Only gas forms stars, what's wrong?\n");
592 STARP(child).FormationTime = Time;
593 STARP(child).LastEnrichmentMyr = 0;
594 STARP(child).TotalMassReturned = 0;
611 double egycurrent =
SPHP(i).Entropy * densityfac;
612 double trelax = sfr_data.
trelax;
615 if(egycurrent > egyeff)
617 double ne =
SPHP(i).Ne;
628 if(tcool < trelax && tcool > 0)
634 SPHP(i).Entropy = (egyeff + (egycurrent - egyeff) * exp(-dtime / trelax)) /densityfac;
647 double unew =
SPHP(i).Entropy * enttou;
666 starformation(
int i,
double *localsfr,
MyFloat * sm_out,
MyFloat * GradRho,
const double redshift,
const double a3inv,
const double hubble,
const double GravInternal,
const struct UVBG *
const GlobalUVBG)
670 double dtime =
dloga / hubble;
677 double atime = 1/(1+redshift);
680 double sm = smr * dtime;
683 double p = sm /
P[i].Mass;
688 *localsfr +=
SPHP(i).Sfr;
691 const double frac = (1 - exp(-p));
695 if(
dloga > 0 &&
P[i].TimeBin)
696 cooling_relaxed(i, dtime, &uvbg, redshift, a3inv, sfr_data, GlobalUVBG);
699 double prob =
P[i].Mass / mass_of_star * (1 - exp(-p));
707 if(
P[i].Mass >= 1.1 * mass_of_star)
714 if(!form_star || newstar != i) {
742 if(data.tsfr < dtime && dtime > 0)
753 data.cloudfrac = 1 + 1 / (2 * y) - sqrt(1 / y + 1 / (4 * y * y));
755 data.trelax = data.tsfr * (1 - data.cloudfrac) / data.cloudfrac / (
sfr_params.
FactorSN * (1 + factorEVP));
765 double cloudmass = sfr_data.
cloudfrac *
P[i].Mass;
771 endrun(1,
"GradRho not allocated but has SFR_CRITERION_MOLECULAR_H2. Should never happen!\n");
792 double x = 1 + 1 / (2 * y) - sqrt(1 / y + 1 / (4 * y * y));
860 struct UVBG uvbg = {0};
866 const double tcool =
GetCoolingTime(0, egyhot, dens, &uvbg, &ne, 0.0);
868 const double coolrate = egyhot / tcool / dens;
881 message(0,
"EXPECTED FRACTION OF COLD GAS AT THRESHOLD = %g\n", x);
882 message(0,
"tcool=%g dens=%g egyhot=%g\n", tcool, dens, egyhot);
893 const double fac = 1 / (log(dens * 1.025) - log(dens));
894 neff = -log(peff) * fac;
900 neff += log(peff) * fac;
902 while(neff > 4.0 / 3);
904 message(0,
"Run-away sets in for dens=%g\n", dens);
907 const double sigma = 10.0 /
CP->
Hubble * 1.0e-10 / pow(1.0e-3, 2);
909 message(0,
"Isotherm sheet central density: %g z0=%g\n",
928 if(mass_of_star >
P[i].Mass) {
930 mass_of_star =
P[i].Mass;
938 mass_of_star =
P[i].Mass;
967 ev_NH = rho*rho/gradrho_mag;
978 const double a2 = atime * atime;
980 double gradrho_mag = sqrt(GradRho[3*
P[i].PI]*GradRho[3*
P[i].PI]+GradRho[3*
P[i].PI+1]*GradRho[3*
P[i].PI+1]+GradRho[3*
P[i].PI+2]*GradRho[3*
P[i].PI+2]);
983 tau_fmol *= (0.1 + zoverzsun);
986 double y = 0.756*(1+3.1*pow(zoverzsun,0.365));
987 y = log(1+0.6*y+0.01*y*y)/(0.6*tau_fmol);
988 y = 1-0.75*y/(1+0.25*y);
998 const double a2 = atime * atime;
999 double divv =
SPHP(i).DivVel / a2;
1001 divv += 3.0*hubble * a2;
1004 if( divv>=0 )
return 0;
1007 double dv2abs = (divv*divv
1008 + (
SPHP(i).CurlVel/a2)
1009 * (
SPHP(i).CurlVel/a2)
1011 double alpha_vir = 0.2387 * dv2abs/(GravInternal *
SPHP(i).Density * a3inv);
1015 if((alpha_vir < 1.0)
1027 y *= 1.0/(1.0 + alpha_vir);
void init_cooling(const char *TreeCoolFile, const char *MetalCoolFile, char *reion_hist_file, struct cooling_units cu, Cosmology *CP)
double GetCoolingTime(double redshift, double u_old, double rho, struct UVBG *uvbg, double *ne_guess, double Z)
static struct cooling_units coolunits
double DoCooling(double redshift, double u_old, double rho, double dt, struct UVBG *uvbg, double *ne_guess, double Z, double MinEgySpec, int isHeIIIionized)
double GetHeliumIonFraction(int ion, double u_old, double rho, const struct UVBG *uvbg, double ne_init)
double GetNeutralFraction(double u_old, double rho, const struct UVBG *uvbg, double ne_init)
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)
struct UVBG get_global_UVBG(double redshift)
double hubble_function(const Cosmology *CP, double a)
void message(int where, const char *fmt,...)
void endrun(int where, const char *fmt,...)
int force_tree_allocated(const ForceTree *tree)
#define mymalloc(name, size)
#define ta_malloc(name, type, nele)
#define myrealloc(ptr, size)
#define mymalloc2(name, size)
#define report_memory_usage(x)
double param_get_double(ParameterSet *ps, const char *name)
void param_get_string2(ParameterSet *ps, const char *name, char *dst, size_t len)
int param_get_int(ParameterSet *ps, const char *name)
int param_get_enum(ParameterSet *ps, const char *name)
struct part_manager_type PartManager[1]
#define HYDROGEN_MASSFRAC
static double get_egyeff(double redshift, double dens, struct UVBG *uvbg)
void init_cooling_and_star_formation(int CoolingOn, int StarformationOn, Cosmology *CP, const double avg_baryon_mass, const double BoxSize, const struct UnitSystem units)
double get_helium_neutral_fraction_sfreff(int ion, double redshift, double hubble, struct particle_data *partdata, struct sph_particle_data *sphdata)
static struct SFRParams sfr_params
static int starformation(int i, double *localsfr, MyFloat *sm_out, MyFloat *GradRho, const double redshift, const double a3inv, const double hubble, const double GravInternal, const struct UVBG *const GlobalUVBG)
int sfreff_on_eeqos(const struct sph_particle_data *sph, const double a3inv)
static struct sfr_eeqos_data get_sfr_eeqos(struct particle_data *part, struct sph_particle_data *sph, double dtime, struct UVBG *local_uvbg, const double redshift, const double a3inv)
double get_neutral_fraction_sfreff(double redshift, double hubble, struct particle_data *partdata, struct sph_particle_data *sphdata)
int get_generations(void)
static int make_particle_star(int child, int parent, int placement, double Time)
static double get_starformation_rate_full(int i, MyFloat *GradRho, struct sfr_eeqos_data sfr_data, const double atime, const double a3inv, const double hubble, const double GravInternal)
static void cooling_relaxed(int i, double dtime, struct UVBG *local_uvbg, const double redshift, const double a3inv, struct sfr_eeqos_data sfr_data, const struct UVBG *const GlobalUVBG)
static double get_sfr_factor_due_to_selfgravity(int i, const double atime, const double a3inv, const double hubble, const double GravInternal)
double get_MinEgySpec(void)
void cooling_and_starformation(ActiveParticles *act, double Time, double dloga, ForceTree *tree, const Cosmology *CP, MyFloat *GradRho, FILE *FdSfr)
static double ev_NH_from_GradRho(MyFloat gradrho_mag, double hsml, double rho, double include_h)
static int * sfr_reserve_slots(ActiveParticles *act, int *NewStars, int NumNewStar, ForceTree *tt)
static double find_star_mass(int i, const double avg_baryon_mass)
static void cooling_direct(int i, const double redshift, const double a3inv, const double hubble, const struct UVBG *const GlobalUVBG)
static int quicklyastarformation(int i, const double a3inv)
int sfr_need_to_compute_sph_grad_rho(void)
void set_sfr_params(ParameterSet *ps)
static double get_sfr_factor_due_to_h2(int i, MyFloat *GradRho, const double atime)
@ SFR_CRITERION_MOLECULAR_H2
@ SFR_CRITERION_CONVERGENT_FLOW
@ SFR_CRITERION_CONTINUOUS_CUTOFF
@ SFR_CRITERION_SELFGRAVITY
size_t slots_reserve(int where, int64_t atleast[6], struct slots_manager_type *sman)
struct slots_manager_type SlotsManager[1]
int slots_convert(int parent, int ptype, int placement, struct part_manager_type *pman, struct slots_manager_type *sman)
int slots_split_particle(int parent, double childmass, struct part_manager_type *pman)
int64_t NumActiveParticle
double UnitSfr_in_solar_per_year
char UVFluctuationFile[100]
double QuickLymanAlphaTempThresh
enum StarformationCriterion StarformationCriterion
double QuickLymanAlphaProbability
double UnitInternalEnergy_in_cgs
double UnitDensity_in_cgs
double density_in_phys_cgs
double CurrentParticleOffset[3]
void gadget_setup_thread_arrays(int *dest, int *srcs[], size_t sizes[], size_t total_size, int narrays)
double get_random_number(uint64_t id)
void sumup_large_ints(int n, int *src, int64_t *res)
size_t gadget_compact_thread_arrays(int *dest, int *srcs[], size_t sizes[], int narrays)
#define MPIU_Barrier(comm)
static const double tt[NEXACT]
double loga_from_ti(int ti)
double get_dloga_for_bin(int timebin, const inttime_t Ti_Current)
static inttime_t dti_from_timebin(int bin)
#define walltime_measure(name)
void winds_evolve(int i, double a3inv, double hubble)
void winds_subgrid(int *MaybeWind, int NumMaybeWind, const double Time, const double hubble, ForceTree *tree, MyFloat *StellarMasses)
int winds_are_subgrid(void)
void winds_and_feedback(int *NewStars, int NumNewStars, const double Time, const double hubble, ForceTree *tree)
void init_winds(double FactorSN, double EgySpecSN, double PhysDensThresh, double UnitTime_in_s)