ETikhonov

Ideas Gas in box simulation

Sep 20th, 2014
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.10 KB | None | 0 0
  1. #!/usr/bin/env python3.3
  2. # -*- coding: utf8 -*-
  3.  
  4. from OpenGL.GL import *
  5. from OpenGL.GLU import *
  6. from OpenGL.GLUT import *
  7. import sys
  8. import numpy as np
  9. from scipy.spatial.distance import pdist, squareform
  10.  
  11. # Window size
  12. width = height = 720
  13. global axrng
  14. axrng = 1.0
  15.  
  16.  
  17. dt=0.001
  18. # Animation control and state
  19. global anim
  20. anim = 0
  21.  
  22. # FPS calculation
  23. global frameCount
  24. global previousTime
  25. PrintFPS = 1
  26. previousTime = 0
  27. frameCount = 0
  28.  
  29. def init():
  30.     glClearColor(0.0,0.0,0.0,1.0)
  31.     glOrtho(-axrng,axrng,-axrng,axrng,axrng,-axrng)
  32.  
  33. def idle():
  34.     global anim
  35.     if anim == 1:
  36.         if PrintFPS:
  37.             calculateFPS()
  38.         glutPostRedisplay()
  39.  
  40. def idle2():
  41.     global anim
  42.     if anim == 1:
  43.         glutPostRedisplay()
  44.  
  45. def calculateFPS():
  46.     global frameCount,previousTime
  47.     frameCount+=1
  48.     currentTime = glutGet(GLUT_ELAPSED_TIME);
  49.     timeInterval = currentTime - previousTime;
  50.     if timeInterval > 1000:
  51.         fps = frameCount / (timeInterval / 1000.)
  52.         previousTime = currentTime;
  53.         frameCount = 0;
  54.         print (fps)
  55.  
  56. def keyboard(key,x_,y_):
  57.     global anim
  58.     if key == (b'\x1b') or key == (b'q') :
  59.         sys.exit()
  60.     if key == (b'a'):
  61.         anim = 1
  62.     if key == (b's'):
  63.         anim = 0
  64.  
  65. def anim():
  66.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
  67.     Gas.draw()
  68.     Gas.step()
  69.     glutSwapBuffers()
  70.  
  71. def anim2():
  72.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
  73.     Gas.drawHIST()
  74.     glutSwapBuffers()
  75.  
  76. def reshape(w,h):
  77.     if h == 0:
  78.         h = 1
  79.     glViewport(0,0,w,h)
  80.     glMatrixMode(GL_PROJECTION)
  81.     glLoadIdentity()
  82.     if w <= h:
  83.         glOrtho(-axrng,axrng,-axrng*h/w,axrng*h/w,axrng,-axrng)
  84.     else:
  85.         glOrtho(-axrng*w/h,axrng*w/h,-axrng,axrng,axrng,-axrng)
  86.     glMatrixMode(GL_MODELVIEW)
  87.     glLoadIdentity()
  88.  
  89. def main():
  90.     glutInit(sys.argv)
  91.     glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH)
  92.     glutInitWindowPosition(0,0)
  93.     glutInitWindowSize(width,height)
  94.     glutCreateWindow(b'Particles in the box')
  95.     init()
  96.     glutReshapeFunc(reshape)
  97.     glutDisplayFunc(anim)
  98.     glutKeyboardFunc(keyboard)
  99.     glutIdleFunc(idle)
  100.     glutInitWindowPosition(720,0)
  101.     glutInitWindowSize(600,600)
  102.     glutCreateWindow(b'Speed distribution')
  103.     init()
  104.     glutDisplayFunc(anim2)
  105.     glutReshapeFunc(reshape)
  106.     glutIdleFunc(idle2)
  107.     glutMainLoop()
  108.  
  109. class gas:
  110.     def __init__(self,size):
  111.         self.time=0
  112.         self.size=size
  113.         self.rad=0.005
  114.         self.G=-9.8
  115.         self.state=np.random.random((self.size,4))
  116.         self.state[:,0:2]=-1+(2)*(self.state[:,0:2]-self.state[:,0.:2].max())/(-self.state[:,0.:2].max()-self.state[:,0.:2].min())
  117.         #self.state[:,2:4]=self.state[:,2:4]*20-10
  118.         self.state[:,2:4]=np.zeros(self.state[:,2:4].shape)
  119.     def drawHIST(self):
  120.         glPushMatrix()
  121.         glColor4f(1.0,1.0,1.0,0.5)
  122.         glBegin(GL_LINES)
  123.         glVertex2f(-axrng*0.95,-axrng*0.95)
  124.         glVertex2f(axrng*0.95,-axrng*0.95)
  125.         glVertex2f(-axrng*0.95,-axrng*0.95)
  126.         glVertex2f(-axrng*0.95,axrng*0.95)
  127.         glEnd()
  128.         glColor4f(0.0,0.0,1.0,0.5)
  129.         HISTarray,bins=np.histogram(np.sqrt(self.state[:,2:3]*self.state[:,2:3]+self.state[:,3:4]*self.state[:,3:4]),bins=self.size/25)
  130.         HISTarray=-axrng*0.95+(axrng*0.95+axrng*0.95)*(HISTarray-HISTarray.min())/(HISTarray.max()-HISTarray.min())
  131.         bins=-axrng*0.95+(axrng*0.95+axrng*0.95)*(bins-bins.min())/(bins.max()-bins.min())
  132.         width=bins[1]-bins[0]
  133.         glBegin(GL_QUADS)
  134.         for a in np.arange(len(HISTarray)):
  135.             glVertex2f(bins[a]-width/2,-axrng*0.95)
  136.             glVertex2f(bins[a]-width/2,HISTarray[a])
  137.             glVertex2f(bins[a]+width/2,HISTarray[a])
  138.             glVertex2f(bins[a]+width/2,-axrng*0.95)
  139.         glEnd()
  140.         glPopMatrix()
  141.         glutPostRedisplay()
  142.     def draw(self):
  143.         glPushMatrix()
  144.         glColor4f(1.0,1.0,1.0,0.5)
  145.         glEnable(GL_VERTEX_ARRAY)
  146.         glVertexPointer(2,GL_FLOAT,0,self.state[:,:2])
  147.         glDrawArrays(GL_POINTS,0,self.size)
  148.         glPopMatrix()
  149.     def step(self):
  150.         self.state[:,3:4]+=self.G/2*dt
  151.         self.state[:,2:3][ self.state[:,0:1]+self.state[:,2:3]*dt >= axrng ]*=-1.
  152.         self.state[:,2:3][ self.state[:,0:1]+self.state[:,2:3]*dt <=-axrng ]*=-1.
  153.         self.state[:,3:4][ self.state[:,1:2]+self.state[:,3:4]*dt >= axrng ]*=-1.
  154.         self.state[:,3:4][ self.state[:,1:2]+self.state[:,3:4]*dt <=-axrng ]*=-1.
  155.         self.state[:,0:1]+=self.state[:,2:3]*dt
  156.         self.state[:,1:2]+=self.state[:,3:4]*dt
  157.         self.state[:,3:4]+=self.G/2*dt
  158.         self.time+=dt
  159.         # Piece of collision detection code taken from internet
  160.         D = squareform(pdist(self.state[:, :2]))
  161.         ind1, ind2 = np.where(D < 2 * self.rad)
  162.         unique = (ind1 < ind2)
  163.         ind1 = ind1[unique]
  164.         ind2 = ind2[unique]
  165.          # update velocities of colliding pairs
  166.         for i1, i2 in zip(ind1, ind2):
  167.             # mass
  168.             # m1 = self.M[i1]
  169.             # m2 = self.M[i2]
  170.  
  171.             # location vector
  172.             r1 = self.state[i1, :2]
  173.             r2 = self.state[i2, :2]
  174.  
  175.             # velocity vector
  176.             v1 = self.state[i1, 2:]
  177.             v2 = self.state[i2, 2:]
  178.  
  179.             # relative location & velocity vectors
  180.             r_rel = r1 - r2
  181.             v_rel = v1 - v2
  182.  
  183.             # momentum vector of the center of mass
  184.             # v_cm = (m1 * v1 + m2 * v2) / (m1 + m2)
  185.             v_cm = (v1 + v2) / (2.)
  186.  
  187.             # collisions of spheres reflect v_rel over r_rel
  188.             rr_rel = np.dot(r_rel, r_rel)
  189.             vr_rel = np.dot(v_rel, r_rel)
  190.             v_rel = 2 * r_rel * vr_rel / rr_rel - v_rel
  191.  
  192.             # assign new velocities
  193.             self.state[i1, 2:] = v_cm + v_rel  / (2.)
  194.             self.state[i2, 2:] = v_cm - v_rel  / (2.)        
  195.         #print (str(self.time)+" "+str((self.state[:,2:3]*self.state[:,2:3]+self.state[:,3:4]*self.state[:,3:4]).sum()/2)+" "+str( (-self.G*self.state[:,1:2]).sum() ))
  196.  
  197. if __name__ == "__main__":
  198.     Gas = gas(1000)
  199.     main()
Advertisement
Add Comment
Please, Sign In to add comment