def inelastic_particles(particle0: Particle, particle1: Particle, dt: float): """ TODO extending for moveable walls Determines the resulting velocity of a set of colliding particles with mid-fram correction :param particle0: First particle in the collision :param particle1: Second particle in the collision """ # Determine mass ratios mass_ratio0 = 2 * particle1.mole.mass / (particle0.mole.mass + particle1.mole.mass) mass_ratio1 = 2 * particle0.mole.mass / (particle0.mole.mass + particle1.mole.mass) # generate relative terms X = particle0.x - particle1.x U = particle1.u - particle0.u R = particle0.mole.radius + particle1.mole.radius a = np.dot(U, U) b = 2*np.dot(X, U) c = np.dot(X, X) - R*R # Determine time of collision dt0 = (-b + np.sqrt(b*b - 4*a*c))/(2*a) x0 = particle0.x - particle0.u*dt0 x1 = particle1.x - particle1.u*dt0 u0 = particle0.u u1 = particle1.u # Direction magnitude dir_mag = np.dot(u0 - u1, x0 - x1) / (np.dot(x0 - x1, x0 - x1)) dir_vec = (x0 - x1) # Set new velocities particle0.u -= mass_ratio0 * dir_mag * dir_vec particle1.u -= mass_ratio1 * dir_mag * -dir_vec # Correct positions particle0.x = x0 + particle0.u * dt0 particle1.x = x1 + particle1.u * dt0
def inelastic_wall(wall: Wall, particle: Particle, dt: float): """ TODO extending for moveable walls Determines the resulting velocity of a particle bouncing off a wall, with mid-frame position correction :param wall: the wall object that may intersect the particle :param particle: the particle in the vicinity of the wall :param dt: length of the timestep :return: Boolean value of true if a collision occured """ x0 = particle.x u0 = particle.u x1 = wall.vert[0, :] p = x0 - x1 r = particle.mole.radius unit = wall.unit norm = wall.norm dis = np.dot(p, norm) # Determine if a collision actually occured if dis > r: return False #if norm_dir > 0: # return False # Decompose particles velocity normal and tangential to wall norm_dir = np.dot(u0, norm) nu = np.multiply(norm_dir, norm) uu = np.multiply(np.dot(u0, unit), unit) # Update velocity and position x0 -= u0 * dt dt0 = (np.abs(np.dot(x0 - x1, norm)) - r) / np.linalg.norm(nu) x0 += u0 * dt0 particle.u = uu - nu particle.x = x0 + particle.u*(dt - dt0) return True