示例#1
0
文件: group.py 项目: lq3552/caesar
    def _calculate_radial_quantities(self):
        """ Calculate various component radii and half radii """
        from caesar.group_funcs import get_half_mass_radius, get_full_mass_radius
        
        r = np.empty(len(self.global_indexes), dtype=np.float64)
        get_periodic_r(self.obj.simulation.boxsize.d, self.pos.d, self.obj.data_manager.pos[self.global_indexes], r)
        
        rsort = np.argsort(r)
        r     = r[rsort]
        mass  = self.obj.data_manager.mass[self.global_indexes][rsort]
        ptype = self.obj.data_manager.ptype[self.global_indexes][rsort]

        radial_categories = dict(
            total   = [ptype_ints['gas'],ptype_ints['star'],ptype_ints['dm'],ptype_ints['bh'],ptype_ints['dust']],
            baryon  = [ptype_ints['gas'],ptype_ints['star']],
            gas     = [ptype_ints['gas']],
            stellar = [ptype_ints['star']],
            dm      = [ptype_ints['dm']],
        )
        
        half_masses = {}
        for k,v in six.iteritems(self.masses):
            half_masses[k] = 0.5 * v            

        for k,v in six.iteritems(radial_categories):
            if k == 'dm' and self.obj_type == 'galaxy': continue
            binary = 0
            for p in v:
                binary += 2**p

            full_r = get_full_mass_radius(r[::-1], ptype[::-1], binary)
            self.radii[k] = self.obj.yt_dataset.quan(full_r, self.obj.units['length'])
            
            half_r = get_half_mass_radius(mass, r, ptype, half_masses[k], binary)
            self.radii['%s_half_mass' % k] = self.obj.yt_dataset.quan(half_r, self.obj.units['length'])
示例#2
0
文件: group.py 项目: lq3552/caesar
    def _calculate_center_of_mass_quantities(self):
        """Calculate center-of-mass position and velocity.  From caesar_mika """
        def get_center_of_mass_quantity(quantity):  ## REFACTOR ME TO BE MORE GENERIC WITH SHAPE
            val  = np.zeros(3)
            for i in range(0,3):
                quantity_arr = getattr(self.obj.data_manager, quantity)[self.global_indexes, i]
                weights      = self.obj.data_manager.mass[self.global_indexes]
                if (quantity=='pos'):# We need to be consistent with periodic boundaries
                    if (quantity_arr.max() - quantity_arr.min())>0.5*self.obj.simulation.boxsize.d:
                        theta_i          = 6.283185307179586*quantity_arr/self.obj.simulation.boxsize.d #(2pi)
                        Zeta_i           = np.cos(theta_i)
                        Xhi_i            = np.sin(theta_i)
                        Theta            = np.arctan2(-np.average(Xhi_i, weights=weights), -np.average(Zeta_i, weights=weights))+3.141592653589793
                        val[i]           = self.obj.simulation.boxsize.d*Theta/6.283185307179586
                    else: val[i]  = np.average(quantity_arr, weights=weights)
                else: val[i]  = np.average(quantity_arr, weights=weights)
            return val

        self.pos = self.obj.yt_dataset.arr(get_center_of_mass_quantity('pos'), self.obj.units['length'])
        self.vel = self.obj.yt_dataset.arr(get_center_of_mass_quantity('vel'), self.obj.units['velocity'])
        cmpos = (self.pos.to('kpc')).d
        ppos  = self.obj.yt_dataset.arr(self.obj.data_manager.pos[self.global_indexes], self.obj.units['length'])
        ppos  = (ppos.to('kpc')).d

        #Minimum potential position
        pot = self.obj.data_manager.pot[self.global_indexes]
        pos = self.obj.data_manager.pos[self.global_indexes]
        self.minpotpos = self.obj.yt_dataset.arr(pos[np.argmin(pot)], self.obj.units['length'])

        #Compute distances from the center of mass or minimum potential?
        self.periodic_r = np.empty(len(ppos), dtype=np.float64)
        #get_periodic_r(self.obj.simulation.boxsize.to('kpc').d, cmpos, ppos, self.periodic_r) # COM
        get_periodic_r(self.obj.simulation.boxsize.to('kpc').d, self.minpotpos.to('kpc').d, ppos, self.periodic_r) # minimum potential
        #Put the periodic_r for further use and not to compute it everytime
        self.periodic_r = self.obj.yt_dataset.arr(self.periodic_r, 'kpc')
示例#3
0
文件: group.py 项目: lq3552/caesar
    def _unbind(self):
        """Iterative procedure to unbind objects."""
        if not getattr(self.obj.simulation, 'unbind_%s' %
                       group_types[self.obj_type]):
            return

        if not hasattr(self, 'unbound_indexes'):
            self.unbound_indexes = {
                ptype_ints['gas']:[],
                ptype_ints['star']:[],
                ptype_ints['dm']:[],
                ptype_ints['bh']:[],
                ptype_ints['dust']:[],
            }
        if not hasattr(self, 'unbind_iterations'):
            self.unbind_iterations = 0        
        self.unbind_iterations += 1
        
        cmpos = (self.pos.to('kpc')).d
        ppos  = self.obj.yt_dataset.arr(self.obj.data_manager.pos[self.global_indexes], self.obj.units['length'])
        ppos  = (ppos.to('kpc')).d
        cmvel = (self.vel.to('kpc/s')).d
        pvels = self.obj.yt_dataset.arr(self.obj.data_manager.vel[self.global_indexes], self.obj.units['velocity'])
        pvels = (pvels.to('kpc/s')).d
        mass  = self.obj.yt_dataset.arr(self.obj.data_manager.mass[self.global_indexes], self.obj.units['mass'])
        mass  = (mass.to('Msun')).d

        init_mass = (self.masses['total'].to('Msun')).d

        r = np.empty(len(ppos), dtype=np.float64)
        get_periodic_r(self.obj.simulation.boxsize.d, cmpos, ppos, r)

        v2 = ( (pvels[:,0] - cmvel[0])**2 +
               (pvels[:,1] - cmvel[1])**2 +
               (pvels[:,2] - cmvel[2])**2 )
        
        energy = -(mass * self.obj.simulation.G.d * (init_mass - mass) / r) + (0.5 * mass * v2)

        positive = np.where(energy > 0)[0]
        if len(positive) > 0:
            positive = positive[::-1]
            for i in positive:
                global_index = self.global_indexes[i]
                self.unbound_indexes[self.obj.data_manager.ptype[global_index]].append(self.obj.data_manager.index[global_index])
                del self.global_indexes[i]

            self._assign_local_data()                        
            if not self._valid: return            
            self._calculate_total_mass()
            self._calculate_center_of_mass_quantities()
            self._unbind()