Example #1
0
def go(v0):
    def f(R):
        return R * (vy + g / b) / vx + g * np.log(1 - b * R / vx) / (b**b)

    def df(R):
        return (vy + g / b) / vx - g / (b * (1 - b * R / vx) * vx)

    g, b = 9.8, 1.0
    x, yb, yn, dtr = [], [], [], np.pi / 180

    for theta in range(1, 90):
        vx, vy = v0 * np.cos(theta * dtr), v0 * np.sin(theta * dtr)
        Rb = rtf.bisect(f, 0.01, vx / b - 1e-5, 1e-6)
        Rn = rtf.newton(f, df, vx / b - 1e-5)

        if (Rb != None and Rn != None):
            x.append(theta)
            yb.append(Rb)
            yn.append(Rn)

    plt.figure()
    plt.plot(x, yb, label='Bisection method', zorder=-1)
    plt.plot(x, yn, 'r.', label='Newton Method')
    plt.xlabel('angle (deg)')
    plt.ylabel('R (m)')
    plt.legend(loc='best')
    plt.title('v0 = {0}'.format(v0))
    plt.show()
Example #2
0
#
# Program 3.3: Range vs. angle (range.py)
# J Wang, Computational modeling and visualization with Python
#

import rootfinder as rtf, math as ma   # get root finders, math
import matplotlib.pyplot as plt # get matplotlib plot functions

def f(R):                       # range function, 
    return R*(vy+g/b)/vx + g*ma.log(1.-b*R/vx)/(b*b)

g, b, v0 = 9.8, 1.0, 100.       # g, linear coeff., firing speed
x, y, dtr = [], [], ma.pi/180.  # temp arrays, deg-to-rad conv

for theta in range(1,90):
    vx, vy = v0*ma.cos(theta*dtr), v0*ma.sin(theta*dtr) # init vel
    R = rtf.bisect(f, 0.01, vx/b-1.e-5, 1.e-6)       # solve 
    if (R != None): x.append(theta), y.append(R)
    
plt.figure()                    # open fig, plot, label, show fig
plt.plot(x, y), plt.xlabel('angle (deg)'), plt.ylabel('R (m)')
plt.show()
Example #3
0
    E = En
    wfup, psiup = intsch([0., .1], N, xL, h)  # march upward
    wfdn, psidn = intsch([0., .1], N, xR, -h)  # march downward
    return psidn[0] * psiup[1] - psiup[0] * psidn[1]


a, b, V0 = 4.0, 1.0, 6.  # double well widths, depth
xL, xR, N = -4 * a, 4 * a, 500  # limits, intervals
xa = np.linspace(xL, xR, 2 * N + 1)  # grid
h, M = xa[1] - xa[0], 2  # step size, M=matching point
E1, dE, j = -V0, 0.01, 1

plt.figure()
while (E1 < 0):  # find E, calc and plot wave function
    if (shoot(E1) * shoot(E1 + dE) < 0):  # bracket E
        E = rtf.bisect(shoot, E1, E1 + dE, 1.e-8)
        print('Energy found: %.3f' % (E))
        wfup, psiup = intsch([0., .1], N + M, xL, h)  # compute WF
        wfdn, psidn = intsch([0., .1], N - M, xR, -h)
        psix = np.concatenate((wfup[:-1], wfdn[::-1]))  # combine WF
        scale = psiup[0] / psidn[0]
        psix[N + M:] *= scale  # match WF
        ax = plt.subplot(2, 2, j)
        ax.plot(xa, psix / max(psix))  # plot WF
        ax.plot(xa, np.vectorize(V)(xa) / (2 * V0))  # overlay V
        ax.set_xlim(-a, a)
        ax.text(2.2, 0.7, '%.3f' % (E))
        if (j == 1 or j == 3): ax.set_ylabel(r'$\psi$')
        if (j == 3 or j == 4): ax.set_xlabel('$x$')
        if (j < 4): j += 1  # 4 plots max
    E1 += dE
