2 Drude model electron gas simulation
\r
10 import pygame #(Slow, but fast to code)
\r
13 scale = 20 #Scale in pixels per angstrom
\r
15 mass = {"proton": 10**4, "electron":1} #Masses normalised to electron mass
\r
16 charge = {"proton":+1, "electron":-1} #Charges normalised to fundamental charge
\r
17 k = 10**-3 #Coulomb constant (Supposed to be 10**-8 but I increased to speed things up)
\r
18 A = 10**-3 #Repulsion constant (Seems to work best when A = k. Completely arbitrarily chosen)
\r
19 m = 6 #Inverse power for the repulsion law (Fr = A/r^m). Completely arbitrarily chosen.
\r
24 """Class to represent a single classical particle"""
\r
25 def __init__(self, mass, charge, r):
\r
26 """Create a particle"""
\r
28 self.charge = charge
\r
29 self.r = r #Particle position (in angstrom)
\r
30 self.v = [0,0] #Particle velocity
\r
31 self.f = [0,0] #Net force acting on particle (note: recalculated every step)
\r
34 """Do a single step"""
\r
37 for i in range(0,2):
\r
38 self.v[i] += self.f[i] / self.mass
\r
41 for i in range(0,2):
\r
42 self.r[i] += self.v[i]
\r
45 #Note: Doesn't work if particle velocity is very big
\r
46 if self.r[0] <= 0 or self.r[0] >= 640:
\r
47 self.v[0] = -self.v[0]
\r
48 if self.r[1] <= 0 or self.r[1] >= 480:
\r
49 self.v[1] = -self.v[1]
\r
52 """Calculate the force between particles a and b (acting on a)"""
\r
53 r = [0,0] #Relative displacement of b to a
\r
54 for i in range(0,2):
\r
55 r[i] = b.r[i] - a.r[i]
\r
57 if r[0] == 0 and r[1] == 0: #To prevent divide by zero...
\r
60 distance = (r[0]**2 + r[1]**2)**(1/2)
\r
62 f = [0,0] #Calculated net force
\r
64 #Apply Coulomb force
\r
65 for i in range(0,2):
\r
66 f[i] -= r[i] * (k * a.charge * b.charge / (distance**3))
\r
68 #Apply generic Repulsive force
\r
69 for i in range(0,2):
\r
70 f[i] -= r[i] * (A / ((distance)**(m+1)))
\r
71 return [f[0], f[1]] #Return the resultant force
\r
73 def draw(self, window):
\r
74 """Draw the particle"""
\r
75 if self.charge == 1:
\r
76 colour = pygame.Color(255,0,0,1) #Protons are red
\r
78 elif self.charge == -1:
\r
79 colour = pygame.Color(0,0,255,1) #Electrons are blue
\r
81 elif self.charge == 0:
\r
82 colour = pygame.Color(255,255,255,1) #Neutrons are white
\r
85 colour = pygame.Color(0,255,0,1) #And I love you
\r
87 #(I don't really love you. Whoever you are).
\r
89 #Draw the most amazingly realistic depiction of a particle
\r
90 #The result of many years of research.
\r
91 pygame.draw.circle(window,colour,[int(self.r[0] * scale), int(self.r[1] * scale)],size,0)
\r
98 """Class to simulate THE UNIVERSE"""
\r
100 self.particles = [] #List of particles
\r
103 """Do a single step"""
\r
105 #Calculate force pairings
\r
106 for a in self.particles:
\r
108 for b in self.particles:
\r
110 fAB = particle.calcForce(a,b)
\r
111 for i in range(0,2):
\r
114 #for a in self.particles:
\r
117 def draw(self, window):
\r
118 for a in self.particles:
\r
121 def runSimulation():
\r
123 window = pygame.display.set_mode((640, 480))
\r
124 theUniverse = universe()
\r
131 window.fill(pygame.Color(0,0,0,0))
\r
132 theUniverse.draw(window)
\r
133 #Update draw events
\r
134 pygame.display.flip()
\r
136 #pygame.time.wait(1)
\r
138 for event in pygame.event.get():
\r
139 if event.type == pygame.QUIT:
\r
142 elif event.type == pygame.MOUSEBUTTONDOWN:
\r
143 mousestate = pygame.mouse.get_pressed()
\r
144 mousepos = pygame.mouse.get_pos()
\r
145 if mousestate[0] and mousestate[2] == False:
\r
146 theUniverse.particles.append(particle(mass["proton"],charge["proton"], [mousepos[0]/scale,mousepos[1]/scale]))
\r
147 elif mousestate[2] and mousestate[0] == False:
\r
148 theUniverse.particles.append(particle(mass["electron"],charge["electron"], [mousepos[0]/scale,mousepos[1]/scale]))
\r
156 if __name__ == "__main__":
\r