Example #1
0
 def combine_particles(self,particle1,particle2):
     #get phase space of new particle
     
     #delete collided particles in state and mass
     #add new particle in state and mass
     
     #nparticles -= 1 
     
     mass1 = self.masses[particle1]
     mass2 = self.masses[particle2]
     
     xd1 = self.state[particle1,1,0]
     yd1 = self.state[particle1,1,1]
     
     xd2 = self.state[particle2,1,0]
     yd2 = self.state[particle2,1,1]
     
     totalmass = mass1+mass2
     
     newxd = ((mass1*xd1) + (m2*xd2))/totalmass
     newyd = ((mass1*yd1) + (m2*yd2))/totalmass
     
     self.masses = np.delete(self.masses,[particle1,particle2],axis=0)
     
     new_phase_vector = [self.state[particle1,0,0],self.state[particle1,0,1],[newxd,newyd]]
     self.masses = np.append(self.masses,totalmass,axis=0)
     
     self.Nparticles -= 1
     
     return(new_phase_vector)
Example #2
0
 def UpdateStateVectorRK4(self,t):
     self.event_horizon = self.get_event_horizon(t)
     new_state = np.ndarray((self.Nparticles,2,2))
     
     for particle in xrange(self.Nparticles):
         kstate = np.copy(self.state)
         #do RK4 shit
         k1 = self.dt * self.SingleParticleDerivativeVector(kstate,particle, t+self.dt)
         kstate[particle] = np.copy(self.state[particle]) + k1/2
         k2 = self.dt * self.SingleParticleDerivativeVector(kstate,particle,t+(self.dt/2))
         kstate[particle] = np.copy(self.state[particle]) + k2/2
         k3 = self.dt * self.SingleParticleDerivativeVector(kstate,particle,t+(self.dt/2))
         kstate[particle] = np.copy(self.state[particle]) + k3
         k4 = self.dt * self.SingleParticleDerivativeVector(kstate,particle,t+self.dt)
         new_state[particle] = np.copy(self.state[particle]) + (1/3)*(k1/2 + k2 + k3 + k4/2)
         
     
     #Get rid of gobbled or ejected particles 
     if self.cleanup != []:
         for particle in self.cleanup:
             print("\n***particle {} shit the bed at step {}***".format(particle,int(t/self.dt)))
             self.remove_particle(particle)
             new_state = np.delete(new_state,particle,axis=0)
             print("***particle {} removed***".format(particle))
             self.cleanup.remove(particle)
             if self.cleanup == []:
                 print("***cleanup completed***")
     self.cleanup = []
     
     #Cleanup collided particles
     if self.collisions != {}:
         print("*****")
         for key in self.collisions:
             p1 = self.collisions[key][1][0]
             p2 = self.collisions[key][1][1]
             new_particle = self.combine_particles()
             print("***{} and {} collided at step{}***".format(p1,p2,int(t/self.dt)))
             new_state = np.delete(new_state,[self.collisions[key][0],self.collisions[1]],axis=0)
             new_state = np.append(new_state,new_particle,axis = 0)
         self.collisions = {}
     return(new_state)
Example #3
0
 def remove_particle(self,particle):
     self.state = np.delete(self.state,particle,axis=0)
     self.Nparticles -= 1
Example #4
0
 def remove_particle(self,particle):
     self.state = np.delete(self.state,self.cleanup,axis=0)
     for key in self.collision_dict:
         if particle in self.collision_dict[key][1]:
             self.collision_dict[key][1].remove(particle)
     self.Nparticles = len(self.state)
