Пример #1
0
 def test_dust_graingrowth(self):
     dust_ism = graingrowth(1,500,1.02e10,1e9,0.07,6.765e8,0.5)[0]
     assert  3.200e6 < dust_ism < 3.202e6
Пример #2
0
    def gas_metal_dust_mass(self, sn_rate):
        '''
        Calculates the gas, metal and dust mass from stars
        note mass is only ejected after stars die ie when
        t - taum (where taum is lifetime of star) > 0
        '''
        # initialize
        mg = self.gasmass_init
        mstars = 0
        md = 0
        md_all = 0
        md_stars = 0
        md_gg = 0
        metals = 0
        prev_t = 1e-3
        metals_pre = 0
        mstars_list = []
        z = []
        z_lookup = []
        sfr_list = []
        sfr_lookup = []
        all_results = []
        # Limit time to less than tend
        time = self.sfh[:, 0]
        time = time[time < self.tend]
        now = datetime.now()

        #Planet formation
        planets = (self.f_disc * (self.f_wind + self.f_debris) - 1.) * (-1.)
        if planets < 0:
            planets = -1. * planets

        # TIME integral
        for item, t in enumerate(time):
            r_sn = sn_rate[item]
            metallicity = metals / mg

            # start appending arrays for needing later
            z.append([t, metallicity])
            z_lookup = array(z)
            sfr_list.append([t, self.sfr(t)])
            sfr_lookup = array(sfr_list)
            '''
            GAS: dMg = (-sfr(t) + e(t) + inflows(t) - outflows(t)) * dt
            set up astration, inflow, outflow components
            '''
            gas_ast = self.sfr(t)
            gas_inf = inflows(self.sfr(t), self.inflows['xSFR'])
            gas_out = outflows(self.sfr(t), self.outflows['xSFR'])
            '''
            METALS: dMz = (-Z*sfr(t) + ez(t) + Z*inflows(t) - Z*outflows(t)) * dt
            set up astration, inflow and outflow components
            '''
            metals_ast = astration(metals, mg, self.sfr(t)) * planets
            if self.outflows['metals']:
                metals_out = metallicity * outflows(self.sfr(t),
                                                    self.outflows['xSFR'])
            else:
                metals_out = 0.
            metals_inf = self.inflows['metals'] * inflows(
                self.sfr(t), self.inflows['xSFR'])
            '''
            DUST: dMd = (-Md/Mg*sfr(t) + ed(t) + Md/Mg*inflows(t) - Md/Mg*outflows(t)
                         - (1-f)*Md/t_destroy + f(1-Md/Mg)*Md/t_graingrowth) * dt
            set up astration, inflows, outflows, destruction, grain growth components
            '''
            if self.outflows['dust']:
                mdust_out = (md / mg) * outflows(self.sfr(t),
                                                 self.outflows['xSFR'])
            else:
                mdust_out = 0.
            mdust_inf = self.inflows['dust'] * inflows(self.sfr(t),
                                                       self.inflows['xSFR'])
            mdust_ast = astration(md, mg, self.sfr(t)) * planets

            mdust_gg, t_gg = graingrowth(self.choice_dust['gg'], self.epsilon,
                                         mg, self.sfr(t), metallicity, md,
                                         self.coldfraction)
            mdust_des, t_des = destroy_dust(self.choice_des, self.destroy_ism,
                                            mg, r_sn, md, self.coldfraction)
            '''
            Get ejected masses from stars when they die
            gas_ej = e(t): ejected gas mass from stars of mass m at t = taum
            metals_stars = ez(t): ejected metal mass from stars of mass m at t = taum (fresh + recycled)
            mdust_stars = ed(t): ejected dust mass from stars of mass m at t = taum (fresh + recycled)
            '''
            gas_ej, metals_stars, mdust_stars = \
                    mass_integral(self.choice_dust, self.reduce_sn, t, metallicity, sfr_lookup, z_lookup, self.imf)
            '''
            STARS: dM_stars = (sfr(t) - e(t)) * dt
            '''
            dmstars = self.sfr(t) - gas_ej
            '''
            integrate over time for gas, metals and stars (mg, metals, md)
            '''
            dmg = -gas_ast + gas_ej + gas_inf - gas_out
            dmetals = -metals_ast + metals_stars + metals_pre + metals_inf - metals_out
            ddust = -mdust_ast + mdust_stars + mdust_inf - mdust_out + mdust_gg - mdust_des
            # dust_source_all separates out the dust sources (Md vs t) wihtout including sinks (Astration etc)
            # and grain growth separately (this is the Md vs time contributed by dust sources)
            dust_source_all = mdust_stars + mdust_gg
            dt = t - prev_t  # calculate  next time step
            prev_t = t
            mstars += dmstars * dt
            mg += dmg * dt  # gas mass integral
            if mg <= 0:
                # exit program if all ISM removed
                print('Oops you have no interstellar medium left')
                break
            metals += dmetals * dt  # metal mass integral
            md += ddust * dt  # dust mass integral
            md_all += dust_source_all * dt  # dust mass sources integral
            md_gg += mdust_gg * dt  # dust source from grain growth only
            md_stars += mdust_stars * dt  # dust source from stars only
            Z = zip(*z_lookup)  # write metallicity to an array
            s_f_r = zip(*sfr_lookup)  # write SFR lookup array
            if mg <= 0. or metals <= 0:  # write dust/metals ratio
                dust_to_metals = 0.
            else:
                dust_to_metals = md / metals
            all_results.append((t, mg, mstars, metals, metallicity, \
                                md, dust_to_metals, self.sfr(t)*1e-9, \
                                md_all, md_stars, md_gg, t_des, t_gg))
            # to test code kinks
        print("Gas, metal and dust mass exterior loop %s" %
              str(datetime.now() - now))
        return np.array(all_results)
