def find_virial_radius(ds,center): z = ds.current_redshift co = Cosmology(hubble_constant=ds.hubble_constant, omega_matter=ds.omega_matter, omega_lambda=ds.omega_lambda, omega_curvature=0.0) rho_c = co.critical_density(z=z) r = 0 rs = [] densities = [] density = np.inf while density > 200*rho_c: r+=5 rs.append(r) sp = ds.sphere(center,(r,'kpc')) cell_mass,particle_mass = sp.quantities.total_mass() volume = 4/3*np.pi*ds.arr(r,'kpc')**3 new_density = (cell_mass+particle_mass)/volume if new_density > density: print('density not decreasing!') break density = new_density.in_units('g/cm**3') densities.append(density) toprint = (r,cell_mass+particle_mass,(cell_mass+particle_mass).units,particle_mass,particle_mass.units,cell_mass,cell_mass.units) rs = np.array(rs) densities = np.array(densities) Rvir = np.interp(200*rho_c,np.flip(densities),np.flip(rs)) Mvir = cell_mass+particle_mass return ds.arr(Rvir,'kpc'),ds.arr(Mvir,'g')
def find_radius_mass(m_r, delta, z=0.0, cosmo=None): """ Given a mass profile and an overdensity, find the radius and mass (e.g. M200, r200) Parameters ---------- m_r : RadialProfile The mass profile. delta : float The overdensity to compute the mass and radius for. z : float, optional The redshift of the halo formation. Default: 0.0 cosmo : yt ``Cosmology`` object The cosmology to be used when computing the critical density. If not supplied, a default one from yt will be used. """ from yt.utilities.cosmology import Cosmology from scipy.optimize import bisect if cosmo is None: cosmo = Cosmology() rho_crit = cosmo.critical_density(z).to_value("Msun/kpc**3") f = lambda r: 3.0*m_r(r)/(4.*np.pi*r**3) - delta*rho_crit r_delta = bisect(f, 0.01, 10000.0) return r_delta, m_r(r_delta)
def nfw_scale_density(conc, z=0.0, delta=200.0, cosmo=None): """ Compute a scale density parameter for an NFW profile given a concentration parameter, and optionally a redshift, overdensity, and cosmology. Parameters ---------- conc : float The concentration parameter for the halo, which should correspond the selected overdensity (which has a default of 200). z : float, optional The redshift of the halo formation. Default: 0.0 delta : float, optional The overdensity parameter for which the concentration is defined. Default: 200.0 cosmo : yt Cosmology object The cosmology to be used when computing the critical density. If not supplied, a default one from yt will be used. """ from yt.utilities.cosmology import Cosmology if cosmo is None: cosmo = Cosmology() rho_crit = cosmo.critical_density(z).to_value("Msun/kpc**3") rho_s = delta*rho_crit*conc**3*_nfw_factor(conc)/3. return rho_s
def _set_code_unit_attributes(self): # First try to set units based on parameter file if self.cosmological_simulation: mu = self.parameters.get("dMsolUnit", 1.0) self.mass_unit = self.quan(mu, "Msun") lu = self.parameters.get("dKpcUnit", 1000.0) # In cosmological runs, lengths are stored as length*scale_factor self.length_unit = self.quan(lu, "kpc") * self.scale_factor density_unit = self.mass_unit / (self.length_unit / self.scale_factor) ** 3 if "dHubble0" in self.parameters: # Gasoline's internal hubble constant, dHubble0, is stored in # units of proper code time self.hubble_constant *= np.sqrt(G * density_unit) # Finally, we scale the hubble constant by 100 km/s/Mpc self.hubble_constant /= self.quan(100, "km/s/Mpc") # If we leave it as a YTQuantity, the cosmology object # used below will add units back on. self.hubble_constant = self.hubble_constant.to_value("") else: mu = self.parameters.get("dMsolUnit", 1.0) self.mass_unit = self.quan(mu, "Msun") lu = self.parameters.get("dKpcUnit", 1.0) self.length_unit = self.quan(lu, "kpc") # If unit base is defined by the user, override all relevant units if self._unit_base is not None: for my_unit in ["length", "mass", "time"]: if my_unit in self._unit_base: my_val = self._unit_base[my_unit] my_val = ( self.quan(*my_val) if isinstance(my_val, tuple) else self.quan(my_val) ) setattr(self, f"{my_unit}_unit", my_val) # Finally, set the dependent units if self.cosmological_simulation: cosmo = Cosmology( hubble_constant=self.hubble_constant, omega_matter=self.omega_matter, omega_lambda=self.omega_lambda, ) self.current_time = cosmo.lookback_time(self.current_redshift, 1e6) # mass units are rho_crit(z=0) * domain volume mu = ( cosmo.critical_density(0.0) * (1 + self.current_redshift) ** 3 * self.length_unit ** 3 ) self.mass_unit = self.quan(mu.in_units("Msun"), "Msun") density_unit = self.mass_unit / (self.length_unit / self.scale_factor) ** 3 # need to do this again because we've modified the hubble constant self.unit_registry.modify("h", self.hubble_constant) else: density_unit = self.mass_unit / self.length_unit ** 3 if not hasattr(self, "time_unit"): self.time_unit = 1.0 / np.sqrt(density_unit * G)
def find_overdensity_radius(m, delta, z=0.0, cosmo=None): """ Given a mass value and an overdensity, find the radius that corresponds to that enclosed mass. Parameters ---------- m : float The enclosed mass. delta : float The overdensity to compute the radius for. z : float, optional The redshift of the halo formation. Default: 0.0 cosmo : yt ``Cosmology`` object The cosmology to be used when computing the critical density. If not supplied, a default one from yt will be used. """ from yt.utilities.cosmology import Cosmology if cosmo is None: cosmo = Cosmology() rho_crit = cosmo.critical_density(z).to_value("Msun/kpc**3") return (3.0*m/(4.0*np.pi*delta*rho_crit))**(1./3.)
proton_electron_mass_ratio = 1836. proton_mass = 1.67e-24 # g hubble_constant = 67.11 # H_0 in km / s / Mpc outer_scale_0_IGM = 1e6 # pc ## from Ryu+ 2008 ## global outer scale assumed to compute SM, choose other values by SM*L0**(-2/3) ## cosmic functions co = Cosmology(hubble_constant=h, omega_matter=omega_matter, omega_lambda=omega_lambda, omega_curvature=omega_curvature) comoving_radial_distance = co.comoving_radial_distance ## comoving distance z0 to z1 luminosity_distance = co.luminosity_distance ## proper distance z0 to z1 CriticalDensity = lambda redshift: co.critical_density(redshift).in_cgs( ).value * 1 critical_density = CriticalDensity(0) def GasDensity(z): return critical_density * omega_baryon * (1 + z)**3 ## redshift <-> time z_from_t = co.z_from_t t_from_z = co.t_from_z ## Geometry def GetDirection(x, y, z):