/** @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); }
void deal_with_galaxy_merger(int p, int merger_centralgal, int centralgal, double time, double deltaT, int nstep) { /** @brief Deals with the physics triggered by mergers, according to the mass * fraction of the merger \f$(M_{\rm{sat}}/M_{\rm{central}}><0.3)\f$. * Add the cold and stellar phase of the satellite galaxy to the central * one, form a bulge at the central galaxy with the stars from the * satellite in a minor merger if BulgeFormationInMinorMergersOn=1. * Grows black hole through accretion from cold gas "quasar mode". * If StarBurstRecipe = 0, the Somerville 2001 model * of bursts is used, SN Feedback from starformation is computed and * the sizes of bulge and disk followed. When a major merger occurs, * the disk of both merging galaxies is completely destroyed to form * a bulge. */ double mi, ma, mass_ratio, Mcstar, Mcgas, Mcbulge, Mpstar, Mpgas,Mpbulge; double frac; #ifdef GALAXYTREE int q; mass_checks("deal_with_galaxy_merger #0",p); mass_checks("deal_with_galaxy_merger #0",merger_centralgal); mass_checks("deal_with_galaxy_merger #0",centralgal); q = Gal[merger_centralgal].FirstProgGal; if(q >= 0) { 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("may not happen"); q = GalTree[q].NextProgGal; if(HaloGal[GalTree[q].HaloGalIndex].GalTreeIndex != q) terminate("inconsistency"); HaloGal[GalTree[q].HaloGalIndex].MergeOn = 2; if(Gal[p].Type == 1) HaloGal[GalTree[q].HaloGalIndex].MergeOn = 3; #endif /* flag galaxy as finished */ Gal[p].Type = 3; /* calculate mass ratio of merging galaxies */ mi = Gal[p].DiskMass+Gal[p].BulgeMass+Gal[p].ColdGas; ma = Gal[merger_centralgal].DiskMass+Gal[merger_centralgal].BulgeMass+Gal[merger_centralgal].ColdGas; if(max(mi,ma) > 0.) mass_ratio = min(mi,ma) / max(mi,ma); else mass_ratio = 1.0; /* record the gas and stellar component mass of merger central and satellite * galaxies before the before merger */ Mcstar=(Gal[merger_centralgal].DiskMass+Gal[merger_centralgal].BulgeMass); Mcbulge=Gal[merger_centralgal].BulgeMass; Mcgas=Gal[merger_centralgal].ColdGas; Mpstar=(Gal[p].DiskMass+Gal[p].BulgeMass); Mpbulge=Gal[p].BulgeMass; Mpgas=Gal[p].ColdGas; mass_checks("deal_with_galaxy_merger #1",p); mass_checks("deal_with_galaxy_merger #1",merger_centralgal); mass_checks("deal_with_galaxy_merger #1",centralgal); /* Add the cold and stellar phase of the merged galaxy to the central one. Also form a bulge if BulgeFormationInMinorMergersOn is set on, but only with the stars from the satellite. In a major merger (dealt at the burst make_bulge_from_burst) all the stars in the central and satellite end up in the central bulge. */ add_galaxies_together(merger_centralgal, p); mass_checks("deal_with_galaxy_merger #2",p); mass_checks("deal_with_galaxy_merger #2",merger_centralgal); mass_checks("deal_with_galaxy_merger #2",centralgal); /* grow black hole through accretion from cold disk during mergers, as in * Kauffmann & Haehnelt (2000) + minor mergers - Quasar Mode */ if(AGNrecipeOn > 0) grow_black_hole(merger_centralgal, mass_ratio, deltaT); mass_checks("deal_with_galaxy_merger #3",p); mass_checks("deal_with_galaxy_merger #3",merger_centralgal); mass_checks("deal_with_galaxy_merger #3",centralgal); if (StarBurstRecipe == 0) { /* Starburst as in Somerville 2001, with feedback computed inside. */ frac=collisional_starburst_recipe(mass_ratio, merger_centralgal, centralgal, time, deltaT, nstep); bulgesize_from_merger(mass_ratio,merger_centralgal,p,Mcstar,Mcbulge,Mcgas, Mpstar,Mpbulge,Mpgas,frac); mass_checks("deal_with_galaxy_merger #3.5",p); mass_checks("deal_with_galaxy_merger #3.5",merger_centralgal); mass_checks("deal_with_galaxy_merger #3.5",centralgal); if(mass_ratio > ThreshMajorMerger) make_bulge_from_burst(merger_centralgal); } mass_checks("deal_with_galaxy_merger #4",p); mass_checks("deal_with_galaxy_merger #4",merger_centralgal); mass_checks("deal_with_galaxy_merger #4",centralgal); /* If we are in the presence of a minor merger, check disk stability (the disk * is completely destroyed in major mergers)*/ if(TrackDiskInstability) if(mass_ratio < ThreshMajorMerger && (Gal[merger_centralgal].DiskMass+Gal[merger_centralgal].BulgeMass) > 0.0) check_disk_instability(merger_centralgal); /* Not supported option to shrink bulge sizes in gas rich mergers */ #ifdef SHRINKINRICHMERGER if (Mcgas+Mcstar+Mpgas+Mpstar > 1.e-8 ) { Gal[merger_centralgal].BulgeSize /= 1+pow((Mcgas+Mpgas)/(Mcgas+Mcstar+Mpgas+Mpstar)/0.15,1.); if (Gal[merger_centralgal].BulgeSize < 1.e-8) Gal[merger_centralgal].BulgeSize = 1.e-8; } #endif if ((Gal[merger_centralgal].BulgeMass > 1.e-6 && Gal[merger_centralgal].BulgeSize == 0.0) || (Gal[merger_centralgal].BulgeMass == 0.0 && Gal[merger_centralgal].BulgeSize >1.e-6)) { printf("central: stellarmass %f, bulgemass %f, bulgesize %f, coldgas %f,gasdisk %f,stellardisk %f \n", (Gal[merger_centralgal].DiskMass+Gal[merger_centralgal].BulgeMass),Gal[merger_centralgal].BulgeMass, Gal[merger_centralgal].BulgeSize,Gal[merger_centralgal].ColdGas,Gal[merger_centralgal].GasDiskRadius, Gal[merger_centralgal].StellarDiskRadius); exit(0); } if (DiskRadiusMethod == 2) { get_gas_disk_radius(merger_centralgal); get_stellar_disk_radius(merger_centralgal); } mass_checks("deal_with_galaxy_merger #5",p); mass_checks("deal_with_galaxy_merger #5",merger_centralgal); mass_checks("deal_with_galaxy_merger #5",centralgal); }
//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); }