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; }
/* there are two modes for supernova feedback corresponding to when the mass returning * by dying stars is returned to the cold gas - reheat and ejection; and when the mass * is returned to the hot gas - onle ejection.*/ void SN_feedback(int p, int centralgal, double stars, char feedback_location[]) { double CentralVvir, MergeCentralVvir=0., EjectVmax, EjectVvir, SN_Energy, Reheat_Energy, fac; double reheated_mass=0., ejected_mass=0.; /* SN FEEDBACK MODEL */ /* 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. */ if (strcmp(feedback_location,"HotGas")==0) reheated_mass = 0.; else if (strcmp(feedback_location,"ColdGas")==0) { 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(FeedbackReheatingModel == 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)); 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); } /*else if(FeedbackReheatingModel == 1) { reheated_mass = ALTERNATIVE Reheating LAW ; }*/ if(reheated_mass > Gal[p].ColdGas) reheated_mass = Gal[p].ColdGas; }// end if feedback_location /* Determine ejection (for FeedbackEjectionModel 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(FeedbackEjectionModel == 0) { ejected_mass = (FeedbackEjectionEfficiency* (EtaSNcode * EnergySNcode) * stars * min(1./FeedbackEjectionEfficiency, .5+1/pow(EjectVmax/EjectPreVelocity,EjectSlope)) - reheated_mass*EjectVvir*EjectVvir) /(EjectVvir*EjectVvir); } else if(FeedbackEjectionModel == 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 For Feedback */ /* update cold, hot, ejected gas fractions and respective metallicities * there are a number of changes introduced by Guo2010 concerning where * the gas ends up */ //ejected_mass = 0.01*Gal[centralgal].HotGas; if (reheated_mass + ejected_mass > 0.) update_from_feedback(p, centralgal, reheated_mass, ejected_mass); }