Example #5
0
    def UpdateStateVectorRK4(self,t):
        self.event_horizon = self.get_event_horizon(t)
        new_state = np.ndarray((self.Nparticles,2,3))
        
        for particle in xrange(self.Nparticles):

            kstate = np.copy(self.state)

            k1 = self.dt * self.SingleParticleDerivativeVector(kstate,particle, t)
            kstate[particle] = np.copy(self.state[particle]) + k1/2
            k2 = self.dt * self.SingleParticleDerivativeVector(kstate,particle,t+(self.dt/2))
            kstate[particle] = np.copy(self.state[particle]) + k2/2
            k3 = self.dt * self.SingleParticleDerivativeVector(kstate,particle,t+(self.dt/2))
            kstate[particle] = np.copy(self.state[particle]) + k3
            k4 = self.dt * self.SingleParticleDerivativeVector(kstate,particle,t+self.dt)
            new_state[particle] = np.copy(self.state[particle]) + (1/3)*(k1/2 + k2 + k3 + k4/2)
            
        
        #Get rid of gobbled or ejected particles 
        if self.cleanup != []:
            new_state = np.delete(new_state,self.cleanup,axis=0)
            self.remove_particle(particle)
            for particle in self.cleanup:
                print("\n***particle {} shit the bed at step {}***".format(particle,int(t/self.dt)))
                print("***particle {} removed***".format(particle))
                self.cleanup.remove(particle)
                if self.cleanup == []:
                	print("***cleanup completed***")
        self.cleanup = []
        
        
        big_particle_list = []
        big_vector_list = []
        new_masses_list = []
        
        

        #Cleanup collided particles
        if self.collisions == "inelastic":
            if self.collision_dict != {}:       
                for key in self.collision_dict:
                	particles = self.collision_dict[key][1]
                	m = 0
                	x = self.collision_dict[key][0][0]
                	y = self.collision_dict[key][0][1]
                	mvx = 0
                	mvy = 0
                	for particle in particles:
                	    m += self.masses[particle]
                	for particle in particles:
                	    mvx += (self.state[particle][1][0]*self.masses[particle])
                	    mvy += (self.state[particle][1][1]*self.masses[particle])
                	    big_particle_list.append(particle)
                	new_masses_list.append(m)
                new_particle = [[x,y],[mvx/m,mvy/m]]
                big_vector_list.append(new_particle)

                self.masses = np.delete(self.masses,big_particle_list,axis=0)
                self.masses = np.append(self.masses,np.array(new_masses_list),axis = 0)
                new_state = np.delete(new_state,big_particle_list,axis=0)
                new_state = np.append(new_state,np.array(big_vector_list),axis = 0)
                self.Nparticles = len(new_state)
                self.collision_dict = {}
                self.collided_particles = np.array([])
        
        elif self.collisions == 'elastic':
            
            distances = squareform(pdist(self.state[:,0,:]))
            ind1, ind2 = np.where(distances < 2 * self.collision_radius)
            unique = (ind1 < ind2)
            ind1 = ind1[unique]
            ind2 = ind2[unique]
            new_collisions = zip(ind1,ind2)
            for i in new_collisions:
            	if i not in self.old_collisions:
            		i1 = i[0]
            		i2 = i[1]
            		
                	m1 = self.masses[i1]
                	m2 = self.masses[i2]
                	
                	x1 = new_state[i1,0,0]
                	y1 = new_state[i1,0,1]
                	z1 = new_state[i2,0,3]
                	x2 = new_state[i2,0,0]
                	y2 = new_state[i2,0,1]
                	z2 = new_state[i2,0,2]
                	
                	x1d = new_state[i1,1,0]
                	y1d = new_state[i1,1,1]
                	z1d = new_state[i1,1,2]
                	x2d = new_state[i2,1,0]
                	y2d = new_state[i2,1,1]
                	z2d = new_state[i2,1,2]
                	
                	new_state[i1, 1] = [(x1d*(m1-m2) + 2*m2*x2d)/(m1+m2),
                	                    (y1d*(m1-m2) + 2*m2*y2d)/(m1+m2),
                	                    (z1d*(m1-m2) + 2*m2*z2d)/(m1+m2)]
                	new_state[i2, 1] = [(x2d*(m2-m1) + 2*m1*x1d)/(m1+m2),
                	                    (y2d*(m2-m1) + 2*m1*y1d)/(m1+m2),
                	                    (z2d*(m2-m1) + 2*m1*z1d)/(m1+m2)]
            self.old_collisions = new_collisions
        return(new_state)
Example #6
0
    def SingleParticleNewtonianForce(self, i, soi_radius, collision_radius):        
        forces = np.zeros([self.Nparticles,2])
        
        x1 = self.state[i,0,0]
        y1 = self.state[i,0,1]
        
        m1 = self.masses[i]
        collided1 = 0
        
        if self.interaction=='ClassicalNBody':

            xmin = x1-soi_radius
            xmax = x1+soi_radius
            ymin = y1-soi_radius
            ymax = y1+soi_radius
            sliced_indices_x = np.where(np.logical_and(self.state[:,0,0]>xmin,self.state[:,0,0]<xmax))
            sliced_indices_y = np.where(np.logical_and(self.state[:,0,1]>ymin,self.state[:,0,1]<ymax))
            sliced_indices = np.intersect1d(sliced_indices_x,sliced_indices_y)
            sliced_arr = self.state[sliced_indices]
        
            no_i_indices = np.where(np.logical_and(sliced_arr[:,0,0] == x1,sliced_arr[:,0,1]==y1))
            sliced_arr = np.delete(sliced_arr,no_i_indices,axis=0)
            sliced_masses = self.masses[sliced_indices]
            sliced_masses = np.delete(sliced_masses,no_i_indices,axis=0)
            
            distances2 = np.array(np.transpose(np.matrix((sliced_arr[:,0,0]-x1)**2+(sliced_arr[:,0,1]-y1)**2)))
        
            jforce = np.array(np.transpose(np.matrix(sliced_masses)))/distances2
            jforcedir = np.array(np.transpose(np.matrix([sliced_arr[:,0,0]-x1,sliced_arr[:,0,1]-y1])))/np.sqrt(distances2)
            forces = jforce*jforcedir
        

            for particle_num in xrange(self.Nparticles):
                if particle_num != i:
                	collided2 = 0
                	m2 = self.masses[particle_num]
                	x2 = self.state[particle_num,0,0]
                	y2 = self.state[particle_num,0,1]
                	distance2 = ((x2-x1)**2+(y2-y1)**2)
                	
                	"""
                	if the collision dict is empty, put in the two particles being evaluated.
                
                	if it's not empty, first search to see if the main particle is in there
                	if the main particle is in there, move on to the secondary
                	if the secondary particle is not in there, put it in the entry with the main particle
                	"""
                	if self.Nparticles == 2:
                	    if distance2>500000:
                	        print('\n',distance2)
                	        print(self.state)
                	        raise ValueError("it f****d the duck")
                	elif self.Nparticles == 1:
                	    raise ValueError("it shit the bed")
                	
                	if self.collisions != False and i not in self.cleanup and particle_num not in self.cleanup:
                	    if distance2 < collision_radius:
                	        if self.collision_dict == {}:
                	            self.collision_dict[0] = [(x1,y1),[i,particle_num]]
                	        else:
                	            i_val = farts.dict_check(self.collision_dict, i)
                	            keynum = max(self.collision_dict)+1
                	            if i_val == -1:
                	                self.collision_dict[keynum] = [(x1,y1),[i]]
                	                i_val = keynum
                	            elif farts.dict_check(self.collision_dict, particle_num) == -1:
                	                self.collision_dict[i_val][1].append(particle_num)

            return(np.sum(forces,axis=0))