Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    def sfr(self, t):
        try:
            vals = find_nearest(self.sfh, t)

            return vals[1]
        except:
            logger.error("No SFH yet")
Ejemplo n.º 4
0
 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")
Ejemplo n.º 5
0
 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")
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
 def final_sfr(self, t):
     try:
         vals = find_nearest(self.extra_sfr, t)
         return vals[1]
     except:
         logger.error("No SFH yet")
Ejemplo n.º 10
0
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