double collisional_starburst_recipe(double mass_ratio, int merger_centralgal, int centralgal, double time, double deltaT, int nstep) //ROB: New variable 'nstep' added, for use in update_yields() { /** @brief If StarBurstRecipe = 1 (since Croton2006), the Somerville 2001 * model of bursts is used. The burst can happen for both major * and minor mergers, with a fraction of the added cold gas from * the satellite and central being consumed. SN Feedback from * starformation is computed and the sizes of bulge and disk * followed (not done for the other burst mode).*/ double mstars, reheated_mass, ejected_mass, fac, metallicitySF; double CentralVvir, eburst, MergeCentralVvir, Ggas, EjectVmax, EjectVvir; double SN_Energy, Reheat_Energy; /* This is the major and minor merger starburst recipe of Somerville 2001. * The coefficients in eburst are taken from TJ Cox's PhD thesis and should * be more accurate then previous. */ Ggas=Gal[merger_centralgal].ColdGas; /* the bursting fraction given the mass ratio */ /* m_dot = 0.56*(m_sat/m_central)^0.7*m_gas */ eburst = SfrBurstEfficiency * pow(mass_ratio, SfrBurstSlope); //eburst = 0.56 * pow(mass_ratio, 0.7); mstars = eburst * Gal[merger_centralgal].ColdGas; if(mstars < 0.0) mstars = 0.0; /* this bursting results in SN feedback on the cold/hot gas * TODO this is the same code used in star_formation_and_feedback.c * and should be merged if possible. */ if(FeedbackRecipe == 0 || FeedbackRecipe == 1) { if (Gal[merger_centralgal].Type == 0) reheated_mass = FeedbackReheatingEpsilon * mstars*(.5+1./pow(Gal[merger_centralgal].Vmax/ReheatPreVelocity,ReheatSlope)); else reheated_mass = FeedbackReheatingEpsilon * mstars*(.5+1./pow(Gal[merger_centralgal].InfallVmax/ReheatPreVelocity,ReheatSlope)); } //Make sure that the energy used does not exceed the SN energy (central subhalo Vvir used) if(FeedbackRecipe == 0 || FeedbackRecipe == 1) { if (reheated_mass * Gal[merger_centralgal].Vvir * Gal[merger_centralgal].Vvir > mstars * EtaSNcode * EnergySNcode) reheated_mass = mstars * EtaSNcode * EnergySNcode / Gal[merger_centralgal].Vvir / Gal[merger_centralgal].Vvir; } /* cant use more cold gas than is available! so balance SF and feedback */ if((mstars + reheated_mass) > Gal[merger_centralgal].ColdGas) { fac = Gal[merger_centralgal].ColdGas / (mstars + reheated_mass); mstars *= fac; reheated_mass *= fac; } if (merger_centralgal == centralgal) { EjectVmax=Gal[centralgal].Vmax; EjectVvir=Gal[centralgal].Vvir;// main halo Vvir } else { EjectVmax=Gal[merger_centralgal].InfallVmax; EjectVvir=Gal[merger_centralgal].Vvir; //central subhalo Vvir } /* determine ejection*/ if(FeedbackRecipe == 0) { ejected_mass = (FeedbackEjectionEfficiency* (EtaSNcode * EnergySNcode) *mstars * min(1./FeedbackEjectionEfficiency,.5+1/pow(EjectVmax/EjectPreVelocity,EjectSlope)) - reheated_mass*EjectVvir*EjectVvir) /(EjectVvir*EjectVvir); } else if(FeedbackRecipe == 1) { SN_Energy = .5 * mstars * (EtaSNcode * EnergySNcode); Reheat_Energy = .5 * reheated_mass * EjectVvir * EjectVvir; ejected_mass = (SN_Energy - Reheat_Energy)/(0.5 * FeedbackEjectionEfficiency*(EtaSNcode * EnergySNcode)); if(FeedbackEjectionEfficiency*(EtaSNcode * EnergySNcode)<EjectVvir*EjectVvir) ejected_mass =0.0; } // Finished calculating mass exchanges, so just check that none are negative if (reheated_mass < 0.0) reheated_mass = 0.0; if (ejected_mass < 0.0) ejected_mass = 0.0; /* update the star formation rate */ #ifdef SAVE_MEMORY Gal[merger_centralgal].Sfr += mstars / deltaT; #else for(outputbin = 0; outputbin < NOUT; outputbin++) { if(Halo[halonr].SnapNum == ListOutputSnaps[outputbin]) { Gal[merger_centralgal].Sfr[outputbin] += mstars / deltaT; break; } } #endif /* Store the value of the metallicity of the cold phase when SF occurs. * Used to update luminosities below */ #ifdef METALS //metallicitySF = Gal[merger_centralgal].MetalsColdGas.type2/Gal[merger_centralgal].ColdGas; metallicitySF = metals_total(Gal[merger_centralgal].MetalsColdGas)/Gal[merger_centralgal].ColdGas; #else metallicitySF = Gal[merger_centralgal].MetalsColdGas/Gal[merger_centralgal].ColdGas; #endif mass_checks("collisional_starburst_recipe #1",merger_centralgal); if (mstars > 0.) update_from_star_formation(merger_centralgal, mstars, deltaT/STEPS, nstep); mass_checks("collisional_starburst_recipe #2",merger_centralgal); // Do not call if Gal[merger_centralgal].ColdGas < 1e-8? if (reheated_mass + ejected_mass > 0.) update_from_feedback(merger_centralgal, centralgal, reheated_mass, ejected_mass); #ifndef POST_PROCESS_MAGS /* update the luminosities due to the stars formed */ if (mstars > 0.0) add_to_luminosities(merger_centralgal, mstars, time, metallicitySF); #endif if (Ggas > 0.) return mstars/Ggas; else return 0.0; }
/** @brief Main recipe, calculates the fraction of cold gas turned into stars due * to star formation; the fraction of mass instantaneously recycled and * returned to the cold gas; the fraction of gas reheated from cold to hot, * ejected from hot to external and returned from ejected to hot due to * SN feedback. */ void starformation(int p, int centralgal, double time, double dt, int nstep) { /*! Variables: reff-Rdisk, tdyn=Rdisk/Vmax, strdot=Mstar_dot, stars=strdot*dt*/ double tdyn, strdot=0., stars, cold_crit, metallicitySF; if(Gal[p].Type == 0) { tdyn = Gal[p].GasDiskRadius / Gal[p].Vmax; cold_crit = SfrColdCrit * Gal[p].Vmax/200. * Gal[p].GasDiskRadius*100.; } else { tdyn = Gal[p].GasDiskRadius / Gal[p].InfallVmax; cold_crit = SfrColdCrit * Gal[p].InfallVmax/200. * Gal[p].GasDiskRadius*100.; } //standard star formation law (Croton2006, Delucia2007, Guo2010) if(StarFormationModel == 0) { if(Gal[p].ColdGas > cold_crit) strdot = SfrEfficiency * (Gal[p].ColdGas - cold_crit) / tdyn; else strdot = 0.0; } /*if(StarFormationModel == 1) { strdot = ALTERNATIVE STAR FORMATION LAW }*/ /* Note that Units of dynamical time are Mpc/Km/s - no conversion on dt needed */ stars = strdot * dt; if(stars < 0.0) terminate("***error stars<0.0***\n"); //otherwise cold gas and stars share material in update_stars_due_to_reheat #ifdef FEEDBACK_COUPLED_WITH_MASS_RETURN if(stars > Gal[p].ColdGas) stars = Gal[p].ColdGas; #endif mass_checks("recipe_starform #1",p); mass_checks("recipe_starform #1.1",centralgal); /* update for star formation * updates Mcold, StellarMass, MetalsMcold and MetalsStellarMass * in Guo2010 case updates the stellar spin -> hardwired, not an option */ /* Store the value of the metallicity of the cold phase when SF occurs */ if (Gal[p].ColdGas > 0.) metallicitySF= metals_total(Gal[p].MetalsColdGas)/Gal[p].ColdGas; else metallicitySF=0.; if (stars > 0.) update_stars_due_to_reheat(p, centralgal, &stars); mass_checks("recipe_starform #2",p); mass_checks("recipe_starform #2.1",centralgal); /* update the star formation rate */ /*Sfr=stars/(dt*steps)=strdot*dt/(dt*steps)=strdot/steps -> average over the STEPS*/ Gal[p].Sfr += stars / (dt * STEPS); // update_from_star_formation can only be called // after SD_feeedback recipe since stars need to be re_set once the reheated mass is known // (star formation and feedback share the same fraction of cold gas) if (stars > 0.) update_from_star_formation(p, stars, false, nstep); // false indicates not a burst update_massweightage(p, stars, time); #ifndef FEEDBACK_COUPLED_WITH_MASS_RETURN /* ifdef FEEDBACK_COUPLED_WITH_MASS_RETURN feedback is only called * when stars die, inside DETAILED_METALS_AND_MASS_RETURN */ if (stars > 0.) SN_feedback(p, centralgal, stars, "ColdGas"); #endif #ifdef COMPUTE_SPECPHOT_PROPERTIES #ifndef POST_PROCESS_MAGS /* Update the luminosities due to the stars formed */ if (stars > 0.0) add_to_luminosities(p, stars, time, dt, metallicitySF); #endif //NDEF POST_PROCESS_MAGS #endif //COMPUTE_SPECPHOT_PROPERTIES if(Gal[p].DiskMass > 0.0) check_disk_instability(p); if (DiskRadiusModel== 0) get_stellar_disk_radius(p); }
void do_AGN_heating(double dt, int ngal) { double AGNrate, AGNheating, AGNaccreted, AGNcoeff, fraction, EDDrate, FreeFallRadius; double dist, HotGas, HotRadius, Rvir, Vvir, Mvir; double LeftOverEnergy, CoolingGas, AGNAccretedFromCentral; int p, FoFCentralGal; if(AGNRadioModeModel == 0) { for (p = 0; p < ngal; p++) if(Gal[p].Type == 0) FoFCentralGal=p; } for (p = 0; p < ngal; p++) { Gal[p].CoolingRate_beforeAGN += Gal[p].CoolingGas / (dt*STEPS); AGNrate=0.; LeftOverEnergy = 0.; HotGas = Gal[p].HotGas; HotRadius = Gal[p].HotRadius; CoolingGas = Gal[p].CoolingGas; Mvir = Gal[p].Mvir; Rvir = Gal[p].Rvir; Vvir = Gal[p].Vvir; if(HotGas > 0.0) { if(AGNRadioModeModel == 0) AGNrate = AgnEfficiency * (UnitTime_in_s*SOLAR_MASS)/(UNITMASS_IN_G*SEC_PER_YEAR) * Gal[p].BlackHoleMass/Hubble_h * (HotGas/Hubble_h) * 10.; else if(AGNRadioModeModel == 2) { //empirical (standard) accretion recipe - Eq. 10 in Croton 2006 AGNrate = AgnEfficiency / (UNITMASS_IN_G / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS) * (Gal[p].BlackHoleMass / 0.01) * pow3(Vvir / 200.0) * ((HotGas / HotRadius * Rvir / Mvir) / 0.1); } else if(AGNRadioModeModel == 3 || AGNRadioModeModel == 4) { double x, lambda, temp, logZ, tot_metals; tot_metals = metals_total(Gal[p].MetalsHotGas); /* temp -> Temperature of the Gas in Kelvin, obtained from * hidrostatic equilibrium KT=0.5*mu_p*(Vc)^2 assuming Vvir~Vc */ temp = 35.9 * Vvir * Vvir; if(tot_metals > 0) logZ = log10(tot_metals / HotGas); else logZ = -10.0; lambda = get_metaldependent_cooling_rate(log10(temp), logZ); x = PROTONMASS * BOLTZMANN * temp / lambda; // now this has units sec g/cm^3 x /= (UnitDensity_in_cgs * UnitTime_in_s); // now in internal units /* Bondi-Hoyle accretion recipe -- efficiency = 0.15 * Eq. 29 in Croton 2006 */ if(AGNRadioModeModel == 3) AGNrate = (2.5 * M_PI * G) * (0.75 * 0.6 * x) * Gal[p].BlackHoleMass * 0.15; else if(AGNRadioModeModel == 4) { /* Cold cloud accretion recipe -- trigger: Rff = 50 Rdisk, * and accretion rate = 0.01% cooling rate * Eq. 25 in Croton 2006 */ FreeFallRadius = HotGas / (6.0 * 0.6 * x * Rvir * Vvir) / HotRadius * Rvir; if(Gal[p].BlackHoleMass > 0.0 && FreeFallRadius < Gal[p].GasDiskRadius * 50.0) AGNrate = 0.0001 * CoolingGas / dt; else AGNrate = 0.0; } } /* Eddington rate */ /* Note that this assumes an efficiency of 50% * - it ignores the e/(1-e) factor in L = e/(1-e) Mdot c^2 */ EDDrate = 1.3e48 * Gal[p].BlackHoleMass / (UnitEnergy_in_cgs / UnitTime_in_s) / 9e10; /* accretion onto BH is always limited by the Eddington rate */ if(AGNrate > EDDrate) AGNrate = EDDrate; /* accreted mass onto black hole the value of dt puts an h factor into AGNaccreted as required for code units */ AGNaccreted = AGNrate * dt; /* cannot accrete more mass than is available! */ if(AGNaccreted > HotGas) AGNaccreted = HotGas; /* coefficient to heat the cooling gas back to the virial temperature of the halo */ /* 1.34e5 = sqrt(2*eta*c^2), eta=0.1 (standard efficiency) and c in km/s * Eqs. 11 & 12 in Croton 2006 */ AGNcoeff = (1.34e5 / Vvir) * (1.34e5 / Vvir); /* cooling mass that can be suppressed from AGN heating */ AGNheating = AGNcoeff * AGNaccreted; if(AGNRadioModeModel == 0 && Gal[p].Type==1) { if(dist < Gal[FoFCentralGal].Rvir) { if(AGNheating > (Gal[p].CoolingGas + Gal[FoFCentralGal].CoolingGas)) { AGNheating = (Gal[p].CoolingGas + Gal[FoFCentralGal].CoolingGas); AGNaccreted = (Gal[p].CoolingGas + Gal[FoFCentralGal].CoolingGas) / AGNcoeff; } if(AGNheating > Gal[p].CoolingGas) LeftOverEnergy = AGNheating - Gal[p].CoolingGas; } } else if(AGNheating > Gal[p].CoolingGas) AGNaccreted = Gal[p].CoolingGas / AGNcoeff; /* limit heating to cooling rate */ if(AGNheating > Gal[p].CoolingGas) AGNheating = Gal[p].CoolingGas; /* accreted mass onto black hole */ Gal[p].BlackHoleMass += AGNaccreted; //ROB: transfer_mass functions should be used here Gal[p].RadioAccretionRate += AGNaccreted / (dt*STEPS); fraction=AGNaccreted/Gal[p].HotGas; Gal[p].HotGas -= AGNaccreted; Gal[p].MetalsHotGas = metals_add(Gal[p].MetalsHotGas,Gal[p].MetalsHotGas, -fraction); #ifdef INDIVIDUAL_ELEMENTS Gal[p].HotGas_elements = elements_add(Gal[p].HotGas_elements,Gal[p].HotGas_elements,-fraction); #endif #ifdef METALS_SELF Gal[p].MetalsHotGasSelf = metals_add(Gal[p].MetalsHotGasSelf,Gal[p].MetalsHotGasSelf,-fraction); #endif } else AGNheating = 0.0; Gal[p].CoolingGas -= AGNheating; if(Gal[p].CoolingGas < 0.0) Gal[p].CoolingGas = 0.0; Gal[p].CoolingRate += Gal[p].CoolingGas / (dt*STEPS); if(AGNRadioModeModel == 0 && LeftOverEnergy>0.) { Gal[FoFCentralGal].CoolingGas -= LeftOverEnergy; if(Gal[FoFCentralGal].CoolingGas < 0.0) Gal[FoFCentralGal].CoolingGas = 0.0; else Gal[FoFCentralGal].CoolingRate -= LeftOverEnergy / (dt*STEPS); } mass_checks("cooling_recipe #2.",p); } }
void compute_cooling(int p, double dt, int ngal) { double Vvir, Rvir, x, lambda, tcool, rcool, temp, tot_hotMass, tot_metals, HotRadius; double coolingGas, logZ, rho_rcool, rho0; mass_checks("cooling_recipe #1",p); tot_hotMass = Gal[p].HotGas; tot_metals = metals_total(Gal[p].MetalsHotGas); if(tot_hotMass > 1.0e-6) { Vvir = Gal[p].Vvir; Rvir = Gal[p].Rvir; tcool = Rvir / Vvir; // tcool = t_dynamical = Rvir/Vvir /* temp -> Temperature of the Gas in Kelvin, obtained from * hidrostatic equilibrium KT=0.5*mu_p*(Vc)^2 assuming Vvir~Vc */ temp = 35.9 * Vvir * Vvir; if (Gal[p].Type == 0) HotRadius = Gal[p].Rvir; else HotRadius = Gal[p].HotRadius; if(tot_metals > 0) logZ = log10(tot_metals / tot_hotMass); else logZ = -10.0; //eq. 3 and 4 Guo2010 lambda = get_metaldependent_cooling_rate(log10(temp), logZ); x = PROTONMASS * BOLTZMANN * temp / lambda; // now this has units sec g/cm^3 x /= (UnitDensity_in_cgs * UnitTime_in_s); // now in internal units rho_rcool = x / (0.28086 * tcool); /* an isothermal density profile for the hot gas is assumed here */ rho0 = tot_hotMass / (4 * M_PI * HotRadius); rcool = sqrt(rho0 / rho_rcool); if (Gal[p].CoolingRadius < rcool) Gal[p].CoolingRadius = rcool; //if Hotradius is used, when galaxies become type 1's there will be a discontinuity in the cooling if(rcool > Rvir) // INFALL DOMINATED REGIME //coolingGas = tot_hotMass; - Delucia 2007 /*comes in to keep the continuity (Delucia2004) */ coolingGas = tot_hotMass / (HotRadius / Vvir) * dt; else // HOT PHASE REGIME /*coolingGas = (tot_hotMass / Rvir) * (rcool / tcool) * dt */ coolingGas = (tot_hotMass / HotRadius) * (rcool / tcool) * dt ; //Photoionizing background if (log10(temp) < 4.0) coolingGas = 0.; if(coolingGas > tot_hotMass) coolingGas = tot_hotMass; else if(coolingGas < 0.0) coolingGas = 0.0; } else { coolingGas = 0.0; } Gal[p].CoolingGas = coolingGas; mass_checks("cooling_recipe #1.5",p); }
/** @brief Main recipe, calculates the fraction of cold gas turned into stars due * to star formation; the fraction of mass instantaneously recycled and * returned to the cold gas; the fraction of gas reheated from cold to hot, * ejected from hot to external and returned from ejected to hot due to * SN feedback. */ void starformation_and_feedback(int p, int centralgal, double time, double dt, int nstep) { /*! Variables: reff-Rdisk, tdyn=Rdisk/Vmax, strdot=Mstar_dot, stars=strdot*dt*/ double tdyn, strdot, stars, reheated_mass, ejected_mass, fac, cold_crit, metallicitySF, CentralVvir, MergeCentralVvir, EjectVmax, EjectVvir, SN_Energy, Reheat_Energy; //standard star formation law (Croton2006, Delucia2007, Guo2010) if(StarFormationRecipe == 0) { if(Gal[p].Type == 0) tdyn = Gal[p].GasDiskRadius / Gal[p].Vmax; else tdyn = Gal[p].GasDiskRadius / Gal[p].InfallVmax; if(Gal[p].Type == 0) cold_crit = 0.19 * Gal[p].Vmax * Gal[p].GasDiskRadius; else cold_crit = 0.19 * Gal[p].InfallVmax * Gal[p].GasDiskRadius; if(Gal[p].ColdGas > cold_crit) strdot = SfrEfficiency * (Gal[p].ColdGas - cold_crit) / tdyn * pow(Gal[p].Vvir / SfrLawPivotVelocity, SfrLawSlope); else strdot = 0.0; } //No dependce on Tdyn if(StarFormationRecipe == 1) { if(Gal[p].ColdGas > 1.e-7) strdot = SfrEfficiency * (Gal[p].ColdGas) / (2.e-5) * pow(Gal[p].Vvir / SfrLawPivotVelocity, SfrLawSlope); else strdot = 0.0; } #ifdef H2FORMATION /* use H2 formation model from Krumholz */ Not yet implemented H2Mass=cal_H2(p); strdot = SfrEfficiency * H2Mass / tdyn; #endif /*TODO - Note that Units of dynamical time are Mpc/Km/s - no conversion on dt needed * be mentioned 3.06e19 to 3.15e19 */ stars = strdot * dt; if(stars < 0.0) terminate("***error stars<0.0***\n"); /* SN FEEDBACK RECIPES */ /* In Guo2010 type 1s can eject, reincorporate gas and get gas from their * own satellites (is not sent to the type 0 galaxy as in Delucia2007), * for gas flow computations: * If satellite is inside Rvir of main halo, Vvir of main halo used * If it is outside, the Vvir of its central subhalo is used. */ CentralVvir = Gal[centralgal].Vvir; // main halo Vvir MergeCentralVvir = Gal[Gal[p].CentralGal].Vvir; //central subhalo Vvir mass_checks("recipe_starform #0",p); mass_checks("recipe_starform #0.1",centralgal); /* Feedback depends on the circular velocity of the host halo * Guo2010 - eq 18 & 19*/ if(FeedbackRecipe == 0) { if (Gal[Gal[p].CentralGal].Type == 0) reheated_mass = FeedbackReheatingEpsilon * stars* (.5+1./pow(Gal[Gal[p].CentralGal].Vmax/ReheatPreVelocity,ReheatSlope)); else reheated_mass = FeedbackReheatingEpsilon * stars* (.5+1./pow(Gal[Gal[p].CentralGal].InfallVmax/ReheatPreVelocity,ReheatSlope)); } //Make sure that the energy used in reheat does not exceed the SN energy (central subhalo Vvir used) if (FeedbackRecipe == 0 || FeedbackRecipe == 1) { if (reheated_mass * Gal[Gal[p].CentralGal].Vvir * Gal[Gal[p].CentralGal].Vvir > stars * (EtaSNcode * EnergySNcode)) reheated_mass = stars * (EtaSNcode * EnergySNcode) / (Gal[Gal[p].CentralGal].Vvir * Gal[Gal[p].CentralGal].Vvir); } /* cant use more cold gas than is available! so balance SF and feedback */ if((stars + reheated_mass) > Gal[p].ColdGas) { fac = Gal[p].ColdGas / (stars + reheated_mass); stars *= fac; reheated_mass *= fac; } /* Determine ejection (for FeedbackRecipe 2 we have the dependence on Vmax) * Guo2010 - eq 22 * Note that satellites can now retain gas and have their own gas cycle*/ if (Gal[Gal[p].CentralGal].Type == 0) { EjectVmax=Gal[centralgal].Vmax; EjectVvir=Gal[centralgal].Vvir;// main halo Vvir } else { EjectVmax=Gal[Gal[p].CentralGal].InfallVmax; EjectVvir=Gal[Gal[p].CentralGal].Vvir; //central subhalo Vvir } if(FeedbackRecipe == 0) { ejected_mass = (FeedbackEjectionEfficiency* (EtaSNcode * EnergySNcode) * stars * min(1./FeedbackEjectionEfficiency, .5+1/pow(EjectVmax/EjectPreVelocity,EjectSlope)) - reheated_mass*EjectVvir*EjectVvir) /(EjectVvir*EjectVvir); } else if(FeedbackRecipe == 1)//the ejected material is assumed to have V_SN { SN_Energy = .5 * stars * (EtaSNcode * EnergySNcode); Reheat_Energy = .5 * reheated_mass * EjectVvir * EjectVvir; ejected_mass = (SN_Energy - Reheat_Energy)/(0.5 * FeedbackEjectionEfficiency*(EtaSNcode * EnergySNcode)); //if VSN^2<Vvir^2 nothing is ejected if(FeedbackEjectionEfficiency*(EtaSNcode * EnergySNcode)<EjectVvir*EjectVvir) ejected_mass =0.0; } // Finished calculating mass exchanges, so just check that none are negative if (reheated_mass < 0.0) reheated_mass = 0.0; if (ejected_mass < 0.0) ejected_mass = 0.0; /* update the star formation rate */ #ifdef SAVE_MEMORY /*Sfr=stars/(dt*steps)=strdot*dt/(dt*steps)=strdot/steps -> average over the STEPS*/ Gal[p].Sfr += stars / (dt * STEPS); #else for(outputbin = 0; outputbin < NOUT; outputbin++) { if(Halo[halonr].SnapNum == ListOutputSnaps[outputbin]) { Gal[p].Sfr[outputbin] += stars / (dt * STEPS); break; } } #endif mass_checks("recipe_starform #1",p); mass_checks("recipe_starform #1.1",centralgal); /* update for star formation * updates Mcold, StellarMass, MetalsMcold and MetalsStellarMass * in Guo2010 case updates the stellar spin -> hardwired, not an option */ /* Store the value of the metallicity of the cold phase when SF occurs */ if (Gal[p].ColdGas > 0.) #ifdef METALS //metallicitySF=Gal[p].MetalsColdGas.type2/Gal[p].ColdGas; metallicitySF= metals_total(Gal[p].MetalsColdGas)/Gal[p].ColdGas; #else metallicitySF=Gal[p].MetalsColdGas/Gal[p].ColdGas; #endif else