python - Lennard Jones interaction between particles. Particles moving to one point -
import numpy np import random import pygame background_colour = (255,255,255) width, height = 300, 325 eps = 1 sigma = 1 dt = 0.05 class particle(): def __init__(self): self.x = random.uniform(0,400) self.y = random.uniform(0,500) self.vx = random.uniform(-.1,.1) self.vy = random.uniform(-.1,.1) self.fx = 0 self.fy = 0 self.m = 1 self.size = 10 self.colour = (0, 0, 255) self.thickness = 0 def bounce(self): if self.x > width - self.size: self.x = 2*(width - self.size) - self.x elif self.x < self.size: self.x = 2*self.size - self.x if self.y > height - self.size: self.y = 2*(height - self.size) - self.y elif self.y < self.size: self.y = 2*self.size - self.y def getforce(self, p2): dx = self.x - p2.x dy = self.y - p2.y self.fx = 500*(-8*eps*((3*sigma**6*dx/(dx**2+dy**2)**4 - 6*sigma**12*dx/(dx**2+dy**2)**7))) self.fy = 500*(-8*eps*((3*sigma**6*dy/(dx**2+dy**2)**4 - 6*sigma**12*dy/(dx**2+dy**2)**7))) return self.fx, self.fy def verletupdate(self,dt): self.x = self.x + dt*self.vx+0.5*dt**2*self.fx/self.m self.y = self.y + dt*self.vy+0.5*dt**2*self.fy/self.m def display(self): pygame.draw.circle(screen, self.colour, (int(self.x), int(self.y)), self.size, self.thickness) screen = pygame.display.set_mode((width, height)) screen.fill(background_colour) partlist = [] k in range(10): partlist.append(particle()) running = true while running: event in pygame.event.get(): if event.type == pygame.quit: running = false screen.fill(background_colour) k, particle in enumerate(partlist): p2 in partlist[k+1:]: particle.getforce(p2) particle.verletupdate(dt) particle.bounce() particle.display() pygame.display.flip() pygame.quit()
is code correct? tried simulate particles in 2d move lennard jones forces. think calculating forces works okay why particles moving 1 point? ocasionally error overflowerror: python int large convert c long
advice useful.
i can not comment on physics of simulation, far display concerned following observations:
your particles move 1 point because update condition x , y parameter in code in verletupdate
moving values beyond display area. values out of range of int() function causing error. can see statement:
def verletupdate(self,dt): self.x = self.x + dt*self.vx+0.5*dt**2*self.fx/self.m self.y = self.y + dt*self.vy+0.5*dt**2*self.fy/self.m print self.x print self.y
sample output:
290.034892392 9.98686293664 290.028208837 9.99352484332 -2.55451579742e+19 1.12437640586e+19
also saturate , iterations, update gets smaller , smaller:
def display(self): print ' %s + %s '%(self.x,self.y) pygame.draw.circle(screen, self.colour, (int(self.x), int(self.y)), self.size, self.thickness)
output:
10.0009120033 + 10.0042647307 10.0009163718 + 10.0000322065 10.0009120033 + 10.0042647307 10.0009163718 + 10.0000322065 ... 10.0009163718 + 10.0000322065 10.0009120033 + 10.0042647307 10.0009163718 + 10.0000322065
this why bounce functions , limit checking not working. , after lot of iterations on occasion self.x , self.y far exceeding limits of int()
.
the code seems fine, can rid of overflow error adding checks above draw line. instance initialized them randomly again simulate particle going off screen , tracking new one. feel free change it.
def display(self): if(self.x<0 or self.x>height): self.__init__() print "reset" if(self.y<0 or self.y>width): self.__init__() print "reset" print ' %s + %s '%(self.x,self.y) pygame.draw.circle(screen, self.colour, (int(self.x), int(self.y)), self.size, self.thickness)
also @ 1 point adress array [k+1:], , addressing 0 element caused divide 0 error. might want @ that.
Comments
Post a Comment