La oss bruke MMS på følgende differensialligning: $$ \begin{align} \label{eq:simple_linear_ode} u'' + u^2 = g \end{align} $$
Denne ligningen kan omgjøres til et system av førsteordens differensialligninger (ved bruk av \( u_0 = u \)): $$ \begin{align*} u_0'&= u_1& \\ u_1'&= g - u_0^2& \end{align*} $$
Predictor: $$ \begin{align*} u_0^p&=(u_0)_n+h\cdot (u_1)_n& \\ u_1^p&=(u_1)_n+h\cdot \left[g(t_n) - (u_0)_n^2\right]& \end{align*} $$
Corrector: $$ \begin{align*} (u_0)_{n+1}&=(u_0)_n+0.5h\cdot [(u_1)_n+(u_1^p)]&\\ (u_1)_{n+1}&=(u_1)_n+0.5h\cdot \left[\left(g(t_n) - \left((u_0)_n\right)^2\right) + \left(g(t_n+ h) - \left(u_0^p\right)^2\right)\right]& \end{align*} $$
eller ved å innføre vektorer: $$ \begin{equation} \label{eq:3102} \boldsymbol{U}' = \begin{bmatrix} u_0' \\ u_1' \end{bmatrix} = \begin{bmatrix} u_1 \\ g - u_0^2 \end{bmatrix} \end{equation} $$
predictor: $$ \begin{equation} \boldsymbol{U}_{n+1}^p = \begin{bmatrix} u_0^p \\ u_1^p \end{bmatrix} = \boldsymbol{U}_n + h \cdot \boldsymbol{U}_{n}' \end{equation} $$
corrector: $$ \begin{equation} \boldsymbol{U}_{n+1} = \begin{bmatrix} (u_0)_{n+1} \\ (u_1)_{n+1} \end{bmatrix} = \boldsymbol{U}_n + \frac{h}{2} \cdot \left[\boldsymbol{U}_{n}' + \boldsymbol{U'}_{n+1}^{p}\right] \end{equation} $$
# lectures/lec-16.02/example1.py
import numpy as np
import sympy as sp
import matplotlib.pylab as plt
from math import pi, sqrt
def dUfunc(U, tau):
u0 = U[0]
u1 = U[1]
du0 = u1
du1 = g_py(tau) - u0**2
return np.array([du0, du1])
# main program starts here:
t = sp.symbols('t')
um = sp.sin(t**2)
du = sp.diff(um, t)
ddu = sp.diff(du, t)
g = ddu + um**2
um_py = sp.lambdify(t, um, np)
du_py = sp.lambdify(t, du, np)
g_py = sp.lambdify(t, g, np)
t0, tend = 0, 2*pi
N = 200*2
time = np.linspace(t0, tend, N)
h = time[1]-time[0]
U_0 = [um_py(t0), du_py(0)]
U = np.zeros((N, 2))
U[0][0]= U_0[0]
U[0][1]= U_0[1]
for n, tau in enumerate(time[0: -1]):
Un = U[n, :]
Up = Un + h*dUfunc(Un, tau)
Un1 = Un + 0.5*h*(dUfunc(Un, tau) + dUfunc(Up, tau + h))
U[n+1, :] = Un1
u_num = U[:, 0]
u_man = um_py(time)
rms = np.max(np.abs(u_num-u_man))
print "rms error: ", rms
plt.figure()
plt.plot(time, u_man, 'k')
plt.plot(time, u_num, 'r--')
plt.legend(['manufactured', 'numeric'], frameon=False)
plt.show()
# lectures/lec-16.02/example2.py
import numpy as np
import sympy as sp
import matplotlib.pylab as plt
from math import pi, sqrt
def dUfunc(U, tau):
u0 = U[0]
u1 = U[1]
du0 = u1
du1 = g_py(tau) - u0**2
return np.array([du0, du1])
def heun_gen(dUfunc, U_0, time):
U = np.zeros((len(time), len(U_0)))
U[0,:] = U_0
for n, tau in enumerate(time[0:-1]):
h = time[n + 1] - time[n]
Un = U[n,:]
k1 = dUfunc(Un, tau)
k2 = dUfunc(Un + h*k1, tau + h)
U[n + 1,:] = Un + h*(0.5*k1 + 0.5*k2)
return U
# main program starts here:
t = sp.symbols('t')
um = sp.sin(t**2)
du = sp.diff(um, t)
ddu = sp.diff(du, t)
g = ddu + um**2
um_py = sp.lambdify(t, um, np)
du_py = sp.lambdify(t, du, np)
g_py = sp.lambdify(t, g, np)
t0, tend = 0, 2*pi
N = 20
time = np.linspace(t0, tend, N)
U_0 = [um_py(t0), du_py(0)]
Ntds = 7
orderList = []
for i in range(Ntds):
U = heun_gen(dUfunc, U_0, time)
u_num = U[:, 0]
u_man = um_py(time)
error = np.max(np.abs(u_num-u_man))
if i>0:
O = np.log(prev_error/error)/np.log(2)
orderList.append(O)
prev_error = error
N *= 2
time = np.linspace(t0, tend, N)
print orderList
plt.figure()
plt.plot(orderList)
plt.show()