Пример #3
0
    def gas_metal_dust_mass(self, sn_rate):
        """
        Calculates the gas, metal and dust mass from stars
        mass is only ejected after stars die ie when
        t - taum (lifetime of star) > 0
        """
        # initialize
        mg = self.gasmass_init
        mstars = 0
        md = 0
        md_all = 0
        md_stars = 0
        md_gg = 0
        metals = 0
        prev_t = 1e-3
        metals_pre = 0
        dust_sources = []
        timescales = []
        mstars_list = []
        z = []
        z_lookup = []
        sfr_list = []
        sfr_lookup = []
        all_results = []
        # Limit time to less than tend
        time = self.sfh[:, 0]
        time = time[time < self.tend]
        now = datetime.now()
        # TIME integral
        for item, t in enumerate(time):
            r_sn = sn_rate[item]
            metallicity = metals / mg
            metals_ast = f.astration(metals, mg, self.sfr(t))
            mdust_ast = f.astration(md, mg, self.sfr(t))
            if self.outflows["metals"]:
                metals_out = metallicity * f.outflows(self.sfr(t), self.outflows["xSFR"])
            else:
                metals_out = 0.0
            if self.outflows["dust"]:
                mdust_out = (md / mg) * f.outflows(self.sfr(t), self.outflows["xSFR"])
            else:
                mdust_out = 0.0

            z.append([t, metallicity])
            z_lookup = np.array(z)
            sfr_list.append([t, self.sfr(t)])
            sfr_lookup = np.array(sfr_list)

            # STARS
            dmstars = self.sfr(t)

            # GAS
            # astration, inflows, outflows
            gas_ast = self.sfr(t)
            gas_inf = f.inflows(self.sfr(t), self.inflows["xSFR"])
            gas_out = f.outflows(self.sfr(t), self.outflows["xSFR"])

            # METALS
            # inflows, outflows
            metals_inf = self.inflows["metals"] * f.inflows(self.sfr(t), self.inflows["xSFR"])

            # DUST
            # astration, inflows, outflows, grain growth, destruction
            mdust_inf = self.inflows["dust"] * f.inflows(self.sfr(t), self.inflows["xSFR"])
            mdust_gg, t_gg = f.graingrowth(
                self.choice_dust[2], self.epsilon, mg, self.sfr(t), metallicity, md, self.coldfraction
            )
            mdust_des, t_des = f.destroy_dust(self.choice_des, self.destroy_ism, mg, r_sn, md, self.coldfraction)

            # do the mass integral to get ejected masses for gas, metals, dust
            gas_ej, metals_stars, mdust_stars = f.mass_integral(
                self.choice_dust, self.reduce_sn, t, metallicity, sfr_lookup, z_lookup, self.imf
            )

            # gas mass integral dmg/dt =
            dmg = -gas_ast + gas_ej + gas_inf - gas_out

            # metal mass integral dMz/dt =

            dmetals = -metals_ast + metals_stars + metals_pre + metals_inf - metals_out

            # dust mass integral dMd/dt
            ddust = -mdust_ast + mdust_stars + mdust_inf - mdust_out + mdust_gg - mdust_des

            dust_source_all = mdust_stars + mdust_gg  # dust sources stars + grain growth
            dt = t - prev_t  # calculate  next time step
            prev_t = t
            mstars += dmstars * dt
            mg += dmg * dt  # gas mass integral
            if mg <= 0:
                # exit program if all ISM removed
                print("Oops you have no interstellar medium left")
                break
            metals += dmetals * dt
            md += ddust * dt  # dust mass integral
            md_all += dust_source_all * dt  # dust mass sources integral
            md_gg += mdust_gg * dt  # dust source from grain growth only
            md_stars += mdust_stars * dt  # dust source from stars only
            Z = zip(*z_lookup)  # write metallicity to an array
            s_f_r = zip(*sfr_lookup)  # write SFR lookup array
            dust_sources.append((md_all, md_stars, md_gg))  # write array of dust sources
            timescales.append((t_des, t_gg))  # write array for grain growth & destruction timescales
            if mg <= 0.0 or metals <= 0:  # write dust/metals ratio
                dust_to_metals = 0.0
            else:
                dust_to_metals = md / metals
            all_results.append((t, mg, mstars, metals, metallicity, md, dust_to_metals, self.sfr(t) * 1e-9))
        print("Gas, metal and dust mass exterior loop %s" % str(datetime.now() - now))
        return np.array(dust_sources), np.array(timescales), np.array(all_results)