Example #4
0
    global E                # global E, needed in sch()
    E = En
    wfup, psiup = intsch([0., .1], N, xL, h)      # march upward 
    wfdn, psidn = intsch([0., .1], N, xR, -h)     # march downward
    return psidn[0]*psiup[1] - psiup[0]*psidn[1]

a, b, V0 = 4.0, 1.0, 6.             # double well widths, depth
xL, xR, N = -4*a, 4*a, 500          # limits, intervals
xa = np.linspace(xL, xR, 2*N+1)     # grid
h, M = xa[1]-xa[0], 2               # step size, M=matching point
E1, dE, j = -V0, 0.01, 1

plt.figure()
while (E1 < 0):     # find E, calc and plot wave function
    if (shoot(E1) * shoot(E1 + dE) < 0):        # bracket E
        E = rtf.bisect(shoot, E1, E1 + dE, 1.e-8)
        print ('Energy found: %.3f' %(E))
        wfup, psiup = intsch([0., .1], N+M, xL, h)      # compute WF
        wfdn, psidn = intsch([0., .1], N-M, xR, -h)
        psix = np.concatenate((wfup[:-1], wfdn[::-1]))  # combine WF
        scale = psiup[0]/psidn[0]
        psix[N+M:] *= scale                             # match WF
        ax = plt.subplot(2,2,j)
        ax.plot(xa, psix/max(psix))                     # plot WF
        ax.plot(xa, np.vectorize(V)(xa)/(2*V0))         # overlay V
        ax.set_xlim(-a,a)
        ax.text(2.2,0.7, '%.3f' %(E))
        if (j == 1 or j == 3): ax.set_ylabel(r'$\psi$')
        if (j == 3 or j == 4): ax.set_xlabel('$x$')
        if (j<4): j += 1            # 4 plots max
    E1 += dE
Example #5
0
import rootfinder as rtf
from scipy.optimize import fsolve

def f(x):
    return 5*x - x**3

def df(x):
    return 5 - 3*x**2

a, b = -2, 2

bs = rtf.bisect(f, a, b)
nt = rtf.newton(f, df, a)

print(bs)
print(nt)

x = fsolve(f, -2)
print(x)

Example #6
0
#
# Program 3.5: Shooting method (shoot.py)
# J Wang, Computational modeling and visualization with Python
#

from __future__ import print_function       # use print() as function
import ode, rootfinder as rtf, numpy as np   # ode, root solvers, numpy

def proj(Y, t):                 # ideal projectile motion
    return np.array([Y[2],Y[3], 0.0,-g])   # [vx,vy,ax,ay]
   
def fy(theta):                  # return f as a func of theta
    Y = [0., 0., v0*np.cos(theta), v0*np.sin(theta)]    # [x,y,vx,vy]
    t = xb / Y[2]               # Step 1: time to xb    
    h = t / nsteps
    for i in range(nsteps):
        Y = ode.RK2(proj, Y, t, h)            # no need to update t
        
    return Y[1] - yb                            # Step 2: $y(\theta) - y_b$

# number of steps, g, init speed, x and y boundary values
nsteps, g, v0, xb, yb = 100, 9.8, 22., 40., 3.  # para. 

theta = rtf.bisect(fy, 0.6, 1.2, 1.e-6)      # Step 3: shoot for $\theta$
if (theta != None): print('theta(deg)=',theta*180/np.pi)   # result
Example #7
0
#
# Program 3.5: Shooting method (shoot.py)
# J Wang, Computational modeling and visualization with Python
#

from __future__ import print_function  # use print() as function
import ode, rootfinder as rtf, numpy as np  # ode, root solvers, numpy


def proj(Y, t):  # ideal projectile motion
    return np.array([Y[2], Y[3], 0.0, -g])  # [vx,vy,ax,ay]


def fy(theta):  # return f as a func of theta
    Y = [0., 0., v0 * np.cos(theta), v0 * np.sin(theta)]  # [x,y,vx,vy]
    t = xb / Y[2]  # Step 1: time to xb
    h = t / nsteps
    for i in range(nsteps):
        Y = ode.RK2(proj, Y, t, h)  # no need to update t

    return Y[1] - yb  # Step 2: $y(\theta) - y_b$


