Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- __author__ = 'Grifter'
- from visual import *
- from random import randint
- class Simulation():
- def __init__(self, num):
- """
- Initialize simulation with values for electrons, coulomb constant and sim dt.
- :param num: Number of electrons to simulate.
- :return: Returns Sim object
- """
- # Default sim constants
- self.dt = 0.02
- self.num = num
- self.coulomb_constant = 8.878E9
- self.electron_mass = 9.11E-31
- self.electron_charge = -1.60E-19
- # Data repository
- self.electron_list = []
- # Particle Init Loop
- for _ in range(self.num):
- self.electron_list.append(self.electron)
- @property
- def electron(self):
- """
- This sim property is called to initialize an electron in the sim with random position and velocity
- :return: Electron sphere object
- """
- return sphere(pos=vector(randint(-20, 20), randint(-20, 20), randint(-20, 20)),
- mass=self.electron_mass, charge=self.electron_charge,
- velocity=vector(randint(-3, 3), randint(-3, 3), randint(-3, 3)),
- acceleration=vector(0, 0, 0),
- color=(randint(0, 1), randint(0, 1), randint(0, 1)),
- make_trail=True, interval=3, retain=50)
- def coulombs_law(self, body1, body2):
- """
- Calculate the force on an electron using Coulombs Law.
- :param body1: The body the force is being calculated on.
- :param body2: The body the force is being calculated with.
- :return: Force vector
- """
- # Calculate the scalar value of the electromagnetic force
- temp_scalar_force = -((self.coulomb_constant * self.electron_charge ** 2) / abs(body1.pos - body2.pos) ** 2)
- # Calculate a norm vector for the electromagnetic force
- temp_norm_vector = (body2.pos - body1.pos) / abs(body2.pos - body1.pos)
- # Return the product of the norm vector and the scalar value of the force (The proper force vector)
- return temp_scalar_force * temp_norm_vector
- def acceleration_calc(self):
- """
- Updates the net acceleration of each particle in the simulation.
- :return: None
- """
- for i in self.electron_list:
- # Initialize acceleration for this step
- i.acceleration = vector(0, 0, 0)
- for j in self.electron_list:
- # Ensure that the particle does not include self in force calc
- if not (i is j):
- # Use newtons second law and the coulomb function to calc acceleration
- i.acceleration += self.coulombs_law(i, j) / self.electron_mass
- def forward_euler(self):
- """
- Updates the position of each particle using a forward Euler method.
- :return: None
- """
- for i in self.electron_list:
- i.velocity += i.acceleration * self.dt
- i.pos += i.velocity * self.dt
- def step(self):
- """
- Iterate the simulation calling the appropriate functions sequentially.
- :return: None
- """
- # FPS = inverse dt (for dt = 0.02, FPS = 50)
- rate(1 / self.dt)
- self.acceleration_calc()
- self.forward_euler()
- ## ~~~~~~~~~~~ MAIN ~~~~~~~~~~~ ##
- #Initialize sim
- sim = Simulation(int(input('How many electrons?: ')))
- #Main Loop
- while True:
- sim.step()
Advertisement
Add Comment
Please, Sign In to add comment