コード例 #1
0
double infall_recipe(int centralgal, int ngal, double Zcurr)
{
  int i;
  double tot_mass, reionization_modifier, infallingMass;
  double dis;

  /*  need to add up all the baryonic mass asociated with the full halo to check
   *  what baryonic fraction is missing/in excess. That will give the mass of gas
   *  that need to be added/subtracted to the hot phase, gas that infalled.*/
  tot_mass = 0.0;

  for(i = 0; i < ngal; i++) {    /* Loop over all galaxies in the FoF-halo */

    /* dis is the separation of the galaxy which i orbits from the type 0 */
    dis=separation_gal(centralgal,Gal[i].CentralGal)/(1+ZZ[Halo[Gal[centralgal].HaloNr].SnapNum]);

    /* If galaxy is orbiting a galaxy inside Rvir of the type 0 it will contribute
     * to the baryon sum */
    if ( dis < Gal[centralgal].Rvir ) {
      tot_mass += Gal[i].DiskMass + Gal[i].BulgeMass + Gal[i].ICM + Gal[i].BlackHoleMass;
      tot_mass += Gal[i].ColdGas + Gal[i].HotGas + Gal[i].EjectedMass;
    }
  }

  /* The logic here seems to be that the infalling mass is supposed to be
   * newly-accreted diffuse gas.  So we take the total mass and subtract all
   * the components that we already know about.  In principle, this could lead
   * to negative infall. */
  /* The reionization modifier is applied to the whole baryon mass, not just the 
   * diffuse component.  It is not obvious that this is the correct thing to do. */
  /* The baryonic fraction is conserved by adding/subtracting the infallingMass
   * calculated here to/from the hot gas of the central galaxy of the FOF
   * This is done in main.c where the infall recipe is called.
   * If ReionizationModel<2, the impact of reonization on the fraction of infalling
   * gas is computed, this is done using the Gnedin formalism with a choice
   * of fitting parameters to the formulas proposed by these authors.
   * There are two options. In both cases reionization has the effect of reducing 
   * the fraction of baryons that collapse into dark matter halos, reducing the
   * amount of infalling gas. */
  if(ReionizationModel == 2)
    reionization_modifier = 1.0;
  else
    reionization_modifier = do_reionization(Gal[centralgal].Mvir, Zcurr);

  infallingMass = reionization_modifier * BaryonFrac * Gal[centralgal].Mvir - tot_mass;

  return infallingMass;
  
}
コード例 #2
0
double infall_recipe(int centralgal, int ngal, double Zcurr)
{
  int i;
  double halomass;
  double tot_mass, reionization_modifier, infallingMass;
  double infall1,infall2;
  double dis;
  int cell;
  double mu,m_p;
  float m1  = 0.01*Hubble_h;
  float m2 = 0.1*Hubble_h;
  mu = 0.59;
  m_p = 1.67262178e-24; // grams
  // printf("calculate infall ReionizationOn = %d\n",ReionizationOn);
  /*  need to add up all the baryonic mass asociated with the full halo to check
   *  what baryonic fraction is missing/in excess. That will give the mass of gas
   *  that need to be added/subtracted to the hot phase, gas that infalled.*/
  tot_mass = 0.0;

  for(i = 0; i < ngal; i++) {    /* Loop over all galaxies in the FoF-halo */

    /* dis is the separation of the galaxy which i orbits from the type 0 */
    dis=separation_gal(centralgal,Gal[i].CentralGal)/(1+ZZ[Halo[Gal[centralgal].HaloNr].SnapNum]);

    /* If galaxy is orbiting a galaxy inside Rvir of the type 0 it will contribute
     * to the baryon sum */
    if ( dis < Gal[centralgal].Rvir ) {
      tot_mass += Gal[i].DiskMass + Gal[i].BulgeMass + Gal[i].ICM + Gal[i].BlackHoleMass;
      tot_mass += Gal[i].ColdGas + Gal[i].HotGas + Gal[i].EjectedMass + Gal[i].BlackHoleGas;
    }
  }

  /* The logic here seems to be that the infalling mass is supposed to be
   * newly-accreted diffuse gas.  So we take the total mass and subtract all
   * the components that we already know about.  In principle, this could lead
   * to negative infall. */
  /* The reionization modifier is applied to the whole baryon mass, not just the 
   * diffuse component.  It is not obvious that this is the correct thing to do. */
  /* The baryonic fraction is conserved by adding/subtracting the infallingMass
   * calculated here to/from the hot gas of the central galaxy of the FOF
   * This is done in main.c where the infall recipe is called.
   * If ReionizationOn>0, the impact of reonization on the fraction of infalling
   * gas is computed, this is done using the Gnedin formalism with a choice
   * of fitting parameters to the formulas proposed by these authors.
   * There are two options. In both cases reionization has the effect of reducing 
   * the fraction of baryons that collapse into dark matter halos, reducing the
   * amount of infalling gas. */
  if(ReionizationOn == 0) {
    reionization_modifier = 1.0;
    infallingMass = reionization_modifier *BaryonFrac * Gal[centralgal].Mvir - tot_mass;
  }

#if defined(READXFRAC) || defined(WITHRADIATIVETRANSFER)
  else if(ReionizationOn == 3)
    {
      if(Gal[centralgal].Xfrac3d > 0.5)
	{
	  if(Gal[centralgal].HaloM_Crit200 < 0.01*Hubble_h)
	    reionization_modifier = 0.;
	  else
	    reionization_modifier = 1.;
	}
      else
	{
	  reionization_modifier = 1.0;
	}
      infallingMass = reionization_modifier * (BaryonFrac * Gal[centralgal].Mvir - tot_mass);
      // printf("re_modifier:%f\n",Gal[centralgal].Xfrac3d,reionization_modifier);
    }
  else if(ReionizationOn == 4)
    {
      if(Gal[centralgal].Xfrac3d > 0.5)
	{
	  if(Gal[centralgal].HaloM_Crit200 < 0.1*Hubble_h)
	    reionization_modifier = 0.;
	  else
	    reionization_modifier = 1.;
	}
      else
	{
	  reionization_modifier = 1.0;
	}
      // printf("re_modifier:%f\n",Gal[centralgal].Xfrac3d,reionization_modifier);
      infallingMass = reionization_modifier * (BaryonFrac * Gal[centralgal].Mvir - tot_mass);
    }
  else if(ReionizationOn == 5){
    if(Gal[centralgal].Xfrac3d > 0.5){
      if(Gal[centralgal].HaloM_Crit200 < m1)
	reionization_modifier = 0.;
      else if(Gal[centralgal].HaloM_Crit200 >= m1 && Gal[centralgal].HaloM_Crit200 <= m2)
	reionization_modifier = log10(Gal[centralgal].HaloM_Crit200/m1)/log10(m2/m1);
      else
	reionization_modifier = 1.0;
    }
    else{
      reionization_modifier = 1.0;
    }
    infallingMass = reionization_modifier * (BaryonFrac * Gal[centralgal].Mvir - tot_mass);
  }
  else if(ReionizationOn == 6){
    if(Gal[centralgal].Xfrac3d > 0.5){
      if(Gal[centralgal].HaloM_Crit200 < m1)
	reionization_modifier = 0.;
      else if(Gal[centralgal].HaloM_Crit200 >= m1 && Gal[centralgal].HaloM_Crit200 <= m2)
	reionization_modifier = log10(Gal[centralgal].HaloM_Crit200/m1)/log10(m2/m1);
      else
	reionization_modifier = 1.0;
    }
    else{
      reionization_modifier = 1.0;
    }
    infallingMass = reionization_modifier * (BaryonFrac * Gal[centralgal].Mvir) - tot_mass;
  }
#endif
  else if(ReionizationOn == 1 || ReionizationOn == 2) {
    reionization_modifier = do_reionization(Gal[centralgal].Mvir, Zcurr);
    infallingMass = reionization_modifier * BaryonFrac * Gal[centralgal].Mvir - tot_mass;
  }
 

  // printf("infall = %g\n",infallingMass);
  //double new_fb;
  //new_fb=0.00625*log10(Gal[centralgal].Mvir*1.e10)+0.06125;
  //new_fb=0.02625*log10(Gal[centralgal].Mvir*1.e10)-0.24;
  //new_fb=0.01375*log10(Gal[centralgal].Mvir*1.e10)-0.05;
  //if(Gal[centralgal].Mvir>50.)
  //	new_fb=0.5*(0.0525*log10(Gal[centralgal].Mvir*1.e10)-0.633);
  //else
  //	new_fb=BaryonFrac;


  /*if(Gal[centralgal].Mvir>50.)
   	new_fb=0.15*pow(Gal[centralgal].Mvir/(3.0e+4),0.15);
  else
   	new_fb=BaryonFrac;*/

  //new_fb=BaryonFrac;
  //if(Gal[centralgal].Mvir>50. && Gal[centralgal].Mvir<100.) new_fb= 0.05;
  //if(Gal[centralgal].Mvir>100. && Gal[centralgal].Mvir<500.) new_fb= 0.1;
  //if(Gal[centralgal].Mvir>500. && Gal[centralgal].Mvir<1000.) new_fb= 0.1;
  //if(Gal[centralgal].Mvir>1000. && Gal[centralgal].Mvir<10000.) new_fb= 0.001;
  //if(Gal[centralgal].Mvir>10000. && Gal[centralgal].Mvir<30000.) new_fb= 0.15;
  //infallingMass = reionization_modifier * new_fb * Gal[centralgal].Mvir - tot_mass;



  return infallingMass;
  
}
/** @brief Updates cold, hot and external gas components due to SN
 *         reheating and ejection. */