# number of steps, g, init speed, x and y boundary values
nsteps, g, v0, xb, yb = 100, 9.8, 22., 40., 3.  # para.

theta = rtf.bisect(fy, 0.6, 1.2, 1.e-6)  # Step 3: shoot for $\theta$
if (theta != None):
    print('theta(deg)=', theta * 180 / np.pi)  # result
def xection(theta, ba, da):  # cross section
    cs = 0.0  # ba=impact para, da=deflection angle
    for i in range(len(ba) - 1):
        if ((theta - da[i]) * (theta - da[i + 1]) < 0.):  # theta bracketed
            db = ba[i + 1] - ba[i]
            cs += (ba[i] + db / 2.) * abs(db / (da[i + 1] - da[i]))
    return cs / np.sin(theta)


Z, R = 1.0, 1.0  # nuclear charge Z,  radius of plum potential
E, b, bmax = 1.2, 0.01, 20.  # energy, initial b, bmax
eps, tiny = 1.E-14, 1.E-5  # rel error, u-limit
ba, theta = [], []  # impact para, deflection
while (b <= bmax):
    umin = rtf.bisect(fu, tiny, 1. / b, eps)  # find turning pt
    alpha = itg.gauss(fx, 0., np.sqrt(umin))
    ba.append(b), theta.append(np.pi - 2 * alpha)
    b *= 1.02

plt.figure(), plt.plot(ba, theta)  # plot deflection function
plt.xlabel('$b$ (a.u.)'), plt.ylabel('$\Theta$', rotation=0)
plt.yticks([0, np.pi / 2, np.pi], ['$0$', '$\pi/2$', '$\pi$'])
plt.xlim(0, 3)

cs, sa = [], np.linspace(0.01, np.pi - .01, 500)  # scattering angle
for x in sa:  # calc, plot cross section
    cs.append(xection(x, ba, theta))
plt.figure(), plt.plot(sa, cs)
plt.xlabel(r'$\theta$'), plt.ylabel(r'$\sigma(\theta)$')
plt.xticks([0, np.pi / 2, np.pi], ['$0$', '$\pi/2$', '$\pi$'])
Example #9
0
    return 2*x*b/np.sqrt(fu(u))

def xection(theta, ba, da):     # cross section
    cs = 0.0                    # ba=impact para, da=deflection angle
    for i in range(len(ba)-1):
        if ((theta-da[i])*(theta-da[i+1]) < 0.):   # theta bracketed 
            db = ba[i+1] - ba[i]
            cs += (ba[i] + db/2.)*abs(db/(da[i+1]-da[i]))
    return cs/np.sin(theta)
    
Z, R = 1.0, 1.0     # nuclear charge Z,  radius of plum potential
E, b, bmax = 1.2, 0.01, 20.             # energy, initial b, bmax
eps, tiny =1.E-14, 1.E-5                # rel error, u-limit
ba, theta = [], []                      # impact para, deflection
while (b <= bmax):
    umin = rtf.bisect(fu, tiny, 1./b, eps)   # find turning pt
    alpha = itg.gauss(fx, 0., np.sqrt(umin))
    ba.append(b), theta.append(np.pi - 2*alpha)
    b *= 1.02
    
plt.figure(), plt.plot(ba, theta)       # plot deflection function
plt.xlabel('$b$ (a.u.)'), plt.ylabel('$\Theta$', rotation=0)
plt.yticks([0, np.pi/2, np.pi], ['$0$','$\pi/2$', '$\pi$'])
plt.xlim(0,3)

cs, sa = [], np.linspace(0.01, np.pi-.01, 500)  # scattering angle
for x in sa:                            # calc, plot cross section
    cs.append(xection(x, ba, theta))
plt.figure(), plt.plot(sa, cs)
plt.xlabel(r'$\theta$'), plt.ylabel(r'$\sigma(\theta)$')
plt.xticks([0, np.pi/2, np.pi], ['$0$','$\pi/2$', '$\pi$'])