The purpose of this code is to watch particles of random positions and velocities interact with each other but after a while when particles are getting very fast they start passing inside each other without colliding. How Can I fix this problem?
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
class Particle:
def __init__(self, color, id=0, charge=1.602E-19, r=np.zeros(2), v=np.zeros(2), rad=0.01, m=1):
self.id = id
self.r = r # Set of the x and y coordinates of the particle
self.v = v # Set of the x and y velocities of the particle
self.rad = rad # Radius of the particle
self.m = m # Mass of the particle
self.charge = charge * (np.random.randint(0, 2) * 2 - 1) # Charge of the particle this will be used later
class Sim:
X=2 #size of the environment
Y=2
def __init__(self, dt=0.00005, Np=100):
self.dt = dt # Time jump between events
self.Np = Np # Number of particles
self.particles = [Particle(i) for i in range(Np)]
def coll_det(self):
for i, particle1 in enumerate(self.particles):
x, y = particle1.r
# Wall collision handling
if x - particle1.rad < -self.X / 2:
particle1.r[0] = -self.X / 2 + particle1.rad
particle1.v[0] *= -1 # reverse x-velocity component
elif x + particle1.rad > self.X / 2:
particle1.r[0] = self.X / 2 - particle1.rad
particle1.v[0] *= -1 # reverse x-velocity component
if y - particle1.rad < -self.Y / 2:
particle1.r[1] = -self.Y / 2 + particle1.rad
particle1.v[1] *= -1 # reverse y-velocity component
elif y + particle1.rad > self.Y / 2:
particle1.r[1] = self.Y / 2 - particle1.rad
particle1.v[1] *= -1 # reverse y-velocity component
for j, particle2 in enumerate(self.particles[i + 1:], start=i + 1):
m1, m2, r1, r2, v1, v2 = particle1.m, particle2.m, particle1.r, particle2.r, particle1.v, particle2.v
dist = np.linalg.norm(r1 - r2)
if dist <= particle1.rad + particle2.rad:
# Collision handling
n = (r1 - r2) / dist # Normal vector pointing from particle2 to particle1
v1_new = v1 - 2 * np.dot(v1 - v2, n) * n
v2_new = v2 - 2 * np.dot(v2 - v1, -n) * (-n)
particle1.v = v1_new
particle2.v = v2_new
# above is an attempt to make particles collide with each other some parts #are stolen from chat gpt
def increment(self):
self.coll_det()
for particle in self.particles:
particle.r += self.dt * particle.v # Euler's method to get positions, perhaps there #is a better way?
def particle_positions(self):
return [particle.r for particle in self.particles]
def particle_color(self):
return [particle.color for particle in self.particles]
sim = Sim()
for particle in sim.particles:
particle.r = np.random.uniform([-sim.X/2, -sim.Y/2], [sim.X/2, sim.Y/2], size=2) # first #positions
particle.v = np.array([np.random.uniform(50, -50), np.random.uniform(50, -50)])
#first velocities
sim.particles[0].color = "red"
fig, ax = plt.subplots()
scatter = ax.scatter([], [], s=0.01, alpha=0.5)
def init():
ax.set_xlim(-sim.X/2, sim.X/2)
ax.set_ylim(-sim.Y/2, sim.Y/2)
return scatter,
def update(frame):
sim.increment()
positions = sim.particle_positions()
ax.clear()
ax.set_xlim(-sim.X / 2, sim.X / 2)
ax.set_ylim(-sim.Y / 2, sim.Y / 2)
ax.scatter(*zip(*positions))
plt.pause(0.01) # Adjust pause time for better visualization
animation = FuncAnimation(fig, update, frames=12000, init_func=init)
#animation stuff which I have no idea on how it works
plt.show()
When particles starts moving faster because of the collisions they start moving without making collisions.