The purpose of this week's homework is to get used to using Python as a language and using it to simulate uniform acceleration. In particular, we will study two possible ways of writing a simulation: 1) using numerical methods to compute approximate values of a function, in this case then displacement function for uniform acceleration and 2) computing the result directly using the equation representing the exact solution. Note that in real systems, that equation is often not known and the first method is the only one available. We will also look at how to write a Python function, the 'if' statement and use some of the graphical capability of VPython.
Many of the exercises ask you to make small modifications to the same program. The only thing you need to turn in is your answers to the questions and a listing of your final program. Don't forget to "save early save often".
We'll start with the program you worked on for this week's computing assignment--a simulation of a particle undergoing uniform acceleration.
x = 0 # starting position v = 5 # v is velocity in m/s a = -1 # a is the acceleration in m/s/s t = 0 # starting time in seconds dt = 1 # delta t, the change in time while t<=20 : print t,x x = x + v*dt v = v + a*dt t = t + dt
Cut and paste this Python code into IDLE and run it to make sure you copied it correctly. It should print out displacement values for times up to t=20. Record the final displacement at t=20.
Final displacement at t=20 with Δt=1 is -90m.
Now change the program to simulate the results with a
smaller time step, Δt, of 0.1 seconds instead of one second and
rerun the simulation. You'll find that due to numerical approximations
within the computer, the simulation won't go all the way up to 20
seconds unless you adjust the time limit up a little in the
while
statement's test (t<=20
). Try adding
dt
on to the limit so it is one step higher than needed
and change the '<=' (less than or equal) to just '<' (less than).
Questions
Δt | x at 20s |
1s | |
.1s | |
.01s | |
.001s | |
.0001s |
Δt | x at 20s |
1s | -90m |
.1s | -99m |
.01s | -99.9m |
.001s | -99.99m |
.0001s | -100.0005m |
(Note: You
could use a 'for' loop around your 'while' loop to change
dt
and rerun the while loop automatically.)
Questions
#-------------------------------------------------------- # UNIFORM.PY - Uniform motion in Python # This version runs the same simulation # for increasingly small delta t's printing # The numerical solution at t=20s. # AUTHOR: Barry Tolnas # CREATED: 1/6/04 #-------------------------------------------------------- from visual import * x = 0 # starting position v = 5 # v is velocity in m/s a = -1 # a is the acceleration in m/s/s t = 0 # starting time in seconds for dt in [1, .1, .01, .001, .0001]: #don't forget to reset all values that were modified #the previous run through the simulation! t=0 x=0 v=5 while t<20 : x = x + v*dt v = v + a*dt t = t + dt print t,x # print the final result at t=20 only
Recall the equation from your physics notes for uniform acceleration that relates final displacement as a function of time, initial position, initial velocity, and acceleration, x=x0+v0t+(1/2)at2. We should be able to use this equation instead of our numerical simulation to get a much more accurate approximation because this equation gives the exact solution. The only reason we can't get an exact answer from the computer is because it can't perform the calculations with 100% accuracy (but you can by hand on paper).
Define a Python function named displacement
which uses this equation to compute displacement for a given
time. There is an example of functions on the website HERE and you should check the Python
Tutorial or a book for more examples. The function should allow
the following program to run:
print "The displacement at t=20 is",displacement(20)
def displacement(t): return x0 + v0*t + a*t*t/2.0
Note: this function assumes that values for x0, v0, and a have already been defined prior to the function definition in the program.
Note 2: Many people wrote a function that takes x0
, v0
, and a
as
additional arguments. While this makes the function more general it
would not work in the one-line program given in the exercise which
assumes only a single argument (time).
gdisplay
and gcurve
.
#----------------------------------------- # UNIFORM.PY - Uniform motion in Python # This version gives an exact solution solved analytically # rather than a numerical approximation and graphs the result # using VPython's graph module. # AUTHOR: Barry Tolnas # CREATED: 1/6/04 #----------------------------------------- from visual.graph import * x0 = 0 # starting position v0 = 5 # v is velocity in m/s a = -1 # a is the acceleration in m/s/s t = 0 # starting time in seconds dt = 1 # delta t, the change in time def displacement(t): return x0 + v0*t + a*t*t/2.0 graph = gdisplay() curve = gcurve() # For a slightly fancier graph replace the above lines with these: #graph = gdisplay(title="Uniform Acceleration", xtitle="displacement", ytitle="time") #curve = gcurve(color=(1,1,0)) while t<=20 : x = displacement(t) print t,x curve.plot(pos=(t,x)) t = t+dt
from visual import * scene.range=10 #How many units wide the display window shows scene.center=(0,5,0)#The point in the center of the window v = 0 #initial velocity t = 0 #initial time dt = 1/30.0 # delta t y = 10 # initial position #setup objects in the scene ball = sphere(pos=(0,y,0), color=(1,0,0)) ground = box(pos=(0,0,0), size=(20,.2,20), color=(0,1,0)) print "ball radius=",ball.radius print "box thickness=",ground.size.y while t<1.6: ball.y = ball.y + v*dt v = v - 9.8*dt t = t + dt rate(1/dt) #this controls the frame rate of animation
# Week 3 Computing HW Solution for exercise 7 -- the bouncing ball problem. from visual import * scene.range=10 scene.center=(0,5,0) v = 0 #initial velocity t = 0 #initial time dt = 1/30.0 # delta t y = 10 # initial position #setup objects in the scene ball = sphere(pos=(0,y,0), color=(1,0,0)) ground = box(pos=(0,0,0), size=(20,.2,20), color=(0,1,0)) print "ball radius=",ball.radius print "box thickness=",ground.size.y while t<10: ball.y = ball.y + v*dt v = v - 9.8*dt # bounce if one radius from the ground if ball.y<(ball.radius+ground.size.y/2.0): ball.y=ball.radius v = -v t = t + dt rate(1/dt) #animation rate in frames per second print "ending at time t =",t