Пример #4
0
 def test_graingrowth_turned_off(Self):
     dustmass = graingrowth(0,500,1.02e10,1e9,0.07,6.765e8,0.5)[0]
     assert dustmass == 0
Пример #5
0
 def test_dust_graingrowth(self):
     dust_ism = graingrowth(1,500,1.02e10,1e9,0.07,6.765e8,0.5)[0]
     assert  3.200e6 < dust_ism < 3.202e6
Пример #6
0
 def test_graingrowth_turned_off(Self):
     dustmass = graingrowth(0,500,1.02e10,1e9,0.07,6.765e8,0.5)[0]
     assert dustmass == 0
Пример #7
0
    def gas_metal_dust_mass(self, sn_rate):
        '''
        Calculates the gas, metal and dust mass from stars
        note mass is only ejected after stars die ie when
        t - taum (where taum is lifetime of star) > 0
        '''
        # initialize
        mg = self.gasmass_init
        mstars = 0
        md = 0
        md_all = 0
        md_stars = 0
        md_gg = 0
        metals = 0
        prev_t = 1e-3
        metals_pre = 0
        mstars_list = []
        z = []
        z_lookup = []
        sfr_list = []
        sfr_lookup = []
        all_results = []
        # Limit time to less than tend
        time = self.sfh[:,0]
        time = time[time < self.tend]
        now = datetime.now()
        # TIME integral
        for item, t in enumerate(time):
            r_sn = sn_rate [item]
            metallicity = metals/mg

            # start appending arrays for needing later
            z.append([t,metallicity])
            z_lookup = array(z)
            sfr_list.append([t,self.sfr(t)])
            sfr_lookup = array(sfr_list)

            '''
            STARS: dM_stars = sfr(t) * dt
            '''
            dmstars = self.sfr(t)

            '''
            GAS: dMg = (-sfr(t) + e(t) + inflows(t) - outflows(t)) * dt
            set up astration, inflow, outflow components
            '''
            gas_ast = self.sfr(t)
            gas_inf = inflows(self.sfr(t), self.inflows['xSFR'])
            gas_out = outflows(self.sfr(t), self.outflows['xSFR'])

            '''
            METALS: dMz = (-Z*sfr(t) + ez(t) + Z*inflows(t) - Z*outflows(t)) * dt
            set up astration, inflow and outflow components
            '''
            metals_ast = astration(metals,mg,self.sfr(t))
            if self.outflows['metals']:
                metals_out = metallicity*outflows(self.sfr(t), self.outflows['xSFR'])
            else:
                metals_out = 0.
            metals_inf = self.inflows['metals']*inflows(self.sfr(t), self.inflows['xSFR'])

            '''
            DUST: dMd = (-Md/Mg*sfr(t) + ed(t) + Md/Mg*inflows(t) - Md/Mg*outflows(t)
                         - (1-f)*Md/t_destroy + f(1-Md/Mg)*Md/t_graingrowth) * dt
            set up astration, inflows, outflows, destruction, grain growth components
            '''
            if self.outflows['dust']:
                mdust_out = (md/mg)*outflows(self.sfr(t), self.outflows['xSFR'])
            else:
                mdust_out = 0.
            mdust_inf = self.inflows['dust']*inflows(self.sfr(t), self.inflows['xSFR'])
            mdust_ast = astration(md,mg,self.sfr(t))

            mdust_gg, t_gg = graingrowth(self.choice_dust['gg'], self.epsilon,mg, self.sfr(t), metallicity, md, self.coldfraction)
            mdust_des, t_des = destroy_dust(self.choice_des, self.destroy_ism, mg, r_sn, md, self.coldfraction)

            '''
            Get ejected masses from stars when they die
            gas_ej = e(t): ejected gas mass from stars of mass m at t = taum
            metals_stars = ez(t): ejected metal mass from stars of mass m at t = taum (fresh + recycled)
            mdust_stars = ed(t): ejected dust mass from stars of mass m at t = taum (fresh + recycled)
            '''
            gas_ej, metals_stars, mdust_stars = \
                    mass_integral(self.choice_dust, self.reduce_sn, t, metallicity, sfr_lookup, z_lookup, self.imf)

            '''
            integrate over time for gas, metals and stars (mg, metals, md)
            '''
            dmg = -gas_ast + gas_ej + gas_inf - gas_out
            dmetals = -metals_ast + metals_stars + metals_pre + metals_inf - metals_out
            ddust = -mdust_ast + mdust_stars + mdust_inf - mdust_out + mdust_gg - mdust_des
            # dust_source_all separates out the dust sources (Md vs t) wihtout including sinks (Astration etc)
            # and grain growth separately (this is the Md vs time contributed by dust sources)
            dust_source_all = mdust_stars + mdust_gg
            dt = t - prev_t             # calculate  next time step
            prev_t = t
            mstars += dmstars*dt
            mg += dmg*dt # gas mass integral
            if mg <= 0:
                # exit program if all ISM removed
                print ('Oops you have no interstellar medium left')
                break
            metals += dmetals*dt # metal mass integral
            md += ddust*dt # dust mass integral
            md_all += dust_source_all*dt # dust mass sources integral
            md_gg += mdust_gg*dt # dust source from grain growth only
            md_stars += mdust_stars*dt # dust source from stars only
            Z = zip(*z_lookup) # write metallicity to an array
            s_f_r = zip(*sfr_lookup) # write SFR lookup array
            if mg <= 0. or metals <=0:  # write dust/metals ratio
                dust_to_metals = 0.
            else:
                dust_to_metals = md/metals
            all_results.append((t, mg, mstars, metals, metallicity, \
                                md, dust_to_metals, self.sfr(t)*1e-9, \
                                md_all, md_stars, md_gg, t_des, t_gg))
            # to test code kinks
        print("Gas, metal and dust mass exterior loop %s" % str(datetime.now()-now))
        return np.array(all_results)
