Example #1
0
    def check_virial(self):
        r"""
        Computes the radial density profile for the collisionless 
        particles computed from integrating over the distribution 
        function, and the relative difference between this and the 
        input density profile.

        Returns
        -------
        rho : NumPy array
            The density profile computed from integrating the
            distribution function. 
        chk : NumPy array
            The relative difference between the input density
            profile and the one calculated using this method.
        """
        n = self.num_elements
        rho = np.zeros(n)
        pden = self.model[f"{self.ptype}_density"].d
        rho_int = lambda e, psi: self.f(e)*np.sqrt(2*(psi-e))
        for i, e in enumerate(self.ee):
            rho[i] = 4.*np.pi*quad(rho_int, 0., e, args=(e,))[0]
        chk = (rho[::-1]-pden)/pden
        mylog.info("The maximum relative deviation of this profile from "
                   "virial equilibrium is %g", np.abs(chk).max())
        return rho[::-1], chk
Example #2
0
 def check_model(self):
     n = len(self.ee)
     rho = np.zeros(n)
     rho_int = lambda e, psi: self.f(e)*np.sqrt(2*(psi-e))
     for i, e in enumerate(self.ee[::-1]):
         rho[i] = 4.*np.pi*quad(rho_int, 0., e, args=(e))[0]
     chk = np.abs(rho-self.pden)/self.pden
     mylog.info("The maximum relative deviation of this profile from "
                "virial equilibrium is %g" % np.abs(chk).max())
     return rho, chk
Example #3
0
 def _generate_df(self):
     pden = self.model[f"{self.ptype}_density"][::-1]
     density_spline = InterpolatedUnivariateSpline(self.ee, pden)
     g = np.zeros(self.num_elements)
     dgdp = lambda t, e: 2*density_spline(e-t*t, 1)
     pbar = tqdm(leave=True, total=self.num_elements,
                 desc="Computing particle DF ")
     for i in range(self.num_elements):
         g[i] = quad(dgdp, 0., np.sqrt(self.ee[i]), epsabs=1.49e-05,
                     epsrel=1.49e-05, args=(self.ee[i]))[0]
         pbar.update()
     pbar.close()
     g_spline = InterpolatedUnivariateSpline(self.ee, g)
     ff = g_spline(self.ee, 1)/(np.sqrt(8.)*np.pi**2)
     self.f = InterpolatedUnivariateSpline(self.ee, ff)
     self.df = unyt_array(ff[::-1], "Msun*Myr**3/kpc**6")
Example #4
0
    def __init__(self, num_particles, rr, gpot, pden, mdm):

        fields = OrderedDict()

        ee = gpot[::-1]
        density_spline = InterpolatedUnivariateSpline(ee, pden[::-1])
        energy_spline = InterpolatedUnivariateSpline(rr, gpot)

        num_points = gpot.shape[0]

        g = np.zeros(num_points)
        dgdp = lambda t, e: 2*density_spline(e-t*t, 1)
        pbar = get_pbar("Computing particle DF.", num_points)
        for i in range(num_points):
            g[i] = quad(dgdp, 0., np.sqrt(ee[i]), args=(ee[i]))[0]
            pbar.update(i)
        pbar.finish()
        g_spline = InterpolatedUnivariateSpline(ee, g)
        f = lambda e: g_spline(e, 1)/(np.sqrt(8.)*np.pi**2)

        self.ee = ee
        self.f = f
        self.rr = rr
        self.pden = pden

        mylog.info("We will be assigning %d particles." % num_particles)
        mylog.info("Compute particle positions.")

        u = np.random.uniform(size=num_particles)
        P_r = np.insert(mdm, 0, 0.0)
        P_r /= P_r[-1]
        radius = np.interp(u, P_r, np.insert(rr, 0, 0.0), left=0.0, right=1.0)

        theta = np.arccos(np.random.uniform(low=-1.,high=1.,size=num_particles))
        phi = 2.*np.pi*np.random.uniform(size=num_particles)

        fields["particle_radius"] = YTArray(radius, "kpc")
        fields["particle_position_x"] = YTArray(radius*np.sin(theta)*np.cos(phi), "kpc")
        fields["particle_position_y"] = YTArray(radius*np.sin(theta)*np.sin(phi), "kpc")
        fields["particle_position_z"] = YTArray(radius*np.cos(theta), "kpc")

        mylog.info("Compute particle velocities.")

        psi = energy_spline(radius)
        vesc = 2.*psi
        fv2esc = vesc*f(psi)
        vesc = np.sqrt(vesc)
        velocity = generate_velocities(psi, vesc, fv2esc, f)
        theta = np.arccos(np.random.uniform(low=-1.,high=1.,size=num_particles))
        phi = 2.*np.pi*np.random.uniform(size=num_particles)

        fields["particle_velocity"] = YTArray(velocity, "kpc/Myr")
        fields["particle_velocity_x"] = YTArray(velocity*np.sin(theta)*np.cos(phi), "kpc/Myr")
        fields["particle_velocity_y"] = YTArray(velocity*np.sin(theta)*np.sin(phi), "kpc/Myr")
        fields["particle_velocity_z"] = YTArray(velocity*np.cos(theta), "kpc/Myr")

        fields["particle_mass"] = YTArray([mdm.max()/num_particles], "Msun")
        fields["particle_potential"] = YTArray(psi, "kpc**2/Myr**2")
        fields["particle_energy"] = fields["particle_potential"]-0.5*fields["particle_velocity"]**2

        super(VirialEquilibrium, self).__init__(num_particles, fields, "spherical")