void update_from_feedback(int p, int centralgal, double reheated_mass, double ejected_mass)
{
  double dis=0.;
  double massremain;
  double fraction;
  int merger_centre;

  //mass_checks("update_from_feedback #1",p);

  if(Gal[p].ColdGas > 0.)
  {
      //REHEAT
      // if galaxy is a type 1 or a type 2 orbiting a type 1 with hot gas being striped,
      //some of the reheated and ejected masses goes to the type 0 and some stays in the type 1

      if(Gal[p].Type ==0)
	{
	  transfer_gas(p,"Hot",p,"Cold",((float)reheated_mass)/Gal[p].ColdGas,"update_from_feedback", __LINE__);
	}
      else if(Gal[p].Type <3)
	{
	  if(Gal[p].Type ==1)
	    merger_centre=centralgal;
	  else if(Gal[p].Type ==2)
	    merger_centre=Gal[p].CentralGal;

	  dis=separation_gal(centralgal,Gal[p].CentralGal)/(1+ZZ[Halo[Gal[centralgal].HaloNr].SnapNum]);

	  //compute share of reheated mass
	  if (dis<Gal[centralgal].Rvir && Gal[Gal[p].CentralGal].Type == 1)
	    {
	      //mass that remains on type1 (the rest goes to type 0) for reheat - massremain, for eject - ejected mass
	      massremain=reheated_mass*Gal[p].HotRadius/Gal[p].Rvir;
	      ejected_mass = ejected_mass*Gal[p].HotRadius/Gal[p].Rvir;

	      if (massremain > reheated_mass)
		massremain = reheated_mass;
	    }
	  else
	    massremain=reheated_mass;

	  //needed due to precision issues, since we first remove massremain and then (reheated_mass-massremain)
	  //from the satellite into the type 0 and type 1 the fraction might not add up on the second call
	  //since Gal[p].ColdGas is a float and reheated_mass & massremain are doubles
	  if((massremain + reheated_mass)>Gal[p].ColdGas)
	    massremain=Gal[p].ColdGas-reheated_mass;

	  //transfer massremain
	  transfer_gas(Gal[p].CentralGal,"Hot",p,"Cold",massremain/Gal[p].ColdGas,"update_from_feedback", __LINE__);

	  //transfer reheated_mass-massremain from galaxy to the type 0
	  if (reheated_mass > massremain)
	    if(Gal[p].ColdGas > 0.) //if the reheat to itself, left cold gas below limit do not reheat to central
	      transfer_gas(centralgal,"Hot",p,"Cold",(reheated_mass-massremain)/Gal[p].ColdGas,"update_from_feedback", __LINE__);
	}//types

  }//if(Gal[p].ColdGas > 0.)

  mass_checks("update_from_feedback #2",p);

  //DO EJECTION OF GAS
  if (Gal[Gal[p].CentralGal].HotGas > 0.)
    {
      if (ejected_mass > Gal[Gal[p].CentralGal].HotGas)
	ejected_mass = Gal[Gal[p].CentralGal].HotGas;  //either eject own gas or merger_centre gas for ttype 2's

      fraction=((float)ejected_mass)/Gal[Gal[p].CentralGal].HotGas;

      if (Gal[Gal[p].CentralGal].Type == 1)
	{
	  /* If type 1, or type 2 orbiting type 1 near type 0 */
	  if (FateOfSatellitesGas == 0)
	    transfer_gas(Gal[p].CentralGal,"Ejected",Gal[p].CentralGal,"Hot",fraction,"update_from_feedback", __LINE__);
	  else if (FateOfSatellitesGas == 1)
	    {
	      if (dis < Gal[centralgal].Rvir)
		transfer_gas(centralgal,"Hot",Gal[p].CentralGal,"Hot",fraction,"update_from_feedback", __LINE__);
	      else
		transfer_gas(Gal[p].CentralGal,"Ejected",Gal[p].CentralGal,"Hot",fraction,"update_from_feedback", __LINE__);
	    }
	}
      else // If galaxy type 0 or type 2 merging into type 0
	transfer_gas(centralgal,"Ejected",Gal[p].CentralGal,"Hot",fraction,"update_from_feedback", __LINE__);

    }//(Gal[Gal[p].CentralGal].HotGas > 0.)

}
コード例 #4
0
void add_infall_to_hot(int centralgal, int ngal, double infallingGas) {

  if (InfallRecipe == 0)
    {
      /* Check for negative infall and Don't allow! */
      /*if (infallingGas < 0.) {
      //ROB: (07-03-13): This message will never be seen, as add_infall_to_hot() is called IFF infallingGas > 0.0 in main.c
      printf("\ninfallingGas is negative in add_infall_to_hot\n");
      printf("If you really want to do this then you need to rewrite the code.\n");
      printf("This has not been done because it is not obvious how to handle metals:\n");
      printf("- if allowed to outflow then they will be lost for ever;\n");
      printf("- if not then the metallicity of the hotgas will be artificially increased.\n");
      exit(1);
      }*/
      if (infallingGas > 0.)
	{
      /*  Add the infalling gas to the central galaxy hot component */
	  Gal[centralgal].HotGas += infallingGas;
#ifdef INDIVIDUAL_ELEMENTS
	  //Gal[centralgal].HotGas_elements.H += 0.75*infallingGas*1.0e10;
	  Gal[centralgal].HotGas_elements.H += 0.75*(infallingGas/Hubble_h)*1.0e10;
	  Gal[centralgal].HotGas_elements.He += 0.25*(infallingGas/Hubble_h)*1.0e10;
#endif
	}
    }

  else if (InfallRecipe == 1)
    {
      int i;
      double tot_mass;
      double dis;
      double EjectedMass_inter;
      double HGMass_inter;
      double ZGMass_inter;
      double Zfrac;
      double M_infalltoHot;
      double MassExcess;
      double Mass_diff;
      double ZfracHG;
      EjectedMass_inter = 0.;
      HGMass_inter = 0.;
      ZGMass_inter = 0.;
      Zfrac = 0.;
      tot_mass = 0.;
      MassExcess = 0.;
      M_infalltoHot = 0.;
      Mass_diff = 0.;
      ZfracHG = 0.;

      for(i = 0; i < ngal; i++) {    /* Loop over all galaxies in the FoF-halo */

	/* dis is the separation of the galaxy which i orbits from the type 0 */
	dis=separation_gal(centralgal,Gal[i].CentralGal)/(1+ZZ[Halo[Gal[centralgal].HaloNr].SnapNum]);

	/* If galaxy is orbiting a galaxy inside Rvir of the type 0 it will contribute
	 * to the baryon sum */
	if ( dis < Gal[centralgal].Rvir ) {
	  tot_mass += Gal[i].DiskMass + Gal[i].BulgeMass + Gal[i].ICM + Gal[i].BlackHoleMass;
	  tot_mass += Gal[i].ColdGas + Gal[i].HotGas + Gal[i].EjectedMass + Gal[i].BlackHoleGas;
	}
      }

      if (infallingGas > 0.) {
	Gal[centralgal].ExcessMass = max(Gal[centralgal].ExcessMass,infallingGas);
	if(Gal[centralgal].HotGas > 0.)
	  M_infalltoHot = (Gal[centralgal].HotGas/(Gal[centralgal].HotGas + Gal[centralgal].EjectedMass)) * infallingGas;
	else
	  M_infalltoHot = infallingGas;
	if (Gal[centralgal].EjectedMass > 0.){
	  Gal[centralgal].MetalsEjectedMass += Gal[centralgal].MetalsExcessMass * (infallingGas/Gal[centralgal].ExcessMass);
	  Gal[centralgal].MetalsExcessMass -= Gal[centralgal].MetalsExcessMass * (infallingGas/Gal[centralgal].ExcessMass);
	  Gal[centralgal].EjectedMass += Gal[centralgal].ExcessMass * (infallingGas/Gal[centralgal].ExcessMass);
	      
	  Gal[centralgal].ExcessMass -= Gal[centralgal].ExcessMass * (infallingGas/Gal[centralgal].ExcessMass);
	  Gal[centralgal].HotGas += M_infalltoHot;
	  Gal[centralgal].MetalsHotGas += Gal[centralgal].MetalsEjectedMass * (M_infalltoHot/Gal[centralgal].EjectedMass);//infallingGas); //Gal[centralgal].EjectedMass);
	  Gal[centralgal].MetalsEjectedMass -= Gal[centralgal].MetalsEjectedMass * (M_infalltoHot/Gal[centralgal].EjectedMass);//infallingGas);//Gal[centralgal].EjectedMass);
	  Gal[centralgal].EjectedMass -= M_infalltoHot;//Gal[centralgal].EjectedMass * (M_infalltoHot/Gal[centralgal].EjectedMass);
	}
	else {
	  Gal[centralgal].HotGas += Gal[centralgal].ExcessMass * (infallingGas/Gal[centralgal].ExcessMass);
	  Gal[centralgal].MetalsHotGas += Gal[centralgal].MetalsExcessMass * (infallingGas/Gal[centralgal].ExcessMass);
	  Gal[centralgal].MetalsExcessMass -= Gal[centralgal].MetalsExcessMass * (infallingGas/Gal[centralgal].ExcessMass);
	  Gal[centralgal].ExcessMass -= Gal[centralgal].ExcessMass * (infallingGas/Gal[centralgal].ExcessMass);
	}
	  
	//transfer_gas(Gal[centralgal],"Excess",1.,"Ejected",1.,(infallingGas/Gal[centralgal].ExcessMass));
	//transfer_gas(Gal[centralgal],"Ejected",1.,"Hot",1.,(M_infalltoHot/Gal[centralgal].EjectedMass));
	 
      }
      else if (infallingGas < 0. && tot_mass > 0.) {
	HGMass_inter = - (infallingGas/tot_mass)*Gal[centralgal].HotGas;
	ZGMass_inter = - (infallingGas/tot_mass)*Gal[centralgal].MetalsHotGas;
	Gal[centralgal].EjectedMass += min(Gal[centralgal].HotGas,HGMass_inter); 
	Gal[centralgal].MetalsEjectedMass += min(Gal[centralgal].MetalsHotGas,ZGMass_inter); 
	Gal[centralgal].MetalsHotGas -= min(Gal[centralgal].MetalsHotGas,ZGMass_inter);
	Gal[centralgal].HotGas -= min(Gal[centralgal].HotGas,HGMass_inter);
	  
	Mass_diff = Gal[centralgal].EjectedMass + infallingGas;
	
	if (Mass_diff > 0.) {
	  Gal[centralgal].ExcessMass += min(Gal[centralgal].EjectedMass,(- infallingGas));
	  if (Gal[centralgal].EjectedMass > 0.)
	    Zfrac = - (infallingGas/Gal[centralgal].EjectedMass);
	  else
	    Zfrac = 0.;  
	  Gal[centralgal].MetalsExcessMass += min(Gal[centralgal].MetalsEjectedMass,(Zfrac*Gal[centralgal].MetalsEjectedMass));
	  Gal[centralgal].MetalsEjectedMass -= min(Gal[centralgal].MetalsEjectedMass,(Zfrac*Gal[centralgal].MetalsEjectedMass));
	  Gal[centralgal].EjectedMass -= min(Gal[centralgal].EjectedMass,(- infallingGas));
	}
	else if(Mass_diff < 0.) {
	  Gal[centralgal].EjectedMass += min(Gal[centralgal].HotGas,(- Mass_diff)); 
	  if (Gal[centralgal].MetalsHotGas > 0. && Gal[centralgal].HotGas > 0.0)
	    ZfracHG = - (Mass_diff/Gal[centralgal].HotGas);
	  else
	    Zfrac = 0.;
	  Gal[centralgal].MetalsEjectedMass += min(Gal[centralgal].MetalsHotGas,Gal[centralgal].MetalsHotGas*ZfracHG); 
	  Gal[centralgal].MetalsHotGas -= min(Gal[centralgal].MetalsHotGas,Gal[centralgal].MetalsHotGas*ZfracHG);
	  Gal[centralgal].HotGas -= min(Gal[centralgal].HotGas,(- Mass_diff));

	  Gal[centralgal].ExcessMass += min(Gal[centralgal].EjectedMass,(- infallingGas));
	  if (Gal[centralgal].MetalsEjectedMass > 0.0 )
	    Zfrac = - (Mass_diff/Gal[centralgal].EjectedMass);
	  else
	    Zfrac = 0.;
	 
	  Gal[centralgal].MetalsExcessMass += min(Gal[centralgal].MetalsEjectedMass,(Zfrac*Gal[centralgal].MetalsEjectedMass));
	  Gal[centralgal].MetalsEjectedMass -= min(Gal[centralgal].MetalsEjectedMass,(Zfrac*Gal[centralgal].MetalsEjectedMass));
	  Gal[centralgal].EjectedMass -= min(Gal[centralgal].EjectedMass,(- infallingGas));
	} 
      }
      /* if(Zfrac != Zfrac) */
      /* 	printf("zfrac = %lg\n",Zfrac); */
    }

}