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