Пример #8
0
 def test_dust_graingrowth(self):
     dust_ism = graingrowth(1, 500, 1.02e10, 1e9, 0.07, 3.765e8, 0.5,
                            0.6)[0]
     assert 3.202e7 < dust_ism < 4.7e7
Пример #9
0
    def gas_metal_dust_mass(self, sn_rate):
        '''
            Calculates the gas, metal and dust mass from stars
            note mass is only ejected after stars die ie when
            t - taum (where taum is lifetime of star) > 0
            '''
        # initialize
        mg = self.gasmass_init
        mstars = 0
        md = 0
        md_all = 0
        md_stars = 0
        md_gg = 0
        metals = 0
        prev_t = 1e-3
        metals_pre = 0
        mstars_list = []
        z = []
        z_lookup = []
        sfr_list = []
        sfr_lookup = []
        all_results = []
        oxymass = 0
        oxymass_pre = 0
        oxymass_pre = 0
        oxyz = []
        oxy_lookup = []
        # Limit time to less than tend
        time = self.sfh[:, 0]  # sfr is in units of Msun Gyr^-1
        time = time[time < self.tend]
        now = datetime.now()

        # TIME integral
        for item, t in enumerate(time):
            r_sn = sn_rate[item]
            metallicity = metals / mg
            oxy_metallicity = oxymass / mg
            # start appending arrays for needing later
            z.append([t, metallicity])
            z_lookup = array(z)
            oxyz.append([t, oxy_metallicity])
            oxy_lookup = array(oxyz)
            sfr_list.append([t, self.sfr(t)])
            sfr_lookup = array(sfr_list)

            # Now for setting up the components of the integrals
            # Stars, gas and dust
            '''
                GAS: dMg = (-sfr(t) + e(t) + inflows(t) - outflows(t)) * dt
                set up astration, inflow, outflow components
                '''
            gas_ast = self.sfr(t)  # gas lost due to astration
            # How much gas is lost or gained dure to outflows/inflows
            gas_inf,gas_out = gas_inandout(
                self.inflows['on'],\
                self.outflows['on'],\
                self.inflows['xSFR'],\
                self.sfr(t),\
                mstars)
            #    print 'time=',t,'sfr=',self.sfr(t)/1e9,'mstar=',mstars/1e10,'gas=','dust=',md_all/1e6,gas_out,gas_inf
            '''
                METALS: dMz = (-Z*sfr(t) + ez(t) + Z*inflows(t) - Z*outflows(t)) * dt
                set up astration, inflow and outflow components
                '''
            # metals lost due to astration
            metals_ast = astration(metals, mg, self.sfr(t))
            # do oxygen metals so we can have 12+log(O/H) later
            oxymass_ast = astration(oxymass, mg, self.sfr(t))
            # are outflows and inflows on (True) and if so what metal parameters needed?
            oxy_metal_inflow = 0.64 * self.inflows[
                'metals']  # fraction of total metals made up of oxygen
            metals_inf,metals_out,oxymass_inf,oxymass_out = metals_inandout(
                self.inflows['on'],\
                self.inflows['xSFR'],\
                self.inflows['metals'],\
                self.outflows['on'],\
                self.outflows['metals'],\
                self.sfr(t),\
                metallicity,\
                oxy_metallicity,\
                oxy_metal_inflow,\
                mstars)
            '''
                DUST: dMd = (-Md/Mg*sfr(t) + ed(t) + Md/Mg*inflows(t) - Md/Mg*outflows(t)
                             - (1-f)*Md/t_destroy + f(1-Md/Mg)*Md/t_graingrowth) * dt
                set up astration, inflows, outflows, destruction, grain growth components
                '''
            # are outflows and inflows on (True) and if so what dust parameters needed?

            mdust_inf,mdust_out = dust_inandout(
                self.inflows['on'],\
                self.inflows['xSFR'],\
                self.inflows['dust'],\
                self.outflows['on'],\
                self.outflows['dust'],\
                self.sfr(t),\
                (md/mg),
                mstars)

            mdust_ast = astration(md, mg, self.sfr(t))

            mdust_gg, t_gg = graingrowth(self.choice_dust['gg'],self.epsilon,mg, self.sfr(t), \
                metallicity, md, self.coldfraction)
            mdust_des, t_des = destroy_dust(self.destroy['on'], self.destroy['mass'], mg, r_sn, \
                md, self.coldfraction)
            '''
                Get ejected masses from stars when they die
                gas_ej = e(t): ejected gas mass from stars of mass m at t = taum
                metals_stars = ez(t): ejected metal mass from stars of mass m at t = taum (fresh + recycled)
                mdust_stars = ed(t): ejected dust mass from stars of mass m at t = taum (fresh + recycled)
                '''
            gas_ej, metals_stars, oxymass_stars, mdust_stars = \
                    mass_integral(self.choice_dust, self.delta_lims, self.reduce_sn, t, metallicity, sfr_lookup, z_lookup, oxy_lookup, self.imf)
            '''
                STARS: dM_stars = (sfr(t) - e(t) ) * dt
                '''
            dmstars = self.sfr(t) - gas_ej
            '''
                integrate over time for gas, metals and stars (mg, metals, md)
                all time units should be in Gyr or per Gyr
                '''
            dmg = -gas_ast + gas_ej + gas_inf - gas_out
            dmetals = -metals_ast + metals_stars + metals_pre + metals_inf - metals_out
            doxymass = -oxymass_ast + oxymass_stars + oxymass_pre + oxymass_inf - oxymass_out
            ddust = -mdust_ast + mdust_stars + mdust_inf - mdust_out + mdust_gg - mdust_des
            # dust_source_all separates out the dust sources (Md vs t) wihtout including sinks (Astration etc)
            # and grain growth separately (this is the Md vs time contributed by dust sources)
            dust_source_all = mdust_stars + mdust_gg
            dt = t - prev_t  # calculate  next time step
            prev_t = t
            mstars += dmstars * dt
            mg += dmg * dt  # gas mass integral
            if mg <= 0:
                # exit program if all ISM removed
                print('Oops you have no interstellar medium left')
                break
            metals += dmetals * dt  # metal mass integral
            oxymass += doxymass * dt  # oxygen mass integral
            md += ddust * dt  # dust mass integral
            md_all += dust_source_all * dt  # dust mass sources integral
            md_gg += mdust_gg * dt  # dust source from grain growth only
            md_stars += mdust_stars * dt  # dust source from stars only
            Z = zip(*z_lookup)  # write metallicity to an array
            s_f_r = zip(*sfr_lookup)  # write SFR lookup array
            if mg <= 0. or metals <= 0:  # write dust/metals ratio
                dust_to_metals = 0.
            else:
                dust_to_metals = md / metals
            all_results.append((t, mg, mstars, metals, metallicity, \
                                md, dust_to_metals, self.sfr(t)*1e-9, \
                                md_all, md_stars, md_gg, t_des, t_gg, oxymass))
        print("Gas, metal and dust mass exterior loop %s" %
              str(datetime.now() - now))
        return np.array(all_results)