예제 #1
0
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);
}