void make_bulge_from_burst(int p) { int outputbin, j; /* generate bulge */ transfer_stars(p,"Bulge",p,"Disk",1.); /* update the star formation rate */ #ifdef SAVE_MEMORY Gal[p].SfrBulge = Gal[p].Sfr; #else for(outputbin = 0; outputbin < NOUT; outputbin++) Gal[p].SfrBulge[outputbin] += Gal[p].Sfr[outputbin]; #endif #ifndef POST_PROCESS_MAGS #ifdef OUTPUT_REST_MAGS for(outputbin = 0; outputbin < NOUT; outputbin++) { for(j = 0; j < NMAG; j++) { Gal[p].LumBulge[j][outputbin] = Gal[p].Lum[j][outputbin]; Gal[p].YLumBulge[j][outputbin] = Gal[p].YLum[j][outputbin]; } } #endif #ifdef COMPUTE_OBS_MAGS for(outputbin = 0; outputbin < NOUT; outputbin++) { for(j = 0; j < NMAG; j++) { Gal[p].ObsLumBulge[j][outputbin] = Gal[p].ObsLum[j][outputbin]; Gal[p].ObsYLumBulge[j][outputbin] = Gal[p].ObsYLum[j][outputbin]; #ifdef OUTPUT_MOMAF_INPUTS Gal[p].dObsLumBulge[j][outputbin] = Gal[p].dObsLum[j][outputbin]; Gal[p].dObsYLumBulge[j][outputbin] = Gal[p].dObsYLum[j][outputbin]; #endif } } #endif #endif //POST_PROCESS_MAGS }
void disrupt(int p, int centralgal) { double rho_sat, rho_cen; double cen_mass, r_sat, radius; int outputbin, j, q; /* If the main halo density at the pericentre (closest point in the orbit * to the central galaxy)is larger than the satellite's density at the * half mass radius, the satellite is completely disrupted. Note that since * the satellite is a type 2 the only mass components remaining and * contributing to the density are the cold gas and stellar mass. */ //TODO If we are passing in centralgal then we should not set it here centralgal=Gal[p].CentralGal; mass_checks("Top of disrupt",centralgal); mass_checks("Top of disrupt",p); /* Radius calculated at the peri-point */ radius=peri_radius(p, centralgal); if (radius < 0) { terminate("must be wrong \n"); } /* Calculate the density of the main central halo at radius (the peri-centre). * The tidal forces are caused by the dark matter of the main halo, hence Mvir * is used. */ cen_mass=Gal[centralgal].Mvir*radius/Gal[centralgal].Rvir; rho_cen=cen_mass/pow3(radius); /* Calculate the density of the satellite's baryonic material */ if (Gal[p].DiskMass+Gal[p].BulgeMass>0) { /* Calculate the rho according to the real geometry */ r_sat = sat_radius(p); /* Or use radius at the mean radius of the stellar mass */ /* r_sat=(Gal[p].BulgeMass*Gal[p].BulgeSize+(Gal[p].StellarMass-Gal[p].BulgeMass) * *Gal[p].StellarDiskRadius/3*1.68) * /(Gal[p].StellarMass); */ /* to calculate the density */ //rho_sat=Gal[p].StellarMass/pow2(r_sat); rho_sat=(Gal[p].DiskMass+Gal[p].BulgeMass+Gal[p].ColdGas)/pow3(r_sat); } else rho_sat=0.0; /* If density of the main halo is larger than that of the satellite baryonic * component, complete and instantaneous disruption is assumed. Galaxy becomes * a type 3 and all its material is transferred to the central galaxy. */ if (rho_cen > rho_sat) { Gal[p].Type = 3; #ifdef GALAXYTREE q = Gal[Gal[p].CentralGal].FirstProgGal; if (q >= 0) { // add progenitors of Gal[p] to the list of progentitors of Gal[p].CentralGal while (GalTree[q].NextProgGal >= 0) q = GalTree[q].NextProgGal; GalTree[q].NextProgGal = Gal[p].FirstProgGal; if(GalTree[q].NextProgGal >= NGalTree) { printf("q=%d p=%d GalTree[q].NextProgGal=%d NGalTree=%d\n", q, p, GalTree[q].NextProgGal, NGalTree); terminate("problem"); } } if(q < 0) terminate("this shouldn't happen"); // TODO if !(q>=0) shouldn't we set // Gal[Gal[p].CentralGal].FirstProgGal to Gal[p].FirstProgGal ?? q = GalTree[q].NextProgGal; if(q < 0) terminate("inconsistency"); if(HaloGal[GalTree[q].HaloGalIndex].GalTreeIndex != q) terminate("inconsistency"); HaloGal[GalTree[q].HaloGalIndex].DisruptOn = 1; #endif /* Put gas component to the central galaxy hot gas and stellar material into the ICM. * Note that the staellite should have no extended components. */ // TODO Shouldn't the stars end up in the bulge? - this is a close merger transfer_gas(centralgal,"Hot",p,"Cold",1.); transfer_gas(centralgal,"Hot",p,"Hot",1.); transfer_stars(centralgal,"ICM",p,"Disk",1.); transfer_stars(centralgal,"ICM",p,"Bulge",1.); /* Add satellite's luminosity into the luminosity of the ICL * component of the central galaxy. */ #ifdef ICL for(outputbin = 0; outputbin < NOUT; outputbin++) { for(j = 0; j < NMAG; j++) { #ifdef OUTPUT_REST_MAGS Gal[centralgal].ICLLum[j][outputbin] += Gal[p].Lum[j][outputbin]; #endif #ifdef COMPUTE_OBS_MAGS Gal[centralgal].ObsICL[j][outputbin] += Gal[p].ObsLum[j][outputbin]; #endif } } #endif } mass_checks("Bottom of disrupt",centralgal); mass_checks("Bottom of disrupt",p); }
void add_galaxies_together(int t, int p) { /** @brief All the components of the satellite galaxy are added to the * correspondent component of the central galaxy. Cold gas spin * is updated and a bulge is formed at the central galaxy, with * the stars of the satellite if BulgeFormationInMinorMergersOn=1. * * TODO Even though galaxy p has been set to type 3 (ie a non-galaxy), it would * make mass conservation more explicit to zero the properties of galaxy p after * the merger. * TODO Correct artificial diffusion of metals when BulgeFormationInMinorMergersOn=1. */ int outputbin, j; float tspin[3],tmass,pmass; /* t central, p satellite */ mass_checks("add_galaxies_together #0",p); mass_checks("add_galaxies_together #0.1",t); /* angular momentum transfer between gas*/ tmass= Gal[t].ColdGas; pmass= Gal[p].ColdGas; Gal[t].MergeSat +=(Gal[p].DiskMass+Gal[p].BulgeMass); Gal[p].MergeSat=0.; transfer_gas(t,"Cold",p,"Cold",1.); transfer_gas(t,"Hot",p,"Hot",1.); transfer_gas(t,"Ejected",p,"Ejected",1.); //TODO chose move to ejected or hot if(BulgeFormationInMinorMergersOn) transfer_stars(t,"Bulge",p,"Disk",1.); else transfer_stars(t,"Disk",p,"Disk",1.); transfer_stars(t,"Bulge",p,"Bulge",1.); transfer_stars(t,"ICM",p,"ICM",1.); Gal[t].BlackHoleMass += Gal[p].BlackHoleMass; Gal[p].BlackHoleMass=0.; Gal[t].BlackHoleGas += Gal[p].BlackHoleGas; Gal[p].BlackHoleGas=0.; Gal[t].StarMerge += Gal[p].StarMerge; Gal[p].StarMerge=0.; mass_checks("add_galaxies_together #1",p); mass_checks("add_galaxies_together #1.1",t); /*update the gas spin*/ for(j=0;j<3;j++) tspin[j]=Gal[t].GasSpin[j]*tmass+Gal[t].HaloSpin[j]*pmass; if (Gal[t].ColdGas != 0) for (j=0;j<3;j++) Gal[t].GasSpin[j]=tspin[j]/(Gal[t].ColdGas); #ifdef SAVE_MEMORY Gal[t].Sfr += Gal[p].Sfr; #else for(outputbin = 0; outputbin < NOUT; outputbin++) Gal[t].Sfr[outputbin] += Gal[p].Sfr[outputbin]; #endif if(BulgeFormationInMinorMergersOn) { #ifdef SAVE_MEMORY Gal[t].SfrBulge += Gal[p].Sfr; #else for(outputbin = 0; outputbin < NOUT; outputbin++) Gal[t].SfrBulge[outputbin] += Gal[p].Sfr[outputbin]; #endif } /* Add the black hole accretion rates. This makes little sense but is not * used if the superior BlackHoleGrowth==1 switch is on. */ Gal[t].QuasarAccretionRate += Gal[p].QuasarAccretionRate; Gal[t].RadioAccretionRate += Gal[p].RadioAccretionRate; #ifndef POST_PROCESS_MAGS /* Add the luminosities of the satellite and central galaxy */ #ifdef OUTPUT_REST_MAGS for(outputbin = 0; outputbin < NOUT; outputbin++) { for(j = 0; j < NMAG; j++) { Gal[t].Lum[j][outputbin] += Gal[p].Lum[j][outputbin]; Gal[t].YLum[j][outputbin] += Gal[p].YLum[j][outputbin]; #ifdef ICL Gal[t].ICLLum[j][outputbin] += Gal[p].ICLLum[j][outputbin]; #endif } if(BulgeFormationInMinorMergersOn) { for(j = 0; j < NMAG; j++) { Gal[t].LumBulge[j][outputbin] += Gal[p].Lum[j][outputbin]; Gal[t].YLumBulge[j][outputbin] += Gal[p].YLum[j][outputbin]; } } else { for(j = 0; j < NMAG; j++) { Gal[t].LumBulge[j][outputbin] += Gal[p].LumBulge[j][outputbin]; Gal[t].YLumBulge[j][outputbin] += Gal[p].YLumBulge[j][outputbin]; } } Gal[t].MassWeightAge[outputbin] += Gal[p].MassWeightAge[outputbin]; } #endif // OUTPUT_REST_MAGS #ifdef COMPUTE_OBS_MAGS for(outputbin = 0; outputbin < NOUT; outputbin++) { for(j = 0; j < NMAG; j++) { Gal[t].ObsLum[j][outputbin] += Gal[p].ObsLum[j][outputbin]; Gal[t].ObsYLum[j][outputbin] += Gal[p].ObsYLum[j][outputbin]; #ifdef ICL Gal[t].ObsICL[j][outputbin] += Gal[p].ObsICL[j][outputbin]; #endif #ifdef OUTPUT_MOMAF_INPUTS Gal[t].dObsLum[j][outputbin] += Gal[p].dObsLum[j][outputbin]; Gal[t].dObsYLum[j][outputbin] += Gal[p].dObsYLum[j][outputbin]; #endif } if(BulgeFormationInMinorMergersOn) { for(j = 0; j < NMAG; j++) { Gal[t].ObsLumBulge[j][outputbin] += Gal[p].ObsLum[j][outputbin]; Gal[t].ObsYLumBulge[j][outputbin] += Gal[p].ObsYLum[j][outputbin]; #ifdef OUTPUT_MOMAF_INPUTS Gal[t].dObsLumBulge[j][outputbin] += Gal[p].dObsLum[j][outputbin]; Gal[t].dObsYLumBulge[j][outputbin] += Gal[p].dObsYLum[j][outputbin]; #endif } } else { for(j = 0; j < NMAG; j++) { Gal[t].ObsLumBulge[j][outputbin] += Gal[p].ObsLumBulge[j][outputbin]; Gal[t].ObsYLumBulge[j][outputbin] += Gal[p].ObsYLumBulge[j][outputbin]; #ifdef OUTPUT_MOMAF_INPUTS Gal[t].dObsLumBulge[j][outputbin] += Gal[p].dObsLumBulge[j][outputbin]; Gal[t].dObsYLumBulge[j][outputbin] += Gal[p].dObsYLumBulge[j][outputbin]; #endif } } } #endif //COMPUTE_OBS_MAGS #endif //POST_PROCESS_MAGS }
/** @brief Checks for disk stability using the * Mo, Mao & White (1998) criteria */ void check_disk_instability(int p) { double Mcrit, fraction, stars, diskmass; /** @brief Calculates the stability of the stellar disk as discussed * in Mo, Mao & White (1998). For unstable stars, the required * amount is transfered to the bulge to make the disk stable again. * Mass, metals and luminosities updated. After Guo2010 the bulge * size is followed and needs to be updated. * Eq 34 & 35 in Guo2010 are used. */ if(DiskInstabilityModel == 0) { /* check stellar disk -> eq 34 Guo2010*/ if (Gal[p].Type != 0) Mcrit = Gal[p].InfallVmax * Gal[p].InfallVmax * Gal[p].StellarDiskRadius / G; else Mcrit = Gal[p].Vmax * Gal[p].Vmax * Gal[p].StellarDiskRadius / G; diskmass = Gal[p].DiskMass; stars = diskmass - Mcrit; fraction = stars / diskmass; } else if (DiskInstabilityModel == 1) stars = 0.; /* add excess stars to the bulge */ if(stars > 0.0) { /* to calculate the bulge size */ update_bulge_from_disk(p,stars); transfer_stars(p,"Bulge",p,"Disk",fraction); if(BHGrowthInDiskInstabilityModel == 1) if(Gal[p].ColdGas > 0.) { Gal[p].BlackHoleMass += Gal[p].ColdGas*fraction; Gal[p].ColdGas -= Gal[p].ColdGas*fraction; } #ifndef POST_PROCESS_MAGS double Lumdisk; int outputbin, j; #ifdef OUTPUT_REST_MAGS for(outputbin = 0; outputbin < NOUT; outputbin++) { for(j = 0; j < NMAG; j++) { Lumdisk = Gal[p].Lum[j][outputbin]-Gal[p].LumBulge[j][outputbin]; Gal[p].LumBulge[j][outputbin] += fraction * Lumdisk; Lumdisk = Gal[p].YLum[j][outputbin]-Gal[p].YLumBulge[j][outputbin]; Gal[p].YLumBulge[j][outputbin] += fraction * Lumdisk; } } #endif #ifdef COMPUTE_OBS_MAGS for(outputbin = 0; outputbin < NOUT; outputbin++) { for(j = 0; j < NMAG; j++) { Lumdisk = Gal[p].ObsLum[j][outputbin]-Gal[p].ObsLumBulge[j][outputbin]; Gal[p].ObsLumBulge[j][outputbin] += fraction * Lumdisk; Lumdisk = Gal[p].ObsYLum[j][outputbin]-Gal[p].ObsYLumBulge[j][outputbin]; Gal[p].ObsYLumBulge[j][outputbin] += fraction * Lumdisk; #ifdef OUTPUT_MOMAF_INPUTS Lumdisk = Gal[p].dObsLum[j][outputbin]-Gal[p].dObsLumBulge[j][outputbin]; Gal[p].dObsLumBulge[j][outputbin] += fraction * Lumdisk; Lumdisk = Gal[p].dObsYLum[j][outputbin]-Gal[p].dObsYLumBulge[j][outputbin]; Gal[p].dObsYLumBulge[j][outputbin] += fraction * Lumdisk; #endif } } #endif #endif if ((Gal[p].BulgeMass > 1e-9 && Gal[p].BulgeSize == 0.0)|| (Gal[p].BulgeMass == 0.0 && Gal[p].BulgeSize >1e-9)) { char sbuf[1000]; sprintf(sbuf, "bulgesize wrong in diskinstablility.c \n"); terminate(sbuf); } }// if(stars > 0.0) }