1
0
Fork 0

Week5: Wrap up: MultiStep

This commit is contained in:
Eric Teunis de Boone 2020-03-05 17:55:00 +01:00
parent 374cef0784
commit 40f3d9f969

View file

@ -4,7 +4,11 @@
import numpy as np import numpy as np
# Integrations Schemes #
########################
# Single Step
#------------
def mk_phi_euler(f): def mk_phi_euler(f):
""" Return a Phi computed for the Euler Method. """ """ Return a Phi computed for the Euler Method. """
def phi_euler(x, y, h): def phi_euler(x, y, h):
@ -12,7 +16,6 @@ def mk_phi_euler(f):
return phi_euler return phi_euler
def mk_phi_euler_mod(f): def mk_phi_euler_mod(f):
""" Return a Phi computed for the Modified Euler (Collatz) Method. """ """ Return a Phi computed for the Modified Euler (Collatz) Method. """
def phi_euler_mod(x, y, h): def phi_euler_mod(x, y, h):
@ -20,7 +23,6 @@ def mk_phi_euler_mod(f):
return phi_euler_mod return phi_euler_mod
def mk_phi_heun(f): def mk_phi_heun(f):
""" Return a Phi computed for the Heun Method. """ """ Return a Phi computed for the Heun Method. """
def phi_heun(x, y, h): def phi_heun(x, y, h):
@ -40,6 +42,31 @@ def mk_phi_rk4(f):
return phi_rk4 return phi_rk4
# Multi Step
#-----------
def mk_phi_AB3(f, phi_short):
steps = 3
def phi_AB3(x, y, h):
if len(x) <= steps:
return phi_short(x, y, h)
else:
return ( 23*f(x[-1], y[-1]) - 16*f(x[-2], y[-2]) + 5*f(x[-3], y[-3]) )/12
return phi_AB3
def mk_phi_AB4(f, phi_short):
steps = 4
def phi_AB4(x, y, h):
if len(x) <= steps:
return phi_short(x, y, h)
else:
return ( 55*f(x[-1], y[-1]) - 59*f(x[-2], y[-2]) + 37*f(x[-3], y[-3]) -9*f(x[-4],y[-4]))/24
return phi_AB4
# Integrator #
##############
def integrator(x, y_0, phi): def integrator(x, y_0, phi):
x = np.asarray(x) x = np.asarray(x)
if isinstance(y_0, (list,np.ndarray)): if isinstance(y_0, (list,np.ndarray)):
@ -54,20 +81,14 @@ def integrator(x, y_0, phi):
y[0] = y_0 y[0] = y_0
h = x[1]-x[0] h = x[1]-x[0]
for i, x_i in enumerate(x): for i in range(1,N):
# Skip the first iteration
if not i:
continue
y[i] = y[i-1] + h*phi(x[:i], y[:i], h) y[i] = y[i-1] + h*phi(x[:i], y[:i], h)
return y return y
# Math Test Functions #
def test_integrator(): #######################
np.random.seed(0)
def ODEF(x, y): def ODEF(x, y):
return y - x**2 + 1 return y - x**2 + 1
@ -75,6 +96,10 @@ def test_integrator():
return (x+1)**2 - 0.5*np.exp(x) return (x+1)**2 - 0.5*np.exp(x)
# Testing #
###########
def test_integrator_singlestep():
test_func = ODEF test_func = ODEF
exact_sol = ODEF_sol exact_sol = ODEF_sol
@ -110,5 +135,39 @@ def test_integrator():
pyplot.show() pyplot.show()
def test_integrator_multistep():
test_func = ODEF
exact_sol = ODEF_sol
N = 2e1
M = 1
# Domain on which to do the integration
x = np.linspace(0, 1, N)
# Calculate Initial Values using RK4
y_0 = 0.5
schemes = [
["AB3", mk_phi_AB3],
["AB4", mk_phi_AB4],
]
# Show Plot
from matplotlib import pyplot
pyplot.subplots()
for name, func in schemes:
pyplot.plot(x, integrator(x, y_0, func(test_func, mk_phi_rk4(test_func))), '--o', label=name)
pyplot.plot(x, exact_sol(x), '-', label="Exact Solution")
pyplot.xlabel("x")
pyplot.ylabel("y")
pyplot.legend()
pyplot.show()
if __name__ == "__main__": if __name__ == "__main__":
test_integrator() np.random.seed(0)
#test_integrator_singlestep()
test_integrator_multistep()