def test_destruction_turned_off(self): dustmass = destroy_dust(0,1000,4e10,0.006,1e5,0.5)[0] assert dustmass == 0
def test_dust_destruction(self): dust_sink = destroy_dust(1,1000.,1.02e10,6.66e6,6.765e08,0.5)[0] assert 2.02e8 < dust_sink < 2.29e8
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)
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)
def test_destruction_turned_off(self): dustmass = destroy_dust(0, 1000, 4e10, 0.006, 1e5, 0.5, 0.36)[0] assert dustmass == 0
def test_dust_destruction(self): # test dust destruction timescale is on and outputs expected values # for on,destruct,gasmass,supernova_rate,md,f_c; [0] ==> mdust_destroy dust_sink = destroy_dust(1, 1000., 1.02e10, 6.66e6, 6.765e08, 0.5)[0] assert 2.02e8 < dust_sink < 2.29e8
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)