Skip to content

Instantly share code, notes, and snippets.

@rameshvarun
Last active August 29, 2015 13:59
Show Gist options
  • Save rameshvarun/10702135 to your computer and use it in GitHub Desktop.
Save rameshvarun/10702135 to your computer and use it in GitHub Desktop.

Point Charges Simulator

Basic program for simulating the motion of three point charges.

Example Graph

Config Dialog

from Tkinter import *
import sys
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
K = 8.9875517873681764 * (10 ** 9)
class Particle:
def __init__(self):
self.x = []
self.y = []
#Pushes position into vector (so it can be graphed with respect to time)
def push_position(self):
self.x.append(self.position[0])
self.y.append(self.position[1])
#Use the position of all of the particles to calculate the current particle's position
def calc_velocity(self, particles, dt):
#Start with empty net force
net_force = [0,0]
for particle in particles:
if particle != self:
r = np.subtract(self.position, particle.position)
r_mag = np.linalg.norm(r)
r_hat = np.divide(r, r_mag)
magnitude = (K*particle.charge*self.charge)/(r_mag ** 2)
force = np.multiply(magnitude, r_hat)
net_force = np.add(net_force, force)
acceleration = np.divide( net_force, self.mass)
self.velocity = np.add( self.velocity, np.multiply( acceleration, dt) )
def calc_position(self, dt):
self.position = np.add(self.position, np.multiply( self.velocity, dt) )
def step(particles, dt):
for p in particles: p.push_position()
for p in particles: p.calc_velocity(particles, dt)
for p in particles: p.calc_position(dt)
def to_vector(str):
vector = [0,0]
components = str.split(',')
for i in range(len(vector)):
vector[i] = float(components[i])
return vector
if __name__ == "__main__":
#Create gui for configuring particles
gui = Tk()
gui.title("Particle Configuration")
configs = []
grid_row = 0
def make_particle_config(particle_name, inital_position, initial_velocity, initial_mass, initial_charge):
global grid_row
config_frame = Frame(gui, borderwidth=5, relief=GROOVE)
config_frame.grid(row=grid_row,padx=10, pady=10)
grid_row = grid_row + 1
Label(config_frame, text=particle_name).grid(row=0, column=0, sticky=W)
Label(config_frame, text="Position (m):").grid(row=1, column=0)
position_entry = Entry(config_frame)
position_entry.grid(row=1, column=1)
position_entry.insert(0, inital_position)
Label(config_frame, text="Velocity (m/s):").grid(row=2, column=0)
velocity_entry = Entry(config_frame)
velocity_entry.grid(row=2, column=1)
velocity_entry.insert(0,initial_velocity)
Label(config_frame, text="Mass (kg):").grid(row=3, column=0)
mass_entry = Entry(config_frame)
mass_entry.grid(row=3, column=1)
mass_entry.insert(0, initial_mass)
Label(config_frame, text="Charge (C):").grid(row=4, column=0)
charge_entry = Entry(config_frame)
charge_entry.grid(row=4, column=1)
charge_entry.insert(0, initial_charge)
def get_particle():
particle = Particle()
particle.name = particle_name
particle.position = to_vector(position_entry.get())
particle.velocity = to_vector(velocity_entry.get())
particle.mass = float(mass_entry.get())
particle.charge = float(charge_entry.get())
return particle
configs.append(get_particle)
make_particle_config("Particle A", "0,0", "0,0", "1.67262178e-31", "1.6021766e-19")
make_particle_config("Particle B", "1,0", "0,10", "9.10938291e-31", "-1.6021766e-19")
make_particle_config("Particle C", "-1,0", "0,-10", "9.10938291e-31", "-1.6021766e-19")
settings_frame = Frame(gui)
settings_frame.grid(row=grid_row,padx=10, pady=10)
#Time Step Entry
Label(settings_frame, text="Time Step (sec):").grid(row=0, column=0)
timestep_entry = Entry(settings_frame)
timestep_entry.grid(row=0, column=1)
timestep_entry.insert(0, "0.005")
#Seconds Entry
Label(settings_frame, text="Seconds to Simulate (sec):").grid(row=0, column=2)
seconds_entry = Entry(settings_frame)
seconds_entry.grid(row=0, column=3)
seconds_entry.insert(0, "1")
#Create run menu
gui.option_add('*tearOff', FALSE)
menubar = Menu(gui)
gui['menu'] = menubar
#Plot graph using matplotlib
def plot_graph():
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_xlabel('Time (sec)')
ax.set_ylabel('X (m)')
ax.set_zlabel('Y (m)')
particles = [get_particle() for get_particle in configs]
delta_time = float(timestep_entry.get())
total_seconds = float(seconds_entry.get())
current_time = 0.0
time_steps = []
while current_time < total_seconds:
time_steps.append(current_time)
current_time += delta_time
step(particles, delta_time)
for particle in particles:
ax.plot(time_steps, particle.x, particle.y, label=particle.name)
ax.legend()
plt.show()
'''def animation_2d():
DEFAULTSCREENSIZE = (800, 600)
import pygame
pygame.init()
screen = pygame.display.set_mode(DEFAULTSCREENSIZE, pygame.DOUBLEBUF)
pygame.quit()'''
menu_run = Menu(menubar)
menubar.add_cascade(menu=menu_run, label='Run')
menu_run.add_command(label='Graph Pathways', command=plot_graph)
#menu_run.add_command(label='2D Animation', command=animation_2d)
gui.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment