Exemplo n.º 1
0
def shoot(f, a, b, z1, z2, t, tol):
    """Implements the shooting method to solve second order BVPs

    USAGE:
        y = shoot(f, a, b, z1, z2, t, tol)

    INPUT:
        f     - function dy/dt = f(y,t).  Since we are solving a second-
                order boundary-value problem that has been transformed
                into a first order system, this function should return a
                1x2 array with the first entry equal to y and the second
                entry equal to y'.
        a     - solution value at the left boundary: a = y(t[0]).
        b     - solution value at the right boundary: b = y(t[n-1]).
        z1    - first initial estimate of y'(t[0]).
        z1    - second initial estimate of y'(t[0]).
        t     - array of n time values to determine y at.
        tol   - allowable tolerance on right boundary: | b - y[n-1] | < tol

    OUTPUT:
        y     - array of solution function values corresponding to the
                values in the supplied array t.

    NOTE:
        This function assumes that the second order BVP has been converted to
        a first order system of two equations.  The secant method is used to
        refine the initial values of y' used for the initial value problems.
    """

    from diffeq import rk4

    max_iter = 25  # Maximum number of shooting iterations

    n = len(t)  # Determine the size of the arrays we will generate

    # Compute solution to first initial value problem (IVP) with y'(a) = z1.
    # Because we are using the secant method to refine our estimates of z =
    # y', we don't really need all the solution of the IVP, just the last
    # point of it -- this is saved in w1.

    y = rk4(f, [a, z1], t)
    w1 = y[n - 1, 0]

    print "%2d: z = %10.3e, error = %10.3e" % (0, z1, b - w1)

    # Begin the main loop.  We will compute the solution of a second IVP and
    # then use the both solutions to refine our estimate of y'(a).  This
    # second solution then replaces the first and a new "second" solution is
    # generated.  This process continues until we either solve the problem to
    # within the specified tolerance or we exceed the maximum number of
    # allowable iterations.

    for i in xrange(max_iter):

        # Solve second initial value problem, using y'(a) = z2.  We need to
        # retain the entire solution vector y since if y(t(n)) is close enough
        # to b for us to stop then the first column of y becomes our solution
        # vector.

        y = rk4(f, [a, z2], t)
        w2 = y[n - 1, 0]

        print "%2d: z = %10.3e, error = %10.3e" % (i + 1, z2, b - w2)

        # Check to see if we are done...

        if abs(b - w2) < tol:
            break

        # Compute the new approximations to the initial value of the first
        # derivative.  We compute z2 using a linear fit through (z1,w1) and
        # (z2,w2) where w1 and w2 are the estimates at t=b of the initial
        # value problems solved above with y1'(a) = z1 and y2'(a) = z2.  The
        # new value for z1 is the old value of z2.

        #z1, z2 = ( z2, z1 + ( z2 - z1 ) / ( w2 - w1 ) * ( b - w1 ) )
        z1, z2 = (z2, z2 + (z2 - z1) / (w2 - w1) * (b - w2))
        w1 = w2

    # All done.  Check to see if we really solved the problem, and then return
    # the solution.

    if abs(b - w2) >= tol:
        print "\a**** ERROR ****"
        print "Maximum number of iterations (%d) exceeded" % max_iter
        print "Returned values may not have desired accuracy"
        print "Error estimate of returned solution is %e" % (b - w2)

    return y[:, 0]
Exemplo n.º 2
0
"""
Created on Sat Sep 29 18:38:09 2018

@author: Ben
"""

import numpy as np
from matplotlib import pyplot as pyl
from diffeq import rk4

f = lambda T, t: -r * (T - Ts)
tmax = 60.
T0 = 10.
r = 0.1
Ts = 83.
n = 5
dt = np.zeros(n)
temp = np.zeros(n)

for j in range(0, n):
    dt[j] = 1 / (j + 1)
    nsteps = int(
        tmax /
        dt[j])  #the arrays will have different size for different time steps
    T = T0
    my_temp, my_time = rk4(f, 0, tmax, nsteps)
    temp[j] = my_temp[10 * (j + 1)]

pyl.plot(dt, temp, 'o')
pyl.xlabel('dt')
pyl.ylabel('Temp.')
Exemplo n.º 3
0
for j in range(0, 20):  #arbitrarily increase the size

    deltatarr.append(dt)
    nsteps = int(
        tmax /
        dt)  #the arrays will have different size for different time steps
    my_time = np.linspace(dt, tmax, nsteps)
    my_temp = np.zeros(nsteps)
    T = T0
    for i in range(1, nsteps):
        T = euler(T, -r * (T - Ts), dt)
        my_temp[i] = T
        if dt * i == 10:
            t10.append(T)

    pyplot.plot(my_time, my_temp, ls='-', lw=0.5)
    dt = dt / 2.

print(t10)
print(deltatarr)
pyplot.xlabel('time')
pyplot.ylabel('temperature')
pyplot.xlim(8, 10)
pyplot.ylim(48, 58)

