My Particle Simulation is Slow and After While Does not work as Intended

41 views Asked by At

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.

0

There are 0 answers