python implementation (euler method)ygu/courses/phys234/notes/lec10_2020_po… · python...
TRANSCRIPT
Python Implementation (Euler Method) Lets start with a simpler problem, x=x(t) is a function of time, f(x) is a function of x.
d xdt
= − x + 1A complete specification of the problem must include an initial condition x(0) = x0; here we assume x0 = 0 Tlast=4 .
Start anaconda, choose spider (or use another IDE). Create a new file and save it as eulermethod.py. (using spider).
Steps:
Preparation:(1) Start with your useful comments
(2) Import numpy (a critical and very comprehensive math library/module for scientific computing using python (e.g., forming matrices, special functions). Add a line at the topimport numpy as np (np is new a user-defined reference to the library)
(3) Since we may want to use plotting, then import Matlab-based plotting library called Matplotlib.pyplot.import matplotlib.pyplot as pl
xn+1 = xn + d xdt
|n Δt
#!/usr/bin/env python3# -*- coding: utf-8 -*-"""This program will solve the differential Eqn. dy/dx=-x + 1"""# this could be done by from numpy import *import numpy as npimport matplotlib.pyplot as plt
def dxdt(x):# calculates the function given x
return -x + 1
# below is main code x0 = 0. # initial solutiondt = 0.01 # time stepping, small to be accurateT = 4. # boundary condition, time: 0--T
t = np.linspace(0, T, int(T/dt)+1) # makle array of tx = np.zeros(len(t)) # array to save solution
# integrate the differential equation using Euler's methodx[0] = x0 # initial solutionfor i in range(1, len(t)):
j = i-1 # set j to be 'last' value/starting value x[i] = x[j] + dxdt(x[j])*dt # Euler scheme
Code to solve the differential Eqn. using finite diff
# create a new figure using matlab libraryplt.plot(t, x, '-g')
#axis labelsplt.xlabel('t')plt.ylabel('x(t)')
#save figure in PDFplt.savefig('ploteuler.pdf')
Continued… using Matlab libs to plot solution
Remarks:
(1) Accuracy depends on time stepping, this is the essence of ‘finite’ difference.
(2) Remember to solve equation first, then update(3) Note some comments have been changed from the
original code ‘eulermethod.py’ to simply this demo(4) Try to stick to 4 spaces for blocks of codes
Output:ploteuler.pdf
Use a user-defined external libraryimport numpy as npimport matplotlib.pyplot as pltimport eulerfun as ef
# below is main code that does Euler method. This code uses# user defined library file (external) ‘eulerfun.py’x0 = 0 # initial solutiondt = 0.01 # time stepT = 4 # Final time
t = np.linspace(0, T, int(T/dt)+1) # make time array
x = np.zeros(len(t)) # initialize solution xx[0] = x0; # set starting solutionfor i in range(1, len(t)):
j=i-1 # set j to be 'last' value/starting value# the following calls the function from an import obj
x[i] = x[j] + ef.efun(x[j])*dt
ef.printline()plt.plot(t, x, '-g') # plot using matlabplt.xlabel('t')plt.ylabel('x(t)')
Remarks:(1) Can store multiple library functions inside one .py file(2) The function is ok without the header from ‘spider’
(i.,e., using emacs or VI would be fine to write code);
Useful input/output options
import numpy as npimport matplotlib.pyplot as pl
## This code demonstrates how to input and output to files#a = np.linspace(0., 10., 11)b = a**2 # square the vector a# The block below write a 2 column output fileprint(type(f0)) # just in case you are interested in typef0 = open('testcol.txt', 'w’)i = 0while i < len(a):
f0.write('%10.3e %10.3e\n' % (a[i], b[i]))i += 1
f0.close()
# The block below reads the txt output and # retrieve the real numbersdata=np.loadtxt('testcol.txt')x=data[:,0]y=data[:,1]pl.plot(x,y)
1. A slightly more realistic freefall problem: freefall motion with drag force (air resistance).Drag force is the force exerted on a body moving in a medium like air or water. It depends in a complex way upon the velocity of the body relative to the medium, the viscosity (“stickiness”) and the density of the medium, the shape of the body, and the roughness of its surface.
FD = Drag force, SI: NewtonsCD = Drag Coefficient (dimensionless), why?A = Cross-sectional area perpendicular to the flow,
SI: m2
v = Velocity of the body relative to the medium. SI: m/sr = density of medium (e.g., air)
Drag(up +)
Weight
This means the drag force becomes larger when the falling apple picks up speed (assuming being dropped by a careless eater from a helicopter before taken a bite). Eventually, it reaches a terminal speed at which the apple won’t go any faster.
A simplified relationship between drag force FD and the speed v
where (some constant)
freefall motion with drag force (air resistance).
def Euler(y, v, g, vt2, t, dt):# Euler problem with drag force# input: y, v, g, vt2, t, dt# output: y, v, a, t
y = y + v * dt # updating heightif(vt2 == 0):
a = -gelse:
a = -g*(1-v*v/(vt2*vt2))v = v + a * dt # updating velocityt += dtreturn y, v, a, t
y, v, a, t = Euler(y, v, g, vt2, t, dt)t_array.append(t)v_array.append(v)y_array.append(y)a_array.append(a)
Below: Part of the code that saves elements to arrays
Remarks: 1. Order of y and v in Euler matter!!2. First point is correct, despite being counter-
intuitive
Output (modified):time step dt = 0.1number of time steps between output = 10
time(sec) y(m) velocity a
0.000, 100.000, 0.000, -9.8 1.000, 96.030, -7.714 -4.652.000, 87.125, -9.706 -0.703.000, 77.259, -9.966 -0.084.000, 67.274, -9.996 -0.0095.000, 57.276, -10.000 -0.0016.000, 47.276, -10.000 -0.00017.000, 37.276, -10.000 -1.3e-58.000, 27.276, -10.000 -1.5e-69.000, 17.276, -10.000 -1.7e-7
10.000, 7.276, -10.000 -1.9e-810.800, -0.724, -10.000 -3.4e-9
Remarks:(1) Ball reaches the terminal speed near or before
reaching the height of 57.276 meters.(2) The last height is < 0, which stops the while
loop but the time values, y, v, and a have all been written to the respective arrays
Output graph of y(t) and v(t) vs. t
pl.plot(t_array, y_array, '-g', t_array, v_array, '-r')pl.gca().legend(('y(t)', 'v(t)'))
pl.xlabel('t(sec)')pl.ylabel('y (m)')pl.savefig('euler_drag.pdf')
A 2D problem with Drag:
How far and what trajectory does that wicked line drive off ofVladi Guerrero Jr’s bat travel? It depends: say in the thin air above the mile-high Coors Field (Colorado), the baseball can have a life of its own.
h q0
V0
Forces:
q
V
mg
FD
Newton II:
AlsoVx = V cos(q), Vy = V sin(q)
V2 = Vx2 + Vy2
Now, we already know that drag force can be written as
Vladimir Guerrero Jr,Wall Street Journal
md Vxd t
= − FDcos(θ )
mdVy
dt= − mg − FDsin(θ )
FD = k2V 2 K2
FD = k2V 2 where k2 is some constant
Python Implementation
# key constantsCd = 0.35 # drag coefficientsarea = 4.3e-3 # cross-section area of baseball grav = 9.81 # gravitation accelerationmass = 0.145 # mass of baseballmax_step = 10000
r1[0] = 0.0r1[1] = y1
r1 below stores initial distance and height, y1 is the user input height at which to throw the baseball
v1[0] = speed*np.cos(theta*np.pi/180.) # initial velocity (Vx)v1[1] = speed*np.sin(theta*np.pi/180.) # initial velocity (Vy)
Below stores the initial velocity v1[0] = horizontal velocity, v1[1]=vertical velocity
for istep in range(1, max_step):# record position (computed and thoretical, for plotting)
xplot[istep] = r[0]yplot[istep] = r[1]t = (istep - 1) * delta_t # this is time elapsed
# below is the analytical solution without air resistance# in x direction, uniform speed, in Y direction the solution# is a upward throwing problem (ignoring change in g)# grav = 9.81 m/sec**2
xNoair[istep] = r1[0] + v1[0] * tyNoair[istep] = r1[1] + v1[1] * t - 0.5*grav*t*t
# V_mag = magnitude of velocity using Vx and VyV_mag = np.sqrt( v[0] * v[0] + v[1] * v[1] )accel[0] = air_const*V_mag*v[0] # Air resistanceaccel[1] = air_const*V_mag*v[1] # Air resistance accel[1] -= grav # Gravity
Loop to compute r[0] (distance) and r[1] (height)
d Vxd t
= − cV ⋅ Vx
if air_flag == 0:rho = 0 # no air resistance
else:rho = 1.2 # density of air in km/m**3
air_const = -0.5 * Cd * rho * area/mass # air resistance constant
= − k2m
V ⋅ Vx
d Vxd t
= − FDm
cos(θ )
air_const = -k2/m
# Calculate the new position and velocity using Euler method
r[0] += delta_t*v[0]r[1] += delta_t*v[1]v[0] += delta_t*accel[0]v[1] += delta_t*accel[1]
Documentation:
1. r[0] = x locationr[1] = y locationv[0] = horizontal velocityv[1] = vertical velocity
Equations implemented: xn+1 = xn + vnx * dtyn+1 = yn + vny *dt
Note: these are linear equations do not mean vnyis calculated linearly or it is similar to vnx
pl.plot(xplot[:istep], yplot[:istep], '-r')
Finally, plotting note: By doing the colon notation and index istep, I have removed the last step (where y<0) from plotting.
Starting height = 0, initial speed = 40 m/sInitial angle = 45 deg, no air resistance
Starting height = 40, initial speed = 40 m/sInitial angle = 45 deg, no air resistance
Starting height = 40, initial speed = 40 m/sInitial angle = 45 deg, WITH air resistance
Starting height = 40, initial speed = 40 m/sInitial angle = 15 deg, WITH air resistance
18
More complications to this problem
What about knuckleballs ? Tim Wakefield’s “knuckleball” dances at snail-like 60 miles-per-hour to hitters and baffles them.
Why? Tim is a master of spin control!
Spin ----> Magnus force ---> providing lift
r
v + wr (bottom)
v - wr (top)
FDv
FMagnus
Since FD (bottom) > FD (top), there is a force upward.
nearly straight
distance
height
The angular velocity of the particle at Pwith respect to the origin O is determined by the perpendicular component of the velocity vector v.
20
Something else to think about other than “magnusly” rising baseball, like the wings of a plane.
Bernoulli’s Equation comes to rescue:
This is essentially stating the Conservation of Energy per unit volume.
Take-home message: The faster the flow, the smaller the pressure. And as the upward pressure build up, the plane rises.
Vf = speed of the flowing wind passing the wing.
Pressure = constant
21
In fact, the different “pressure” on different parts of a body also generated the Drag force.
For this very reason, the baseball in a turbulent flow will have funny trajectories due to differential pressure changes between the front and back in the flow stream.
Euler Method & Energy ConsiderationSimple Harmonic Motion
Basic equations:
FMagnus = K w V CD
---> K is the Magnus Coefficient---> w is the spin frequency measured in radians---> V is the velocity of the ball in m/s---> CD is the drag coefficient
F_mag
drag
velocity
Spinning
Non-spinning
baseball-2d-withmagnus.pyV0=40 m/sy0=0angle0=45 degWith air resistance
With air resistance,Upward Magnus
(linear upward trend,Extended range)
With air resistanceDownward Magnus