fig2 = pyplot.figure(2)
ax2 = fig2.add_subplot(111)
ax2.scatter(deltatarr, t10)

m = diffeq.rk4(-r * (T - Ts))
Exemplo n.º 4
0
def shoot( f, a, b, z1, z2, t, tol ):
    """Implements the shooting method to solve second order BVPs

    USAGE:
        y = shoot(f, a, b, z1, z2, t, tol)

    INPUT:
        f     - function dy/dt = f(y,t).  Since we are solving a second-
                order boundary-value problem that has been transformed
                into a first order system, this function should return a
                1x2 array with the first entry equal to y and the second
                entry equal to y'.
        a     - solution value at the left boundary: a = y(t[0]).
        b     - solution value at the right boundary: b = y(t[n-1]).
        z1    - first initial estimate of y'(t[0]).
        z1    - second initial estimate of y'(t[0]).
        t     - array of n time values to determine y at.
        tol   - allowable tolerance on right boundary: | b - y[n-1] | < tol

    OUTPUT:
        y     - array of solution function values corresponding to the
                values in the supplied array t.

    NOTE:
        This function assumes that the second order BVP has been converted to
        a first order system of two equations.  The secant method is used to
        refine the initial values of y' used for the initial value problems.
    """

    from diffeq import rk4

    max_iter = 25   # Maximum number of shooting iterations

    n = len( t )    # Determine the size of the arrays we will generate

    # Compute solution to first initial value problem (IVP) with y'(a) = z1.
    # Because we are using the secant method to refine our estimates of z =
    # y', we don't really need all the solution of the IVP, just the last
    # point of it -- this is saved in w1.

    y = rk4( f, [a,z1], t )
    w1 = y[n-1,0]

    print "%2d: z = %10.3e, error = %10.3e" % ( 0, z1, b - w1 )

    # Begin the main loop.  We will compute the solution of a second IVP and
    # then use the both solutions to refine our estimate of y'(a).  This
    # second solution then replaces the first and a new "second" solution is
    # generated.  This process continues until we either solve the problem to
    # within the specified tolerance or we exceed the maximum number of
    # allowable iterations.

    for i in xrange( max_iter ):

        # Solve second initial value problem, using y'(a) = z2.  We need to
        # retain the entire solution vector y since if y(t(n)) is close enough
        # to b for us to stop then the first column of y becomes our solution
        # vector.

        y = rk4( f, [a,z2], t )
        w2 = y[n-1,0]

        print "%2d: z = %10.3e, error = %10.3e" % ( i+1, z2, b - w2 )

        # Check to see if we are done...
    
        if abs( b - w2 ) < tol:
            break

        # Compute the new approximations to the initial value of the first
        # derivative.  We compute z2 using a linear fit through (z1,w1) and
        # (z2,w2) where w1 and w2 are the estimates at t=b of the initial
        # value problems solved above with y1'(a) = z1 and y2'(a) = z2.  The
        # new value for z1 is the old value of z2.

        #z1, z2 = ( z2, z1 + ( z2 - z1 ) / ( w2 - w1 ) * ( b - w1 ) )
        z1, z2 = ( z2, z2 + ( z2 - z1 ) / ( w2 - w1 ) * ( b - w2 ) )
        w1 = w2

    # All done.  Check to see if we really solved the problem, and then return
    # the solution.

    if abs( b - w2 ) >= tol:
        print "\a**** ERROR ****"
        print "Maximum number of iterations (%d) exceeded" % max_iter
        print "Returned values may not have desired accuracy"
        print "Error estimate of returned solution is %e" % ( b - w2 )

    return y[:,0]
Exemplo n.º 5
0
plt.figure(figsize = (6.75,5))
plt.xlabel('Time', fontsize = 14)
plt.xticks(fontsize = 14)
plt.yticks(fontsize = 14)
plt.title('Huen Method (rk2)')
plt.plot(t, theta2, label = 'Theta')
plt.plot([],[], label = f"R^2 = {format(r2_theta,'.5')}")
plt.plot(t, omega2,'--', label = 'Omega')
plt.plot([],[], label = f"R^2 = {format(r2_omega,'.5')}")
plt.tight_layout()
plt.legend(fontsize = 12)
plt.savefig('huen1.pdf')

# Testing RK4 method, plotting
theta3, omega3, time3 = df.rk4(pend, y0, t)
r3_theta = np.corrcoef(sol1[:,0], theta3)[0,1]
r3_omega = np.corrcoef(sol1[:,1], omega3)[0,1]

plt.figure(figsize = (6.75,5))
plt.xlabel('Time', fontsize = 14)
plt.xticks(fontsize = 14)
plt.yticks(fontsize = 14)
plt.title('RK4 method')
plt.plot(t, theta3, label = 'Theta')
plt.plot([],[], label = f"R^2 = {format(r3_theta,'.5')}")
plt.plot(t, omega3, '--', label = 'Omega')
plt.plot([],[], label = f"R^2 = {format(r3_omega,'.5')}")
plt.tight_layout()
plt.legend(fontsize = 12)
plt.savefig('rk41.pdf')