Basic program for simulating the motion of three point charges.
Last active
August 29, 2015 13:59
-
-
Save rameshvarun/10702135 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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