コード例 #1
0
def resample_one_cluster(particles, hse, center, velocity):
    """
    Resample radial profiles onto a single cluster's particle 
    distribution.

    Parameters
    ----------

    particles : :class:`~cluster_generator.particles.ClusterParticles`
    hse : 
    center : array_like
    velocity : array_like
    """
    if "gas" not in particles.particle_types:
        return particles
    center = ensure_ytarray(center, "kpc")
    velocity = ensure_ytarray(velocity, "kpc/Myr")
    r = ((particles["gas", "particle_position"]-center)**2).sum(axis=1).d
    np.sqrt(r, r)
    get_density = InterpolatedUnivariateSpline(hse["radius"], hse["density"])
    dens = get_density(r)
    e_arr = 1.5 * hse["pressure"] / hse["density"]
    get_energy = InterpolatedUnivariateSpline(hse["radius"], e_arr)
    particles["gas", "thermal_energy"] = unyt_array(get_energy(r), 
                                                    "kpc**2/Myr**2")
    vol = particles["gas", "particle_mass"] / particles["gas", "density"]
    particles["gas", "particle_mass"] = unyt_array(dens*vol.d, "Msun")
    particles["gas", "particle_velocity"][:,:] = velocity
    particles["gas", "density"] = unyt_array(dens, "Msun/kpc**3")
    return particles
コード例 #2
0
    def add_offsets(self, r_ctr, v_ctr, ptypes=None):
        """
        Add offsets in position and velocity to the cluster particles,
        which can be added to one or more particle types.

        Parameters
        ----------
        r_ctr : array-like
            A 3-element list, NumPy array, or unyt_array of the coordinates
            of the new center of the particle distribution. If units are not
            given, they are assumed to be in kpc.
        v_ctr : array-like
            A 3-element list, NumPy array, or unyt_array of the coordinates
            of the new bulk velocity of the particle distribution. If units 
            are not given, they are assumed to be in kpc/Myr.
        ptypes : string or list of strings, optional
            A single string or list of strings indicating the particle
            type(s) to be offset. Default: None, meaning all of the 
            particle types will be offset. This should not be used in
            normal circumstances.
        """
        if ptypes is None:
            ptypes = self.particle_types
        ptypes = ensure_list(ptypes)
        r_ctr = ensure_ytarray(r_ctr, "kpc")
        v_ctr = ensure_ytarray(v_ctr, "kpc/Myr")
        for ptype in ptypes:
            self.fields[ptype, "particle_position"] += r_ctr
            self.fields[ptype, "particle_velocity"] += v_ctr
コード例 #3
0
 def __init__(self,
              basename,
              num_halos,
              profiles,
              center,
              velocity,
              num_particles=None,
              mag_file=None,
              particle_files=None,
              r_max=20000.0):
     self.basename = basename
     self.num_halos = num_halos
     self.profiles = ensure_list(profiles)
     self.center = ensure_ytarray(center, "kpc")
     self.velocity = ensure_ytarray(velocity, "kpc/Myr")
     if self.num_halos == 1:
         self.center = self.center.reshape(1, 3)
         self.velocity = self.velocity.reshape(1, 3)
     self.mag_file = mag_file
     self.r_max = r_max
     if num_particles is None:
         self.tot_np = {"dm": 0, "gas": 0, "star": 0}
     else:
         self.tot_np = num_particles
     self._determine_num_particles()
     self.particle_files = [None] * 3
     if particle_files is not None:
         self.particle_files[:num_halos] = particle_files[:]
コード例 #4
0
    def add_black_hole(self, bh_mass, pos=None, vel=None,
                       use_pot_min=False):
        r"""
        Add a black hole particle to the set of cluster
        particles.

        Parameters
        ----------
        bh_mass : float
            The mass of the black hole particle in solar masses.
        pos : array-like, optional
            The position of the particle, assumed to be in units of
            kpc if units are not given. If use_pot_min=True this
            argument is ignored. Default: None, in which case the
            particle position is [0.0, 0.0, 0.0] kpc.
        vel : array-like, optional
            The velocity of the particle, assumed to be in units of
            kpc/Myr if units are not given. If use_pot_min=True this
            argument is ignored. Default: None, in which case the
            particle velocity is [0.0, 0.0, 0.0] kpc/Myr.
        use_pot_min : boolean, optional 
            If True, use the dark matter particle with the minimum
            value of the gravitational potential to determine the 
            position and velocity of the black hole particle. Default:
            False
        """
        mass = unyt_quantity(bh_mass, "Msun")
        self.fields["black_hole", "particle_mass"] = unyt_array(
            [bh_mass], "Msun")
        if use_pot_min:
            idx = np.argmin(self.fields["dm", "potential_energy"])
            pos = unyt_array(self.fields["dm", "particle_position"][idx]
                             ).reshape(1,3)
            vel = unyt_array(self.fields["dm", "particle_velocity"][idx]
                             ).reshape(1,3)
        else:
            if pos is None:
                pos = unyt_array(np.zeros((1, 3)), "kpc")
            if vel is None:
                vel = unyt_array(np.zeros((1, 3)), "kpc/Myr")
            pos = ensure_ytarray(pos, "kpc")
            vel = ensure_ytarray(vel, "kpc/Myr")
        if "black_hole" not in self.particle_types:
            self.particle_types.append("black_hole")
            self.fields["black_hole", "particle_position"] = pos
            self.fields["black_hole", "particle_velocity"] = vel
            self.fields["black_hole", "particle_mass"] = mass
        else:
            uappend = lambda x, y: unyt_array(np.append(x, y, axis=0).v,
                                              x.units)
            self.fields["black_hole", "particle_position"] = uappend(
                self.fields["black_hole", "particle_position"], pos)
            self.fields["black_hole", "particle_velocity"] = uappend(
                self.fields["black_hole", "particle_velocity"], vel)
            self.fields["black_hole", "particle_mass"] = uappend(
                self.fields["black_hole", "particle_mass"], mass)
        self._update_num_particles()
コード例 #5
0
def _sample_clusters(particles, hses, center, velocity,
                     radii=None, resample=False, 
                     passive_scalars=None):
    num_halos = len(hses)
    center = [ensure_ytarray(c, "kpc") for c in center]
    velocity = [ensure_ytarray(v, "kpc/Myr") for v in velocity]
    r = np.zeros((num_halos, particles.num_particles["gas"]))
    for i, c in enumerate(center):
        r[i,:] = ((particles["gas", "particle_position"]-c)**2).sum(axis=1).d
    np.sqrt(r, r)
    if radii is None:
        idxs = slice(None, None, None)
    else:
        radii = np.array(radii)
        idxs = np.any(r <= radii[:,np.newaxis], axis=0)
    d = np.zeros((num_halos, particles.num_particles["gas"]))
    e = np.zeros((num_halos, particles.num_particles["gas"]))
    m = np.zeros((num_halos, 3, particles.num_particles["gas"]))
    num_scalars = 0
    if passive_scalars is not None:
        num_scalars = len(passive_scalars)
        s = np.zeros((num_halos, num_scalars, particles.num_particles["gas"]))
    for i in range(num_halos):
        hse = hses[i]
        if "density" not in hse:
            continue
        get_density = InterpolatedUnivariateSpline(hse["radius"], hse["density"])
        d[i,:] = get_density(r[i,:])
        e_arr = 1.5*hse["pressure"]/hse["density"]
        get_energy = InterpolatedUnivariateSpline(hse["radius"], e_arr)
        e[i,:] = get_energy(r[i,:])*d[i,:]
        m[i,:,:] = velocity[i].d[:,np.newaxis]*d[i,:]
        if num_scalars > 0:
            for j, name in enumerate(passive_scalars):
                get_scalar = InterpolatedUnivariateSpline(hse["radius"], hse[name])
                s[i,j,:] = get_scalar(r[i,:])*d[i,:]
    dens = d.sum(axis=0)
    eint = e.sum(axis=0)/dens
    mom  = m.sum(axis=0)/dens
    if num_scalars > 0:
        ps = s.sum(axis=0)/dens
    if resample:
        vol = particles["gas", "particle_mass"]/particles["gas", "density"]
        particles["gas", "particle_mass"][idxs] = dens[idxs]*vol[idxs]
    particles["gas", "density"][idxs] = dens[idxs]
    particles["gas", "thermal_energy"][idxs] = eint[idxs]
    particles["gas", "particle_velocity"][idxs] = mom.T[idxs]
    if num_scalars > 0:
        for j, name in enumerate(passive_scalars):
            particles["gas", name][idxs] = ps[j,idxs]
    return particles
コード例 #6
0
def combine_three_clusters(particles1, particles2, particles3,
                           hse1, hse2, hse3, center1, center2,
                           center3, velocity1, velocity2,
                           velocity3):
    center1 = ensure_ytarray(center1, "kpc")
    center2 = ensure_ytarray(center2, "kpc")
    center3 = ensure_ytarray(center3, "kpc")
    velocity1 = ensure_ytarray(velocity1, "kpc/Myr")
    velocity2 = ensure_ytarray(velocity2, "kpc/Myr")
    velocity3 = ensure_ytarray(velocity3, "kpc/Myr")
    if "gas" in particles1.particle_types:
        particles1.add_offsets(center1, [0.0]*3, ptypes=["gas"])
    if "gas" in particles2.particle_types:
        particles2.add_offsets(center2, [0.0]*3, ptypes=["gas"])
    if "gas" in particles3.particle_types:
        particles3.add_offsets(center3, [0.0]*3, ptypes=["gas"])
    ptypes1 = particles1.particle_types.copy()
    ptypes2 = particles2.particle_types.copy()
    ptypes3 = particles3.particle_types.copy()
    if 'gas' in ptypes1:
        ptypes1.remove('gas')
    if 'gas' in ptypes2:
        ptypes2.remove('gas')
    if 'gas' in ptypes3:
        ptypes3.remove('gas')
    particles1.add_offsets(center1, velocity1, ptypes=ptypes1)
    particles2.add_offsets(center2, velocity2, ptypes=ptypes2)
    particles3.add_offsets(center3, velocity3, ptypes=ptypes3)
    particles = particles1+particles2+particles3
    if "gas" in particles.particle_types:
        particles = _sample_clusters(particles, [hse1, hse2, hse3],
                                     [center1, center2, center3],
                                     [velocity1, velocity2, velocity3])
    return particles