from scipy.integrate import odeint from nfw import NFW import cosmology from scipy.interpolate import interp1d from astropy.io import ascii ## Everything done in cgs units Gc = 6.67e-8 kB = 1.38e-16 kpc = 3.086e21 Msun = 2.e33 yr = 3.16e7 mp = 1.67e-24 cosm = cosmology.cosmology(h=.7, Om=.3, Ol=.7) nfw = NFW(1.e6, 25, None, cosm) #nfw = NFW(5.e5,20,None,cosm) tau_star = 3e6 * yr Tion = 3.e4 Tvir = nfw.Tvir cion = np.sqrt(kB * Tion / (0.59 * mp)) cvir = np.sqrt(kB * Tvir / (1.23 * mp)) Shu = ascii.read('Shu_data.tab') alpha_eps = interp1d(Shu['eps'], Shu['alpha0'], kind='quadratic') xsh_eps = interp1d(Shu['eps'], Shu['xs'], kind='quadratic') def ydot(y, x):
import sys sys.path.insert(0, "../../aum/install/lib64/python2.7/site-packages/") import numpy as np import cosmology as cc import pandas from scipy.interpolate import interp1d from scipy.interpolate import UnivariateSpline a = cc.cosmology(0.27, 0.0, -1.0, 0.0, 0.0476, 0.7, 2.726, 0.8, 0.96, np.log10(8.0), 1.0) def get_app_magnitude(z): return -18.93629 + 25.0 + 5.0 * np.log10(a.Dlofz(z)) def get_perturbed_magnitudes(): # Read the matched file for SDSS z and PS magnitudes df = pandas.read_csv( "/work/dominik.zuercher/Output/match_PS_GAMA/matched_spec_new.dat", delim_whitespace=1, usecols=(0, 3, 4, 5, 6), header=None, names=(["zred", "rPS", "gPS", "iPS", "blue"])) # Read in Dominik's median errors as a function of g band magnitude and then perturb gmag, gmag_err = np.loadtxt("/work/dominik.zuercher/g_band_error.txt", unpack=1) rmag, rmag_err = np.loadtxt("/work/dominik.zuercher/r_band_error.txt", unpack=1)
def sfrparams(envname,sfrname,verbose=False): try: name,ts = sfrname.split('TS') except ValueError: raise ValueError("Invalid sfrname: "+sfrname+" (requires 'TS' to denote tstop)") ts = int(ts) Mhalo,zvir,vturb,lturb,nSN,trecovery,Dt,uSN,E51 = bgm.envparams(envname) u0III = uSN ttIII = 100 if 'minihalo' in envname: ttII = ttIII + 10 elif 'atomiccoolinghalo' in envname: ttII = ttIII + 300 if 'burst' in sfrname: assert 'atomiccoolinghalo' in envname #ttIII = 100; ttII = 400; tburst = 50 if 'h14' in sfrname: assert 'minihalo' in envname zvir = bgm.envparams(envname)[1] c = cosmology.cosmology(Ol=0.7,Om=0.3,h=0.7) u0III = -1; ttIII = -1 #not used ttII = c.t_age(zvir) u0II = 0.4 #TODO I think this is the wrong way to proceed... if "fix" in sfrname: u0II = 0.4 elif "10x" in sfrname: u0II = 10*u0III elif "mhsim" in sfrname: u0II = 2.0 #100Msun with TS150 elif "achsim" in sfrname: u0II = 0.1 #10000Msun with TS500 elif "achslo" in sfrname: u0II = 0.01 #1000Msun with TS500 if 'u0IIMLT' in sfrname: pre,suf = sfrname.split('u0IIMLT') multfact = float(suf[0:2]) u0II *= multfact if 'u0IIDIV' in sfrname: pre,suf = sfrname.split('u0IIDIV') multfact = float(suf[0:2]) u0II /= multfact if 'u0IIIMLT' in sfrname: pre,suf = sfrname.split('u0IIIMLT') multfact = float(suf[0:2]) u0III *= multfact if 'u0IIIDIV' in sfrname: pre,suf = sfrname.split('u0IIIDIV') multfact = float(suf[0:2]) u0III /= multfact if 'betalogit' in sfrname: zvir = bgm.envparams(envname)[1] c = cosmology.cosmology(Ol=0.7,Om=0.3,h=0.7) ttIII = c.t_age(zvir)*1000. #tvir ttII = ttIII+trecovery # Normalize u0II based on total Pop II mass if 'minihalo' in envname: MpopII = 100. elif 'atomiccoolinghalo' in envname: MpopII = 10.**4 numtomass = 184. #assuming salpeter slope: th,Vmixfn = util.load_Vmix(envname,get_th=True) #just for th Rvir = th.Rvir logitfn = get_logitfn(ttIII,trecovery) myint = integrate.quad(logitfn,0,ts)[0] u0II = MpopII/(myint*(4*np.pi/3.)*Rvir**3*numtomass) u0III = nSN/(4*np.pi/3 * Rvir**3) if verbose: print name print "u0II %3.2e u0III %3.2e" % (u0II,u0III) print "ttII %i ttIII %i" % (tII,ttIII) print "ts %i" % (ts) return u0II,u0III,ttII,ttIII,ts
def __init__(self, Mvir, zvir, c=None, h=0.7, Om=0.3, Ol=0.7, Ob=0.05, L=L, n_flat=0.1, useiso=True, useflat=False, usechampagne=False, T0=10**4): self.R_SN = {} self.t_SN = {} self.Mvir = Mvir self.zvir = zvir self.c = c self.h = h self.Om = Om self.Ol = Ol self.Ob = Ob fb = Ob / Om self.fb = fb self.L = L # Set up cooling table coolingtable = 'cooling/m-30.cie' tab = ascii.read(coolingtable, header_start=1) _CoolingInt = interpolate.interp1d( np.concatenate(([3.93], tab['log(T)'])), np.concatenate(([-28], tab['log(lambda norm)']))) def _Cooling(logT): if logT <= (3.93 + .146128): return -28 # extrapolate at flat if logT > (8.5 + .146128): return -22.47 # extrapolate at flat return _CoolingInt(logT - .146128) def Cooling(T): # Tbar = 5/7 T_c logT = np.log10(np.ravel(T)) logT[~np.isfinite(logT)] = 3. return 10**ufunclike(_Cooling, logT) self._CoolingInt = _CoolingInt self._Cooling = _Cooling self.Cooling = Cooling # Set up ambient gas density/pressure cosm = cosmology.cosmology(Om=Om, Ol=Ol, h=h) self.cosm = cosm nfw = NFW.NFW(Mvir, zvir, c, cosm) self.nfw = nfw self.c = nfw.c Rvir = nfw.Rvir * nfw.kpc Tion = T0 #K rho_flat = n_flat * nfw.mbar if useiso: def n_iso(r): #r in cm return 10.**(-2 * np.log10(r / nfw.kpc) - 3) * nfw.Tvir / 1211. #scale by CM14 Tvir r_iso = 10**(-(np.log10(n_flat * 1211. / nfw.Tvir) + 3) / 2.) * nfw.kpc #cm def _rho0(r): #r in cm if r < r_iso: return rho_flat return n_iso(r) * nfw.mbar self.r_iso = r_iso self.n_iso = n_iso elif useflat: def _rho0(r): return rho_flat elif usechampagne: import champagne tau_1Myr = 1.e6 * 3.16e7 kB = 1.38e-16 cion = np.sqrt(kB * Tion / (0.59 * nfw.mp)) cdat = np.load('champagne.npy') c_x = cdat[:, 0] c_a = cdat[:, 1] c_narr = champagne.n_(c_a, tau_1Myr) tau_flat = np.sqrt(c_narr[0] / n_flat) * tau_1Myr print n_flat, tau_flat / tau_1Myr c_rarr = c_x * cion * tau_flat c_narr = champagne.n_(c_a, tau_flat) # extend down to r=0 at nflat c_rarr = np.concatenate([[0], c_rarr]) c_narr = np.concatenate([[c_narr[0]], c_narr]) c_interp = interpolate.interp1d(c_rarr, c_narr) c_rmax = c_rarr[-1] rhoIGM = cosm.rho_m(zvir) / 6. nIGM = rhoIGM / nfw.mbar rIGM = 10**( (np.log10(nIGM * 1211. / nfw.Tvir) + 3.) / -2.) * nfw.kpc self.rhoIGM = rhoIGM self.nIGM = nIGM self.rIGM = rIGM def n_iso(r): #r in cm return 10.**(-2 * np.log10(r / nfw.kpc) - 3) * nfw.Tvir / 1211. #scale by CM14 Tvir def _rho0(r): if r < c_rmax: return c_interp(r) * 0.59 * nfw.mp if r > rIGM: return rhoIGM return n_iso(r) * 0.59 * nfw.mp self.c_interp = c_interp self.c_rmax = c_rmax self.n_iso = n_iso else: rhoIGM = cosm.rho_m(zvir) / 6. def _rho0(r): #r in cm if r < Rvir: return rho_flat return (rho_flat - rhoIGM) * np.exp(-(r - Rvir) / (1.2 * Rvir)) + rhoIGM self.rhoIGM = rhoIGM def rho0(r): return ufunclike(_rho0, r) self.Rvir = Rvir self.Tion = Tion self.rho_flat = rho_flat self.n_flat = n_flat self.useiso = useiso self.usechampagne = usechampagne _rarr = np.arange(0, 300 * nfw.Rvir, .001)[1:] * nfw.kpc _rhoarr = rho0(_rarr) _rho0interp = interpolate.UnivariateSpline(_rarr, _rhoarr, s=0) _rho0pinterp = _rho0interp.derivative() _rho0parr = _rho0pinterp(_rarr) _rho0ratio = _rho0parr / _rhoarr _rho0ratiointerp = interpolate.UnivariateSpline(_rarr, _rho0ratio, s=0) def rho0ratio(r): return _rho0ratiointerp(r) #minrho0p = np.abs(np.min(np.diff(_rhoarr))/np.min(np.diff(_rarr))) #def _rho0p(r): # out = np.abs(_rho0pinterp(r)) # if out < minrho0p: return 0 # return out #def rho0p(r): #derivative of rho0 # return ufunclike(_rho0p,r) if useiso: def _P0(r): if r < r_iso: return rho0(r) * nfw.kB * Tion / nfw.mbar #ionized else: return rho0(r) * nfw.kB * nfw.Tvir / (1.23 * nfw.mp ) #neutral def P0(r): return ufunclike(_P0, r) self.cvir = np.sqrt(nfw.kB * nfw.Tvir / (1.23 * nfw.mp)) #cm/s self._P0 = _P0 self.P0 = P0 elif useflat: def P0(r): return rho0(r) * nfw.kB * Tion / nfw.mbar self.cvir = np.sqrt(nfw.kB * Tion / (1.23 * nfw.mp)) #cm/s self.P0 = P0 elif usechampagne: def _P0(r): return rho0(r) * nfw.kB * Tion / nfw.mbar #if r < c_rmax: return rho0(r)*nfw.kB*Tion/nfw.mbar #ionized #else: return rho0(r)*nfw.kB*nfw.Tvir/(1.23 * nfw.mp) #neutral def P0(r): return ufunclike(_P0, r) self.cvir = np.sqrt(nfw.kB * nfw.Tvir / (1.23 * nfw.mp)) #cm/s self._P0 = _P0 self.P0 = P0 else: def P0(r): #cgs: erg/cm^3 return rho0(r) * nfw.kB * Tion / nfw.mbar self.P0 = P0 self._rarr = _rarr self._rhoarr = _rhoarr self._rho0interp = _rho0interp self._rho0pinterp = _rho0pinterp self._rho0 = _rho0 self.rho0 = rho0 #self._rho0p = _rho0p; self.rho0p = rho0p self._rho0parr = _rho0parr self._rho0ratio = _rho0ratio self._rho0ratiointerp = _rho0ratiointerp self.rho0ratio = rho0ratio def Pb(E, R): return E / (2 * np.pi * R**3) def nbar(R, E, T): return 5. / 3 * self.Pb(E, R) / (self.nfw.kB * T) #5/3 n_c def vdot(y, t): #Rdotdot v, R, E, T = y return 3 * (Pb(E, R) - P0(R)) / ( R * rho0(R)) - 3 * v * v / R - v * v * rho0ratio( R) - nfw.Gc * nfw.Msun * nfw.Mltr(R / nfw.kpc) / (R**2) #def vdot(y,t): #if only including gravity from uniform gas, for useflat # v,R,E,T = y # return 3*(Pb(E,R)-P0(R))/(R*rho0(R)) - 3*v*v/R - v*v*rho0p(R)/rho0(R) - 4*np.pi*nfw.Gc*n_flat*1.23*nfw.mp*R/3 def Rdot(y, t): return y[0] def Edot(y, t): v, R, E, T = y return -4 * np.pi * R * R * Pb(E, R) * v + L( t) - (4 * np.pi * R**3 / 3) * (nbar(R, E, T)**2) * Cooling(T) eta = 6e-7 #cgs C1 = 16 * np.pi * nfw.mbar * eta / (25. * nfw.kB) C2 = 125 * np.pi * nfw.mbar / 39. def Tdot(y, t): v, R, E, T = y return 3 * T * v / R + T * Pdot(y, t) / Pb(E, R) - (2.3) * ( C1 / C2) * T**(4.5) * nfw.kB / (R * R * Pb(E, R)) def Pdot(y, t): v, R, E, T = y return Edot( y, t) / (2 * np.pi * R**3) - 3 * E * v / (2 * np.pi * R**4) def ydot(y, t): if y[0] <= 0: return [0, 0, 0, 0] return [vdot(y, t), Rdot(y, t), Edot(y, t), Tdot(y, t)] self.eta = eta self.C1 = C1 self.C2 = C2 self.Pb = Pb self.nbar = nbar self.vdot = vdot self.Rdot = Rdot self.Edot = Edot self.Tdot = Tdot self.Pdot = Pdot self.ydot = ydot
def rho(self, r): """ r in kpc, returns g/cc """ x = r / self.rs return self.rho0 / (x * (1.0 + x) ** 2) def Mltr(self, r): """ r in kpc, returns Msun """ return 4 * np.pi * self.rho0 * (self.rs * self.kpc) ** 3 * self.F(r / self.rs) / self.Msun def Vc(self, r): return self.Vvir * np.sqrt(self.F(r / self.rs) / (r / self.Rvir * self.F(self.c))) def Vesc(self, r): x = r / self.rs return np.sqrt(2) * self.Vvir * np.sqrt((self.F(x) + x / (1 + x)) / (r / self.Rvir * self.F(self.c))) def rho_isothermal(self, r): return np.exp( np.log(self.rhoiso0) - self.mbar * (1.0e10) * (self.Vesc0 ** 2 - self.Vesc(r) ** 2) / (2 * self.kB * self.Tvir) ) if __name__ == "__main__": cosm = cosmology.cosmology(Om=0.3, Ol=0.7, h=0.7) M = 10 ** 8 zvir = 9 c = 4.8 nfw = NFW(M, zvir, c, cosm)
import cosmology as c p=c.cosmo(); p.Om0=0.26; p.Omk=0.0; p.w0=-1.0; p.hval=0.72; p.Omb=0.0469; p.th=1.0093*2.7; p.s8=0.8; p.nspec=0.95; p.ximax=log10(8.0); p.cfac=1.0; cc=c.cosmology(p); ## Some standard paths and constants ################## ## Input foreground and background catalogs lenscatalog='../../catalogs/test_gal.txt' ##lenscatalog='../../catalogs/inp_gal_frg_cat_w2.txt' bkgqsocatalog="../../catalogs/inp_qso_bkg_cat.txt" bkggalcatalog="../../catalogs/inp_gal_bkg_cat.txt" ## Path to keeton's lensmodel executable lenscode="/home/anupreeta/soft/lensmodel" ## Constants gee=4.2994e-9; cspd=299792.458;
def compute_accretion_rates(mpi, path, datasets, data, snap=99, mcut=1.0e12): """ Compute the accretion rate based on different mass estimates """ if not mpi.Rank: print(" > Examining: {0}\n > Snap: {1:03d}".format(path, snap), flush=True) # First we need to find the halos of interest subfind_table = subfind_data.build_table(mpi, sim=path, snap=snap) subfind_table.select_halos(mpi, cut=mcut) if not mpi.Rank: print(" > Found {0:d} halo(s)".format(len(subfind_table.tags)), flush=True) # Now rebuild the trees for those halos if not mpi.Rank: print(" > Building merger tree for halos...", flush=True) Mtrees = tree_build.trees(mpi, path, subfind_table, snap) Mtrees.build_branches(mpi) # Initialize cosmology class instance cosmo = cosmology.cosmology( subfind_table.hub, subfind_table.omega_m, subfind_table.omega_L ) # Age of Universe at snapshots if not mpi.Rank: print(" > Computing mass accretion rates", flush=True) age_Gyr = cosmo.age(Mtrees.zred) # Now compute accretion rates for halos tdyn_500c_Gyr = cosmo.t_dynamic_Gyr(Mtrees.zred, delta=500.0, mode="CRIT") tdyn_200c_Gyr = cosmo.t_dynamic_Gyr(Mtrees.zred, delta=200.0, mode="CRIT") tdyn_200m_Gyr = cosmo.t_dynamic_Gyr(Mtrees.zred, delta=200.0, mode="MEAN") tdyn_vir_Gyr = cosmo.t_dynamic_Gyr(Mtrees.zred, mode="VIR") # Compute age of Universe one dynamical time ago for each snapshot dt_500c_Gyr = age_Gyr - tdyn_500c_Gyr dt_200c_Gyr = age_Gyr - tdyn_200c_Gyr dt_200m_Gyr = age_Gyr - tdyn_200m_Gyr dt_vir_Gyr = age_Gyr - tdyn_vir_Gyr # Delta log(a) of a dynamical time for all snapshots aexp_int = interp1d(age_Gyr, Mtrees.aexp, fill_value="extrapolate") Delta_lgAexp_500c = np.log(Mtrees.aexp) - np.log(aexp_int(dt_500c_Gyr)) Delta_lgAexp_200c = np.log(Mtrees.aexp) - np.log(aexp_int(dt_200c_Gyr)) Delta_lgAexp_200m = np.log(Mtrees.aexp) - np.log(aexp_int(dt_200m_Gyr)) Delta_lgAexp_vir = np.log(Mtrees.aexp) - np.log(aexp_int(dt_vir_Gyr)) # Now loop over haloes computing Delta log(M) -- with appropriate mass definition Delta_lgM500c = np.zeros(Mtrees.M500c.shape, dtype=np.float) Delta_lgM200c = np.zeros(Mtrees.M200c.shape, dtype=np.float) Delta_lgM200m = np.zeros(Mtrees.M200m.shape, dtype=np.float) Delta_lgMvir = np.zeros(Mtrees.Mvir.shape, dtype=np.float) for j in range(0, len(Mtrees.index), 1): lgM500c_int = interp1d( age_Gyr, np.log(Mtrees.M500c[j]), fill_value="extrapolate" ) lgM200c_int = interp1d( age_Gyr, np.log(Mtrees.M200c[j]), fill_value="extrapolate" ) lgM200m_int = interp1d( age_Gyr, np.log(Mtrees.M200m[j]), fill_value="extrapolate" ) lgMvir_int = interp1d(age_Gyr, np.log(Mtrees.Mvir[j]), fill_value="extrapolate") Delta_lgM500c[j] = np.log(Mtrees.M500c[j]) - lgM500c_int(dt_500c_Gyr) Delta_lgM200c[j] = np.log(Mtrees.M200c[j]) - lgM200c_int(dt_200c_Gyr) Delta_lgM200m[j] = np.log(Mtrees.M200m[j]) - lgM200m_int(dt_200m_Gyr) Delta_lgMvir[j] = np.log(Mtrees.Mvir[j]) - lgMvir_int(dt_vir_Gyr) # Now compute mass accretion rates Macc_500c = Delta_lgM500c / Delta_lgAexp_500c Macc_200c = Delta_lgM200c / Delta_lgAexp_200c Macc_200m = Delta_lgM200m / Delta_lgAexp_200m Macc_vir = Delta_lgMvir / Delta_lgAexp_vir # Store and return data["Halos"] = Mtrees.halos data["Indices"] = Mtrees.index data["Redshifts"] = Mtrees.zred data["Snapshots"] = Mtrees.snaps data["M200mean"] = Mtrees.M200m data["M200crit"] = Mtrees.M200c data["M500crit"] = Mtrees.M500c data["Mvir"] = Mtrees.Mvir data["Macc_500c"] = Macc_500c data["Macc_200c"] = Macc_200c data["Macc_200m"] = Macc_200m data["Macc_vir"] = Macc_vir del Mtrees return
""" r in kpc, returns g/cc """ x = r / self.rs return self.rho0 / (x * (1. + x)**2) def Mltr(self, r): """ r in kpc, returns Msun """ return 4 * np.pi * self.rho0 * (self.rs * self.kpc)**3 * self.F( r / self.rs) / self.Msun def Vc(self, r): return self.Vvir * np.sqrt( self.F(r / self.rs) / (r / self.Rvir * self.F(self.c))) def Vesc(self, r): x = r / self.rs return np.sqrt(2) * self.Vvir * np.sqrt( (self.F(x) + x / (1 + x)) / (r / self.Rvir * self.F(self.c))) def rho_isothermal(self, r): return np.exp( np.log(self.rhoiso0) - self.mbar * (1.e10) * (self.Vesc0**2 - self.Vesc(r)**2) / (2 * self.kB * self.Tvir)) if __name__ == "__main__": cosm = cosmology.cosmology(Om=.3, Ol=.7, h=.7) M = 10**8 zvir = 9 c = 4.8 nfw = NFW(M, zvir, c, cosm)
#!/usr/bin/env python import sys; import os; pwd=os.getcwd() f=open("configfile"); for line in f: linecont=line.strip("\n")[1:]; sys.path.append(linecont); import cosmology as c; aa=c.cosmology(); print aa.nofm(1E10,0.1); print aa.nofm(1E10,0.5); print "NOTE: If the code printed out: " print "1.94184058513e-11" print "2.02622771397e-11" print "The code is properly setup" print "Checking that both comoving distances are equal" print "Chi(3.035):",aa.Chiofz(3.035),"Chi_num(3.035):",aa.Chiofz_num(3.035); print "Chi(5.012):",aa.Chiofz(5.012),"Chi_num(5.012):",aa.Chiofz_num(5.012); print "\n" print "#######################################################" print "USE THE FOLLOWING LINES TO REPLACE THE INPUT*.PY FILES IN CLUS_LENS and GAL_LENS" print "################"
from scipy.integrate import odeint from nfw import NFW import cosmology from scipy.interpolate import interp1d from astropy.io import ascii ## Everything done in cgs units Gc = 6.67e-8 kB = 1.38e-16 kpc = 3.086e21 Msun= 2.e33 yr = 3.16e7 mp = 1.67e-24 cosm = cosmology.cosmology(h=.7,Om=.3,Ol=.7) nfw = NFW(1.e6,25,None,cosm) #nfw = NFW(5.e5,20,None,cosm) tau_star = 3e6 * yr Tion = 3.e4 Tvir = nfw.Tvir cion = np.sqrt(kB*Tion/(0.59 * mp)) cvir = np.sqrt(kB*Tvir/(1.23 * mp)) Shu = ascii.read('Shu_data.tab') alpha_eps = interp1d(Shu['eps'],Shu['alpha0'],kind='quadratic') xsh_eps = interp1d(Shu['eps'],Shu['xs'],kind='quadratic') def ydot(y,x): a,v = y
#!/usr/bin/env python import sys import os pwd = os.getcwd() f = open("configfile") for line in f: linecont = line.strip("\n")[1:] sys.path.append(linecont) import cosmology as c aa = c.cosmology() print aa.nofm(1E10, 0.1) print aa.nofm(1E10, 0.5) print "NOTE: If the code printed out: " print "1.94184058513e-11" print "2.02622771397e-11" print "The code is properly setup" print "Checking that both comoving distances are equal" print "Chi(3.035):", aa.Chiofz(3.035), "Chi_num(3.035):", aa.Chiofz_num(3.035) print "Chi(5.012):", aa.Chiofz(5.012), "Chi_num(5.012):", aa.Chiofz_num(5.012) print "\n" print "#######################################################" print "USE THE FOLLOWING LINES TO REPLACE THE INPUT*.PY FILES IN CLUS_LENS and GAL_LENS" print "################"
def __init__(self,Mvir,zvir,c=None,h=0.7,Om=0.3,Ol=0.7,Ob=0.05, L=L,n_flat=0.1,useiso=True,useflat=False,usechampagne=False,T0 = 10**4): self.R_SN = {} self.t_SN = {} self.Mvir = Mvir; self.zvir = zvir; self.c = c self.h = h; self.Om = Om; self.Ol = Ol; self.Ob = Ob fb = Ob/Om; self.fb = fb self.L = L # Set up cooling table coolingtable = 'cooling/m-30.cie' tab = ascii.read(coolingtable,header_start=1) _CoolingInt = interpolate.interp1d(np.concatenate(([3.93],tab['log(T)'])),np.concatenate(([-28],tab['log(lambda norm)']))) def _Cooling(logT): if logT<=(3.93+.146128): return -28 # extrapolate at flat if logT>(8.5+.146128): return -22.47 # extrapolate at flat return _CoolingInt(logT-.146128) def Cooling(T): # Tbar = 5/7 T_c logT = np.log10(np.ravel(T)) logT[~np.isfinite(logT)] = 3. return 10**ufunclike(_Cooling,logT) self._CoolingInt=_CoolingInt; self._Cooling = _Cooling; self.Cooling = Cooling # Set up ambient gas density/pressure cosm = cosmology.cosmology(Om=Om,Ol=Ol,h=h); self.cosm = cosm nfw = NFW.NFW(Mvir,zvir,c,cosm); self.nfw = nfw self.c = nfw.c Rvir = nfw.Rvir * nfw.kpc Tion = T0 #K rho_flat = n_flat*nfw.mbar if useiso: def n_iso(r): #r in cm return 10.**(-2*np.log10(r/nfw.kpc) - 3) * nfw.Tvir/1211. #scale by CM14 Tvir r_iso = 10**(-(np.log10(n_flat*1211./nfw.Tvir)+3)/2.)*nfw.kpc #cm def _rho0(r): #r in cm if r < r_iso: return rho_flat return n_iso(r)*nfw.mbar self.r_iso = r_iso; self.n_iso = n_iso elif useflat: def _rho0(r): return rho_flat elif usechampagne: import champagne tau_1Myr = 1.e6 * 3.16e7 kB = 1.38e-16 cion = np.sqrt(kB*Tion/(0.59 * nfw.mp)) cdat = np.load('champagne.npy') c_x = cdat[:,0]; c_a = cdat[:,1] c_narr = champagne.n_(c_a,tau_1Myr) tau_flat = np.sqrt(c_narr[0]/n_flat) * tau_1Myr print n_flat,tau_flat/tau_1Myr c_rarr = c_x * cion * tau_flat c_narr = champagne.n_(c_a,tau_flat) # extend down to r=0 at nflat c_rarr = np.concatenate([[0],c_rarr]) c_narr = np.concatenate([[c_narr[0]],c_narr]) c_interp = interpolate.interp1d(c_rarr,c_narr) c_rmax = c_rarr[-1] rhoIGM = cosm.rho_m(zvir)/6. nIGM = rhoIGM/nfw.mbar rIGM = 10**((np.log10(nIGM*1211./nfw.Tvir)+3.)/-2.)*nfw.kpc self.rhoIGM = rhoIGM; self.nIGM = nIGM; self.rIGM = rIGM def n_iso(r): #r in cm return 10.**(-2*np.log10(r/nfw.kpc) - 3) * nfw.Tvir/1211. #scale by CM14 Tvir def _rho0(r): if r < c_rmax: return c_interp(r)*0.59*nfw.mp if r > rIGM: return rhoIGM return n_iso(r)*0.59*nfw.mp self.c_interp = c_interp; self.c_rmax = c_rmax self.n_iso = n_iso else: rhoIGM = cosm.rho_m(zvir)/6. def _rho0(r): #r in cm if r < Rvir: return rho_flat return (rho_flat-rhoIGM)*np.exp(-(r-Rvir)/(1.2*Rvir))+rhoIGM self.rhoIGM = rhoIGM def rho0(r): return ufunclike(_rho0,r) self.Rvir = Rvir; self.Tion = Tion self.rho_flat = rho_flat; self.n_flat = n_flat self.useiso = useiso self.usechampagne = usechampagne _rarr = np.arange(0,300*nfw.Rvir,.001)[1:]*nfw.kpc _rhoarr = rho0(_rarr) _rho0interp = interpolate.UnivariateSpline(_rarr, _rhoarr, s=0) _rho0pinterp= _rho0interp.derivative() _rho0parr = _rho0pinterp(_rarr) _rho0ratio = _rho0parr/_rhoarr _rho0ratiointerp = interpolate.UnivariateSpline(_rarr, _rho0ratio, s=0) def rho0ratio(r): return _rho0ratiointerp(r) #minrho0p = np.abs(np.min(np.diff(_rhoarr))/np.min(np.diff(_rarr))) #def _rho0p(r): # out = np.abs(_rho0pinterp(r)) # if out < minrho0p: return 0 # return out #def rho0p(r): #derivative of rho0 # return ufunclike(_rho0p,r) if useiso: def _P0(r): if r < r_iso: return rho0(r)*nfw.kB*Tion/nfw.mbar #ionized else: return rho0(r)*nfw.kB*nfw.Tvir/(1.23 * nfw.mp) #neutral def P0(r): return ufunclike(_P0,r) self.cvir = np.sqrt(nfw.kB * nfw.Tvir / (1.23 * nfw.mp)) #cm/s self._P0 = _P0; self.P0 = P0 elif useflat: def P0(r): return rho0(r)*nfw.kB*Tion/nfw.mbar self.cvir = np.sqrt(nfw.kB * Tion / (1.23 * nfw.mp)) #cm/s self.P0 = P0 elif usechampagne: def _P0(r): return rho0(r)*nfw.kB*Tion/nfw.mbar #if r < c_rmax: return rho0(r)*nfw.kB*Tion/nfw.mbar #ionized #else: return rho0(r)*nfw.kB*nfw.Tvir/(1.23 * nfw.mp) #neutral def P0(r): return ufunclike(_P0,r) self.cvir = np.sqrt(nfw.kB * nfw.Tvir / (1.23 * nfw.mp)) #cm/s self._P0 = _P0; self.P0 = P0 else: def P0(r): #cgs: erg/cm^3 return rho0(r)*nfw.kB*Tion/nfw.mbar self.P0 = P0 self._rarr = _rarr; self._rhoarr = _rhoarr self._rho0interp = _rho0interp; self._rho0pinterp = _rho0pinterp self._rho0 = _rho0; self.rho0 = rho0 #self._rho0p = _rho0p; self.rho0p = rho0p self._rho0parr = _rho0parr self._rho0ratio = _rho0ratio self._rho0ratiointerp = _rho0ratiointerp self.rho0ratio = rho0ratio def Pb(E,R): return E/(2*np.pi*R**3) def nbar(R,E,T): return 5./3 * self.Pb(E,R)/(self.nfw.kB * T) #5/3 n_c def vdot(y,t): #Rdotdot v,R,E,T = y return 3*(Pb(E,R)-P0(R))/(R*rho0(R)) - 3*v*v/R - v*v*rho0ratio(R) - nfw.Gc*nfw.Msun*nfw.Mltr(R/nfw.kpc)/(R**2) #def vdot(y,t): #if only including gravity from uniform gas, for useflat # v,R,E,T = y # return 3*(Pb(E,R)-P0(R))/(R*rho0(R)) - 3*v*v/R - v*v*rho0p(R)/rho0(R) - 4*np.pi*nfw.Gc*n_flat*1.23*nfw.mp*R/3 def Rdot(y,t): return y[0] def Edot(y,t): v,R,E,T = y return -4*np.pi*R*R*Pb(E,R)*v +L(t) - (4*np.pi*R**3/3)*(nbar(R,E,T)**2)*Cooling(T) eta=6e-7 #cgs C1 = 16*np.pi*nfw.mbar*eta/(25.*nfw.kB) C2 = 125*np.pi*nfw.mbar/39. def Tdot(y,t): v,R,E,T = y return 3*T*v/R + T*Pdot(y,t)/Pb(E,R) - (2.3)*(C1/C2)*T**(4.5)*nfw.kB/(R*R*Pb(E,R)) def Pdot(y,t): v,R,E,T = y return Edot(y,t)/(2*np.pi*R**3) - 3*E*v/(2*np.pi*R**4) def ydot(y,t): if y[0] <= 0: return [0,0,0,0] return [vdot(y,t),Rdot(y,t),Edot(y,t),Tdot(y,t)] self.eta = eta; self.C1 = C1; self.C2 = C2 self.Pb = Pb; self.nbar = nbar self.vdot = vdot; self.Rdot = Rdot; self.Edot = Edot self.Tdot = Tdot; self.Pdot = Pdot self.ydot = ydot