Esempio n. 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;

}
/** @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);

}