def mass_integral(choice, reduce_sn, t, metallicity, sfr_lookup, z_lookup, imf): ''' This function does the mass integral for: - e(t): ejected gas mass em - ez(t): ejected metal mass ezm - ed(t): ejected dust mass edm - Zdiff and SFR diff are also calculated ie at t-taum In: -- choice: array of dust source choices -- t: time in Gyrs -- metallicity: metal mass fraction Mz/Mg -- sfr_lookup: SFR array (time, SFR) based on previous time steps -- z_lookup: metallicity array (time, Z) based on previous time steps -- imf: choice of IMF ''' mu = t_lifetime[-1]['mass'] dm = 0.01 t_0 = 1e-3 ezm = 0. edm = 0. em = 0. # we pull out mass corresponding to age of system # to get lower limit of integral # to make taum lookup faster m = lookup_fn(t_lifetime,'lifetime_low_metals',t)['mass'] lifetime_cols = {'low_metals':1, 'high_metals':2} if metallicity < 0.019: col_choice = lifetime_cols['low_metals'] else: col_choice = lifetime_cols['high_metals'] while m <= mu: if m > 10.: dm = 0.5 # pull out lifetime of star of mass m so we can # calculate SFR when star was born which is t-lifetime taum = lookup_taum(m,col_choice) tdiff = t - taum # only release material after stars die if tdiff <= 0: ezm = 0 edm = 0 em = 0 else: # get nearest Z which corresponds to Z at time=t-taum zdiff = find_nearest(z_lookup,tdiff)[1] sfrdiff = find_nearest(sfr_lookup,tdiff)[1] ezm += ejected_metal_mass(m, sfrdiff, zdiff, metallicity, imf) * dm em += ejected_gas_mass(m, sfrdiff, imf) * dm edm += ejected_dust_mass(choice, reduce_sn, m, sfrdiff, zdiff, metallicity, imf) * dm m += dm return em, ezm, edm
def fresh_metals(m, metallicity): ''' Function to return the fresh new elements made by stars These are metallicity dependent and calls mass_yields table in lookups.py metals for LIMS are from van Hoek Massive stars are from Maeder 1992 For m > 40, then only winds contribute to ejected metals For m <= 40, winds + SNe contribute ''' massyields = find_nearest(mass_yields, m) if metallicity <= 0.0025: if m <= 40: sum_yields = massyields[yn.index('yields_sn_001')]+massyields[yn.index('yields_winds_001')] else: sum_yields = massyields[yn.index('yields_winds_001')] elif metallicity <= 0.006: if m <= 40: sum_yields = massyields[yn.index('yields_sn_004')]+massyields[yn.index('yields_winds_004')] else: sum_yields = massyields[yn.index('yields_winds_004')] elif metallicity <= 0.01: if m <= 40: sum_yields = massyields[yn.index('yields_sn_008')]+massyields[yn.index('yields_winds_008')] else: sum_yields = massyields[yn.index('yields_winds_008')] else: if m <= 40: sum_yields = massyields[yn.index('yields_sn_02')]+massyields[yn.index('yields_winds_02')] else: sum_yields = massyields[yn.index('yields_winds_02')] return sum_yields
def sfr(self, t): try: vals = find_nearest(self.sfh, t) return vals[1] except: logger.error("No SFH yet")
def sfr(self, t): ''' define sfr as function to look up nearest sfr value at any specified time ''' try: vals = find_nearest(self.sfh, t) return vals[1] except: logger.error("No SFH yet")
def sfr(self, t): ''' define sfr as function to look up nearest sfr value at any specified time ''' try: vals = find_nearest(self.sfh,t) return vals[1] except: logger.error("No SFH yet")
def dust_masses_fresh(choice, reduce_sn, m, metallicity): ''' This function returns the dust mass ejected by a star of initial mass m made from freshly synthesised elements For dust formed from newly processed metals we split into two categories: winds from LIMS and SN. LIMS: we multiply the metal yields by a dust condensation efficiency parameter assumed to be 0.45 For high mass stars we use the SN yields of Todini & Ferrara 2001 (MNRAS 325 276) In: -- choice: array of dust source choices, set by user in inits 0th element = sn value 1 or 0 1st element = lims value 1 or 0 2nd element = grain growth value 1 or 0 -- reduce_sn: factor to reduce SN dust contribution, set by user in inits -- m: mass of star -- metallicity: metal mass fraction Mz/Mg delta_new_LIMS - dust condensation efficiency for new metals in LIMS yields - metal yields by mass See Figure 3 in Rowlands et al 2014 (MNRAS 441, 1040) ''' # Which dust sources are turned on or off? choice_sn = choice[0] choice_lims = choice[1] delta_new_LIMS = 0.45 if (m <= 8.0): dustmass = choice_lims*delta_new_LIMS * fresh_metals(m, metallicity) elif (m > 8.0) & (m <= 40.0): # find dust mass from TF01 in dust_mass_sn table # assume massive star winds don't form dust dustmass = choice_sn*(reduce_sn)**-1*find_nearest(np.array(dust_mass_sn),m)[1] else: dustmass = 0. return dustmass
def dust_masses_fresh(choice, reduce_sn, m, metallicity): ''' This function returns the dust mass ejected by a star of initial mass m made from freshly synthesised elements For dust formed from newly processed metals we split into two categories: winds from LIMS and SN. LIMS: we multiply the metal yields by a dust condensation efficiency parameter assumed to be 0.45 For high mass stars we use the SN yields of Todini & Ferrara 2001 (MNRAS 325 276) In: -- choice: array of dust source choices, set by user in inits 0th element = sn value 1 or 0 1st element = lims value 1 or 0 2nd element = grain growth value 1 or 0 -- reduce_sn: factor to reduce SN dust contribution, set by user in inits -- m: mass of star -- metallicity: metal mass fraction Mz/Mg delta_new_LIMS - dust condensation efficiency for new metals in LIMS yields - metal yields by mass See Figure 3 in Rowlands et al 2014 (MNRAS 441, 1040) ''' delta_new_LIMS = 0.45 if (m <= 8.0) and choice['lims']: dustmass = delta_new_LIMS * fresh_metals(m, metallicity) elif (m > 8.0) and (m <= 40.0) and choice['sn']: # find dust mass from TF01 in dust_mass_sn table # assume massive star winds don't form dust dustmass = reduce_sn**-1 * find_nearest(np.array(dust_mass_sn), m)[1] else: dustmass = 0. return dustmass
def fresh_oxygen(m, metallicity): ''' Function to return the fresh oxygen made by stars These are metallicity dependent and calls oxymass_yields table in lookups.py metals for LIMS are from van Hoek Massive stars are from Maeder 1992 For m > 40, then only winds contribute to ejected metals For m <= 40, winds + SNe contribute ''' oxymassyields = find_nearest(oxymass_yields, m) if metallicity <= 0.0025: if m <= 40: sum_yields = oxymassyields[yn.index( 'yields_sn_001')] + oxymassyields[yn.index('yields_winds_001')] else: sum_yields = oxymassyields[yn.index('yields_winds_001')] elif metallicity <= 0.006: if m <= 40: sum_yields = oxymassyields[yn.index( 'yields_sn_004')] + oxymassyields[yn.index('yields_winds_004')] else: sum_yields = oxymassyields[yn.index('yields_winds_004')] elif metallicity <= 0.01: if m <= 40: sum_yields = oxymassyields[yn.index( 'yields_sn_008')] + oxymassyields[yn.index('yields_winds_008')] else: sum_yields = oxymassyields[yn.index('yields_winds_008')] else: if m <= 40: sum_yields = oxymassyields[yn.index( 'yields_sn_02')] + oxymassyields[yn.index('yields_winds_02')] else: sum_yields = oxymassyields[yn.index('yields_winds_02')] return sum_yields
def final_sfr(self, t): try: vals = find_nearest(self.extra_sfr, t) return vals[1] except: logger.error("No SFH yet")
def mass_integral(choice, reduce_sn, t, metallicity, sfr_lookup, z_lookup, imf): ''' This function does the mass integral for: - e(t): ejected gas mass em - ez(t): ejected metal mass ezm - ed(t): ejected dust mass edm - Zdiff and SFR diff are also calculated ie at t-taum (when stars that are dying now were born) In: -- choice: array of dust source choices -- t: time in Gyrs -- metallicity: metal mass fraction Mz/Mg -- sfr_lookup: SFR array (time, SFR) based on previous time steps -- z_lookup: metallicity array (time, Z) based on previous time steps -- imf: choice of IMF ''' mu = t_lifetime[-1]['mass'] t_0 = 1e-3 ezm = 0. edm = 0. em = 0. # we pull out mass corresponding to age of system # to get lower limit of integral # to make taum lookup faster m_min = lookup_fn(t_lifetime,'lifetime_low_metals',t)['mass'] # checks that m_min does not exceed mu if(m_min >= mu): m_min = mu # increasing the number of steps increases the # resolution in the mass integral steps = 500 m = m_min dlogm = 0 logmnew = np.log10(m) + dlogm dm = 10**(logmnew)- m dlogm = (np.log10(mu)-np.log10(m_min))/steps count = 0 lifetime_cols = {'low_metals':1, 'high_metals':2} if metallicity <= 0.008: # in between Z=0.001 and Z=0.02 files from Schaller et al 1992 col_choice = lifetime_cols['low_metals'] else: col_choice = lifetime_cols['high_metals'] # loop over the full mass range while count < steps: count += 1 logmnew = np.log10(m) + dlogm dm = 10.0**(logmnew) - m mmid = 10.0**((logmnew+np.log10(m))/2.0) # pull out lifetime of star of mass m so we can # calculate SFR when star was born which is t-lifetime taum = lookup_taum(mmid,col_choice) tdiff = t - taum # only release material after stars die if tdiff <= 0: ezm = 0 edm = 0 em = 0 else: # get nearest Z and SFR which corresponds to Z and SFR at time=t-taum zdiff = find_nearest(z_lookup,tdiff)[1] sfrdiff = find_nearest(sfr_lookup,tdiff)[1] ezm += ejected_metal_mass(mmid, sfrdiff, zdiff, metallicity, imf) * dm em += ejected_gas_mass(mmid, sfrdiff, imf) * dm edm += ejected_dust_mass(choice, reduce_sn, mmid, sfrdiff, zdiff, metallicity, imf) * dm #Calculate the next mass value mnew = 10**(logmnew) m = mnew return em, ezm, edm