void sfh_merge(int p, int p1) { /* Merge galaxy p1 into galaxy p */ int i; /* Perform minimal test that the two galaxies have the same time structure */ if (Gal[p1].sfh_ibin != Gal[p].sfh_ibin) { printf("sfh_merge: trying to merge galaxies with different sfh bins\n"); sfh_print(p); sfh_print(p1); exit(1); } /* The zero-ing of galaxy p1 here is not strictly necessary as galaxy p1 should * cease to exist after merging, but helps to make mass conservation explicit. */ for(i=0;i<=Gal[p].sfh_ibin;i++) { Gal[p].sfh_DiskMass[i]+=Gal[p1].sfh_DiskMass[i]; Gal[p].sfh_BulgeMass[i]+=Gal[p1].sfh_BulgeMass[i]; Gal[p].sfh_ICM[i]+=Gal[p1].sfh_ICM[i]; Gal[p1].sfh_DiskMass[i]=0.; Gal[p1].sfh_BulgeMass[i]=0.; Gal[p1].sfh_ICM[i]=0.; Gal[p].sfh_MetalsDiskMass[i]= metals_add(Gal[p].sfh_MetalsDiskMass[i],Gal[p1].sfh_MetalsDiskMass[i],1.); Gal[p].sfh_MetalsBulgeMass[i]= metals_add(Gal[p].sfh_MetalsBulgeMass[i],Gal[p1].sfh_MetalsBulgeMass[i],1.); Gal[p].sfh_MetalsICM[i]= metals_add(Gal[p].sfh_MetalsICM[i],Gal[p1].sfh_MetalsICM[i],1.); Gal[p1].sfh_MetalsDiskMass[i]=metals_init(); Gal[p1].sfh_MetalsBulgeMass[i]=metals_init(); Gal[p1].sfh_MetalsICM[i]=metals_init(); #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[i] = elements_add(Gal[p].sfh_ElementsDiskMass[i],Gal[p1].sfh_ElementsDiskMass[i],1.); Gal[p].sfh_ElementsBulgeMass[i] = elements_add(Gal[p].sfh_ElementsBulgeMass[i],Gal[p1].sfh_ElementsBulgeMass[i],1.); Gal[p].sfh_ElementsICM[i] = elements_add(Gal[p].sfh_ElementsICM[i],Gal[p1].sfh_ElementsICM[i],1.); Gal[p1].sfh_ElementsDiskMass[i]=elements_init(); Gal[p1].sfh_ElementsBulgeMass[i]=elements_init(); Gal[p1].sfh_ElementsICM[i]=elements_init(); #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[i]+=Gal[p1].sfh_BurstMass[i]; Gal[p1].sfh_BurstMass[i]=0.; #endif } /* Again, not strictly necessary, but safe. */ Gal[p1].sfh_ibin=0; Gal[p1].sfh_age=0.; }
void sfh_print(int p) { /* Prints out populated sfh_structure. * Does sum of Disk + Bulge only. */ int i; printf("For galaxy %d:\n",p); printf("sfh_ibin=%d\n",Gal[p].sfh_ibin); printf("sfh_age=%f\n",Gal[p].sfh_age); printf(" i dt t Stars Metals\n"); for(i=0;i<SFH_NBIN;i++) if (Gal[p].sfh_dt[i]!=0) { printf("%5d %5e %5e %12f\n",i,Gal[p].sfh_dt[i],Gal[p].sfh_t[i],(Gal[p].sfh_DiskMass[i]+Gal[p].sfh_BulgeMass[i])); metals_print("..",metals_add(Gal[p].sfh_MetalsDiskMass[i],Gal[p].sfh_MetalsBulgeMass[i],1.)); #ifdef INDIVIDUAL_ELEMENTS elements_print("..",elements_add(Gal[p].sfh_ElementsDiskMass[i],Gal[p].sfh_ElementsBulgeMass[i],1.)); #endif printf(".......................\n"); } }
void grow_black_hole(int merger_centralgal, double mass_ratio, double deltaT) { double BHaccrete, fraction; /** @brief Grows black hole through accretion from cold gas during mergers, * as in Kauffmann & Haehnelt (2000). I have made an addition here - * the black hole can grow during minor mergers but at a reduced rate * and i have included evolution with redshift. * BlackHoleGrowth == 0 gives instantaneous accretion onto the black hole; * BlackHoleGrowth == 1 instead feeds an accretion disk: accretion occurs * in main.c */ if(Gal[merger_centralgal].ColdGas > 0.0) { BHaccrete = BlackHoleGrowthRate * mass_ratio / (1.0 + pow2((BlackHoleCutoffVelocity / Gal[merger_centralgal].Vvir))) * Gal[merger_centralgal].ColdGas; /* redshift dependent accretion, not published */ /* BHaccrete = BlackHoleGrowthRate * (1.0 + ZZ[Halo[halonr].SnapNum]) * mass_ratio */ /* cannot accrete more gas than is available! */ if(BHaccrete > Gal[merger_centralgal].ColdGas) BHaccrete = Gal[merger_centralgal].ColdGas; fraction=BHaccrete/Gal[merger_centralgal].ColdGas; if (BlackHoleGrowth == 0) { Gal[merger_centralgal].BlackHoleMass += BHaccrete; Gal[merger_centralgal].QuasarAccretionRate += BHaccrete / deltaT; } else if (BlackHoleGrowth == 1) Gal[merger_centralgal].BlackHoleGas += BHaccrete; Gal[merger_centralgal].ColdGas -= BHaccrete; Gal[merger_centralgal].MetalsColdGas= metals_add(Gal[merger_centralgal].MetalsColdGas, Gal[merger_centralgal].MetalsColdGas,-fraction); #ifdef YIELDS Gal[merger_centralgal].ColdGas_elements = elements_add(Gal[merger_centralgal].ColdGas_elements, Gal[merger_centralgal].ColdGas_elements,-fraction); #endif } }
/**@brief Removes h from units of galaxy properties. If desired (makefile option * FIX_OUTPUT_UNITS is set), the output properties of the galaxies can be scaled * to physical units excluding any factors of h == Hubble/100 km/s/Mpc. */ void fix_units_for_ouput(struct GALAXY_OUTPUT *o) { int j; o->Pos[0] /= Hubble_h; o->Pos[1] /= Hubble_h; o->Pos[2] /= Hubble_h; o->CentralMvir /= Hubble_h; o->Mvir /= Hubble_h; o->Rvir /= Hubble_h; #ifdef HALOPROPERTIES o->HaloM_Mean200 /= Hubble_h; o->HaloM_Crit200 /= Hubble_h; o->HaloM_TopHat /= Hubble_h; o->HaloPos[0] /= Hubble_h; o->HaloPos[1] /= Hubble_h; o->HaloPos[2] /= Hubble_h; o->HaloSpin[0] /= Hubble_h; o->HaloSpin[1] /= Hubble_h; o->HaloSpin[2] /= Hubble_h; #endif o->GasSpin[0] /= Hubble_h; o->GasSpin[1] /= Hubble_h; o->GasSpin[2] /= Hubble_h; o->StellarSpin[0] /= Hubble_h; o->StellarSpin[1] /= Hubble_h; o->StellarSpin[2] /= Hubble_h; o->HotRadius /= Hubble_h; o->ColdGas /= Hubble_h; o->DiskMass /= Hubble_h; o->BulgeMass /= Hubble_h; o->HotGas /= Hubble_h; o->EjectedMass /= Hubble_h; o->BlackHoleMass /= Hubble_h; o->ICM /= Hubble_h; o->BulgeSize /= Hubble_h; o->StellarDiskRadius /= Hubble_h; o->GasDiskRadius /= Hubble_h; o->CoolingRadius /= sqrt(Hubble_h); #ifdef TRACK_BURST o->BurstMass /= Hubble_h; #endif o->MetalsColdGas=metals_add(metals_init(),o->MetalsColdGas,1./Hubble_h); o->MetalsDiskMass=metals_add(metals_init(),o->MetalsDiskMass,1./Hubble_h); o->MetalsBulgeMass=metals_add(metals_init(),o->MetalsBulgeMass,1./Hubble_h); o->MetalsHotGas=metals_add(metals_init(),o->MetalsHotGas,1./Hubble_h); o->MetalsEjectedMass=metals_add(metals_init(),o->MetalsEjectedMass,1./Hubble_h); o->MetalsICM=metals_add(metals_init(),o->MetalsICM,1./Hubble_h); #ifdef STAR_FORMATION_HISTORY for(j=0;j<=o->sfh_ibin;j++) { o->sfh_DiskMass[j] /= Hubble_h; o->sfh_BulgeMass[j] /= Hubble_h; o->sfh_ICM[j] /= Hubble_h; #ifdef TRACK_BURST o->sfh_BurstMass[j] /= Hubble_h; #endif o->sfh_MetalsDiskMass[j]=metals_add(metals_init(), o->sfh_MetalsDiskMass[j],1./Hubble_h); o->sfh_MetalsBulgeMass[j]=metals_add(metals_init(), o->sfh_MetalsBulgeMass[j],1./Hubble_h); o->sfh_MetalsICM[j]=metals_add(metals_init(), o->sfh_MetalsICM[j],1./Hubble_h); } #endif }
void sfh_update_bins(int p, int snap, int step, double time) { /* Adds new bins as required. * Then merges bins whenever you have three or more of the same size. * Assumes that time counts from zero at the big bang. */ int i, j; // loop index int SFH_ibin; //desired ibin (i.e. bin in question in for loop below) SFH_ibin=0; Gal[p].sfh_age=time; //t=time/SFH_TIME_INTERVAL; //ibin=Gal[p].sfh_ibin; for(i=0;i<SFH_NBIN;i++) if(SFH_Nbins[snap][step][i]>0) //i.e. If bin is active... SFH_ibin=i; //Assign with 'bin in question' if (Gal[p].sfh_ibin == 0) //i.e. If highest active bin is bin 0... { for(i=0;i<=SFH_ibin;i++) { Gal[p].sfh_t[i]=SFH_t[snap][step][i]; Gal[p].sfh_Nbins[i]=SFH_Nbins[snap][step][i]; } Gal[p].sfh_ibin=SFH_ibin; } else //i.e. If highest active bin is > bin 0... { i=0; while(i<=SFH_ibin) //Up to 'bin in question'... { if(i<=Gal[p].sfh_ibin) //...until highest active bin is reached... { if(Gal[p].sfh_Nbins[i]!= SFH_Nbins[snap][step][i]) //...and until bin has grown to required size. { // Merge bins i and i+1 Gal[p].sfh_Nbins[i]+=Gal[p].sfh_Nbins[i+1]; Gal[p].sfh_t[i]=Gal[p].sfh_t[i+1]; Gal[p].sfh_DiskMass[i]+=Gal[p].sfh_DiskMass[i+1]; Gal[p].sfh_BulgeMass[i]+=Gal[p].sfh_BulgeMass[i+1]; Gal[p].sfh_ICM[i]+=Gal[p].sfh_ICM[i+1]; Gal[p].sfh_MetalsDiskMass[i]=metals_add(Gal[p].sfh_MetalsDiskMass[i],Gal[p].sfh_MetalsDiskMass[i+1],1.); Gal[p].sfh_MetalsBulgeMass[i]=metals_add(Gal[p].sfh_MetalsBulgeMass[i],Gal[p].sfh_MetalsBulgeMass[i+1],1.); Gal[p].sfh_MetalsICM[i]= metals_add(Gal[p].sfh_MetalsICM[i],Gal[p].sfh_MetalsICM[i+1],1.); #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[i] = elements_add(Gal[p].sfh_ElementsDiskMass[i],Gal[p].sfh_ElementsDiskMass[i+1],1.); Gal[p].sfh_ElementsBulgeMass[i] = elements_add(Gal[p].sfh_ElementsBulgeMass[i],Gal[p].sfh_ElementsBulgeMass[i+1],1.); Gal[p].sfh_ElementsICM[i] = elements_add(Gal[p].sfh_ElementsICM[i],Gal[p].sfh_ElementsICM[i+1],1.); #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[i]+=Gal[p].sfh_BurstMass[i+1]; #endif // Relabel all the other bins for(j=i+1;j<Gal[p].sfh_ibin;j++) { Gal[p].sfh_Nbins[j]=Gal[p].sfh_Nbins[j+1]; Gal[p].sfh_t[j]=Gal[p].sfh_t[j+1]; Gal[p].sfh_DiskMass[j]=Gal[p].sfh_DiskMass[j+1]; Gal[p].sfh_BulgeMass[j]=Gal[p].sfh_BulgeMass[j+1]; Gal[p].sfh_ICM[j]=Gal[p].sfh_ICM[j+1]; Gal[p].sfh_MetalsDiskMass[j]=Gal[p].sfh_MetalsDiskMass[j+1]; Gal[p].sfh_MetalsBulgeMass[j]=Gal[p].sfh_MetalsBulgeMass[j+1]; Gal[p].sfh_MetalsICM[j]=Gal[p].sfh_MetalsICM[j+1]; #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[j]=Gal[p].sfh_ElementsDiskMass[j+1]; Gal[p].sfh_ElementsBulgeMass[j]=Gal[p].sfh_ElementsBulgeMass[j+1]; Gal[p].sfh_ElementsICM[j]=Gal[p].sfh_ElementsICM[j+1]; #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[j]=Gal[p].sfh_BurstMass[j+1]; #endif } //set last bin to zero Gal[p].sfh_flag[j]=0; Gal[p].sfh_Nbins[j]=0; Gal[p].sfh_t[j]=0.; Gal[p].sfh_DiskMass[j]=0.; Gal[p].sfh_BulgeMass[j]=0.; Gal[p].sfh_ICM[j]=0.; Gal[p].sfh_MetalsDiskMass[j]=metals_init(); Gal[p].sfh_MetalsBulgeMass[j]=metals_init(); Gal[p].sfh_MetalsICM[j]=metals_init(); #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[j]=elements_init(); Gal[p].sfh_ElementsBulgeMass[j]=elements_init(); Gal[p].sfh_ElementsICM[j]=elements_init(); #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[j]=0.; #endif Gal[p].sfh_ibin=j-1; /* If there are no more time bins in the galaxy to merge and * the last bin still doesn't have the required size * re-size it according to the reference structure SFH */ if(Gal[p].sfh_Nbins[i+1]==0) { Gal[p].sfh_Nbins[i]=SFH_Nbins[snap][step][i]; Gal[p].sfh_t[i]=SFH_t[snap][step][i]; i+=1; } } else i+=1; } else { //no more bins available in the galaxy, fill the rest times from SFH array for(j=i;j<=SFH_ibin;j++) { Gal[p].sfh_Nbins[j]=SFH_Nbins[snap][step][j]; Gal[p].sfh_t[j]=SFH_t[snap][step][j]; Gal[p].sfh_DiskMass[j]=0.; Gal[p].sfh_BulgeMass[j]=0.; Gal[p].sfh_ICM[j]=0.; Gal[p].sfh_MetalsDiskMass[j]=metals_init(); Gal[p].sfh_MetalsBulgeMass[j]=metals_init(); Gal[p].sfh_MetalsICM[j]=metals_init(); #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[j]=elements_init(); Gal[p].sfh_ElementsBulgeMass[j]=elements_init(); Gal[p].sfh_ElementsICM[j]=elements_init(); #endif #ifdef TRACK_BURST Gal[p].sfh_BurstMass[j]=0.; #endif Gal[p].sfh_ibin=j; } i=j; } }//end while }//end else for(i=0;i<SFH_NBIN;i++) { if(i==0) Gal[p].sfh_dt[i]=NumToTime(0)-Gal[p].sfh_t[i]; else Gal[p].sfh_dt[i]=Gal[p].sfh_t[i-1]-Gal[p].sfh_t[i]; } }
//void update_from_star_formation(int p, double time, double stars, double metallicity) void update_from_star_formation(int p, double stars, bool flag_burst, int nstep) { int i; double fraction; double stars_to_add=0.; if(Gal[p].ColdGas <= 0. || stars <= 0.) { printf("update_from_star_formation: Gal[p].ColdGas <= 0. || stars <= 0.\n"); exit(0); } /* If DETAILED_METALS_AND_MASS_RETURN, no longer an assumed instantaneous * recycled fraction. Mass is returned over time via SNe and AGB winds. * Update the Stellar Spin when forming stars */ #ifndef DETAILED_METALS_AND_MASS_RETURN stars_to_add=(1 - RecycleFraction) * stars; #else stars_to_add=stars; #endif if (Gal[p].DiskMass+stars_to_add > 1.e-8) for (i = 0; i < 3; i++) Gal[p].StellarSpin[i]=((Gal[p].StellarSpin[i])*(Gal[p].DiskMass) + stars_to_add*Gal[p].GasSpin[i])/(Gal[p].DiskMass+stars_to_add); /* Update Gas and Metals from star formation */ mass_checks("update_from_star_formation #0",p); fraction=stars_to_add/Gal[p].ColdGas; #ifdef STAR_FORMATION_HISTORY Gal[p].sfh_DiskMass[Gal[p].sfh_ibin]+=stars_to_add; //ROB: Now, all SF gas is put in SFH array ("recycled' mass will return to gas phase over time) Gal[p].sfh_MetalsDiskMass[Gal[p].sfh_ibin] = metals_add(Gal[p].sfh_MetalsDiskMass[Gal[p].sfh_ibin],Gal[p].MetalsColdGas,fraction); #ifdef INDIVIDUAL_ELEMENTS Gal[p].sfh_ElementsDiskMass[Gal[p].sfh_ibin] = elements_add(Gal[p].sfh_ElementsDiskMass[Gal[p].sfh_ibin],Gal[p].ColdGas_elements,fraction); #endif #ifdef TRACK_BURST if (flag_burst) Gal[p].sfh_BurstMass[Gal[p].sfh_ibin]+=stars_to_add; #endif #endif Gal[p].MetalsDiskMass=metals_add(Gal[p].MetalsDiskMass,Gal[p].MetalsColdGas,fraction); Gal[p].MetalsColdGas=metals_add(Gal[p].MetalsColdGas,Gal[p].MetalsColdGas,-fraction); //GLOBAL PROPERTIES Gal[p].DiskMass += stars_to_add; Gal[p].ColdGas -= stars_to_add; #ifdef INDIVIDUAL_ELEMENTS Gal[p].DiskMass_elements=elements_add(Gal[p].DiskMass_elements,Gal[p].ColdGas_elements,fraction); Gal[p].ColdGas_elements=elements_add(Gal[p].ColdGas_elements,Gal[p].ColdGas_elements,-fraction); #endif #ifdef TRACK_BURST if (flag_burst) Gal[p].BurstMass+=stars_to_add; #endif mass_checks("update_from_star_formation #1",p); /* Formation of new metals - instantaneous recycling approximation - only SNII * Also recompute the metallicity of the cold phase.*/ #ifndef DETAILED_METALS_AND_MASS_RETURN /* stars used because the Yield is defined as a fraction of * all stars formed, not just long lived */ Gal[p].MetalsColdGas += Yield * stars; #endif if (DiskRadiusModel == 0) get_stellar_disk_radius(p); }
void do_AGN_heating(double dt, int ngal) { double AGNrate, AGNheating, AGNaccreted, AGNcoeff, fraction, EDDrate, FreeFallRadius; double dist, HotGas, HotRadius, Rvir, Vvir, Mvir; double LeftOverEnergy, CoolingGas, AGNAccretedFromCentral; int p, FoFCentralGal; if(AGNRadioModeModel == 0) { for (p = 0; p < ngal; p++) if(Gal[p].Type == 0) FoFCentralGal=p; } for (p = 0; p < ngal; p++) { Gal[p].CoolingRate_beforeAGN += Gal[p].CoolingGas / (dt*STEPS); AGNrate=0.; LeftOverEnergy = 0.; HotGas = Gal[p].HotGas; HotRadius = Gal[p].HotRadius; CoolingGas = Gal[p].CoolingGas; Mvir = Gal[p].Mvir; Rvir = Gal[p].Rvir; Vvir = Gal[p].Vvir; if(HotGas > 0.0) { if(AGNRadioModeModel == 0) AGNrate = AgnEfficiency * (UnitTime_in_s*SOLAR_MASS)/(UNITMASS_IN_G*SEC_PER_YEAR) * Gal[p].BlackHoleMass/Hubble_h * (HotGas/Hubble_h) * 10.; else if(AGNRadioModeModel == 2) { //empirical (standard) accretion recipe - Eq. 10 in Croton 2006 AGNrate = AgnEfficiency / (UNITMASS_IN_G / UnitTime_in_s * SEC_PER_YEAR / SOLAR_MASS) * (Gal[p].BlackHoleMass / 0.01) * pow3(Vvir / 200.0) * ((HotGas / HotRadius * Rvir / Mvir) / 0.1); } else if(AGNRadioModeModel == 3 || AGNRadioModeModel == 4) { double x, lambda, temp, logZ, tot_metals; tot_metals = metals_total(Gal[p].MetalsHotGas); /* temp -> Temperature of the Gas in Kelvin, obtained from * hidrostatic equilibrium KT=0.5*mu_p*(Vc)^2 assuming Vvir~Vc */ temp = 35.9 * Vvir * Vvir; if(tot_metals > 0) logZ = log10(tot_metals / HotGas); else logZ = -10.0; lambda = get_metaldependent_cooling_rate(log10(temp), logZ); x = PROTONMASS * BOLTZMANN * temp / lambda; // now this has units sec g/cm^3 x /= (UnitDensity_in_cgs * UnitTime_in_s); // now in internal units /* Bondi-Hoyle accretion recipe -- efficiency = 0.15 * Eq. 29 in Croton 2006 */ if(AGNRadioModeModel == 3) AGNrate = (2.5 * M_PI * G) * (0.75 * 0.6 * x) * Gal[p].BlackHoleMass * 0.15; else if(AGNRadioModeModel == 4) { /* Cold cloud accretion recipe -- trigger: Rff = 50 Rdisk, * and accretion rate = 0.01% cooling rate * Eq. 25 in Croton 2006 */ FreeFallRadius = HotGas / (6.0 * 0.6 * x * Rvir * Vvir) / HotRadius * Rvir; if(Gal[p].BlackHoleMass > 0.0 && FreeFallRadius < Gal[p].GasDiskRadius * 50.0) AGNrate = 0.0001 * CoolingGas / dt; else AGNrate = 0.0; } } /* Eddington rate */ /* Note that this assumes an efficiency of 50% * - it ignores the e/(1-e) factor in L = e/(1-e) Mdot c^2 */ EDDrate = 1.3e48 * Gal[p].BlackHoleMass / (UnitEnergy_in_cgs / UnitTime_in_s) / 9e10; /* accretion onto BH is always limited by the Eddington rate */ if(AGNrate > EDDrate) AGNrate = EDDrate; /* accreted mass onto black hole the value of dt puts an h factor into AGNaccreted as required for code units */ AGNaccreted = AGNrate * dt; /* cannot accrete more mass than is available! */ if(AGNaccreted > HotGas) AGNaccreted = HotGas; /* coefficient to heat the cooling gas back to the virial temperature of the halo */ /* 1.34e5 = sqrt(2*eta*c^2), eta=0.1 (standard efficiency) and c in km/s * Eqs. 11 & 12 in Croton 2006 */ AGNcoeff = (1.34e5 / Vvir) * (1.34e5 / Vvir); /* cooling mass that can be suppressed from AGN heating */ AGNheating = AGNcoeff * AGNaccreted; if(AGNRadioModeModel == 0 && Gal[p].Type==1) { if(dist < Gal[FoFCentralGal].Rvir) { if(AGNheating > (Gal[p].CoolingGas + Gal[FoFCentralGal].CoolingGas)) { AGNheating = (Gal[p].CoolingGas + Gal[FoFCentralGal].CoolingGas); AGNaccreted = (Gal[p].CoolingGas + Gal[FoFCentralGal].CoolingGas) / AGNcoeff; } if(AGNheating > Gal[p].CoolingGas) LeftOverEnergy = AGNheating - Gal[p].CoolingGas; } } else if(AGNheating > Gal[p].CoolingGas) AGNaccreted = Gal[p].CoolingGas / AGNcoeff; /* limit heating to cooling rate */ if(AGNheating > Gal[p].CoolingGas) AGNheating = Gal[p].CoolingGas; /* accreted mass onto black hole */ Gal[p].BlackHoleMass += AGNaccreted; //ROB: transfer_mass functions should be used here Gal[p].RadioAccretionRate += AGNaccreted / (dt*STEPS); fraction=AGNaccreted/Gal[p].HotGas; Gal[p].HotGas -= AGNaccreted; Gal[p].MetalsHotGas = metals_add(Gal[p].MetalsHotGas,Gal[p].MetalsHotGas, -fraction); #ifdef INDIVIDUAL_ELEMENTS Gal[p].HotGas_elements = elements_add(Gal[p].HotGas_elements,Gal[p].HotGas_elements,-fraction); #endif #ifdef METALS_SELF Gal[p].MetalsHotGasSelf = metals_add(Gal[p].MetalsHotGasSelf,Gal[p].MetalsHotGasSelf,-fraction); #endif } else AGNheating = 0.0; Gal[p].CoolingGas -= AGNheating; if(Gal[p].CoolingGas < 0.0) Gal[p].CoolingGas = 0.0; Gal[p].CoolingRate += Gal[p].CoolingGas / (dt*STEPS); if(AGNRadioModeModel == 0 && LeftOverEnergy>0.) { Gal[FoFCentralGal].CoolingGas -= LeftOverEnergy; if(Gal[FoFCentralGal].CoolingGas < 0.0) Gal[FoFCentralGal].CoolingGas = 0.0; else Gal[FoFCentralGal].CoolingRate -= LeftOverEnergy / (dt*STEPS); } mass_checks("cooling_recipe #2.",p); } }