用于求解 ODE 系统的 Runge-Kutta 4 Python
Runge-Kutta 4 for solving systems of ODEs Python
我为 Runge-Kutta 4 编写了代码来求解 ODE 系统。
它适用于一维 ODE 但是当我尝试解决 x'' + kx = 0
我在尝试定义矢量函数时遇到问题:
让u1 = x
和u2 = x' = u1'
,那么系统看起来像:
u1' = u2
u2' = -k*u1
如果u = (u1,u2)
和f(u, t) = (u2, -k*u1)
,那么我们需要求解:
u' = f(u, t)
def f(u,t, omega=2):
u, v = u
return np.asarray([v, -omega**2*u])
我的全部代码是:
import numpy as np
def ode_RK4(f, X_0, dt, T):
N_t = int(round(T/dt))
# Create an array for the functions ui
u = np.zeros((len(X_0),N_t+1)) # Array u[j,:] corresponds to the j-solution
t = np.linspace(0, N_t*dt, N_t + 1)
# Initial conditions
for j in range(len(X_0)):
u[j,0] = X_0[j]
# RK4
for j in range(len(X_0)):
for n in range(N_t):
u1 = f(u[j,n] + 0.5*dt* f(u[j,n], t[n])[j], t[n] + 0.5*dt)[j]
u2 = f(u[j,n] + 0.5*dt*u1, t[n] + 0.5*dt)[j]
u3 = f(u[j,n] + dt*u2, t[n] + dt)[j]
u[j, n+1] = u[j,n] + (1/6)*dt*( f(u[j,n], t[n])[j] + 2*u1 + 2*u2 + u3)
return u, t
def demo_exp():
import matplotlib.pyplot as plt
def f(u,t):
return np.asarray([u])
u, t = ode_RK4(f, [1] , 0.1, 1.5)
plt.plot(t, u[0,:],"b*", t, np.exp(t), "r-")
plt.show()
def demo_osci():
import matplotlib.pyplot as plt
def f(u,t, omega=2):
# u, v = u Here I've got a problem
return np.asarray([v, -omega**2*u])
u, t = ode_RK4(f, [2,0], 0.1, 2)
for i in [1]:
plt.plot(t, u[i,:], "b*")
plt.show()
提前谢谢。
模型是这样的:
enter image description here
摘自 Langtangen 的《计算编程》一书 - Python。
您走在正确的道路上,但是当将 time-integration 方法(例如 RK)应用于向量值 ODE 时,基本上与标量情况完全相同,只是使用向量。
因此,您跳过 for j in range(len(X_0))
循环和关联的索引,并确保将初始值作为向量(numpy 数组)传递。
还稍微清理了 t
的索引并将解决方案存储在列表中。
import numpy as np
def ode_RK4(f, X_0, dt, T):
N_t = int(round(T/dt))
# Initial conditions
usol = [X_0]
u = np.copy(X_0)
tt = np.linspace(0, N_t*dt, N_t + 1)
# RK4
for t in tt[:-1]:
u1 = f(u + 0.5*dt* f(u, t), t + 0.5*dt)
u2 = f(u + 0.5*dt*u1, t + 0.5*dt)
u3 = f(u + dt*u2, t + dt)
u = u + (1/6)*dt*( f(u, t) + 2*u1 + 2*u2 + u3)
usol.append(u)
return usol, tt
def demo_exp():
import matplotlib.pyplot as plt
def f(u,t):
return np.asarray([u])
u, t = ode_RK4(f, np.array([1]) , 0.1, 1.5)
plt.plot(t, u, "b*", t, np.exp(t), "r-")
plt.show()
def demo_osci():
import matplotlib.pyplot as plt
def f(u,t, omega=2):
u, v = u
return np.asarray([v, -omega**2*u])
u, t = ode_RK4(f, np.array([2,0]), 0.1, 2)
u1 = [a[0] for a in u]
for i in [1]:
plt.plot(t, u1, "b*")
plt.show()
我为 Runge-Kutta 4 编写了代码来求解 ODE 系统。
它适用于一维 ODE 但是当我尝试解决 x'' + kx = 0
我在尝试定义矢量函数时遇到问题:
让u1 = x
和u2 = x' = u1'
,那么系统看起来像:
u1' = u2
u2' = -k*u1
如果u = (u1,u2)
和f(u, t) = (u2, -k*u1)
,那么我们需要求解:
u' = f(u, t)
def f(u,t, omega=2):
u, v = u
return np.asarray([v, -omega**2*u])
我的全部代码是:
import numpy as np
def ode_RK4(f, X_0, dt, T):
N_t = int(round(T/dt))
# Create an array for the functions ui
u = np.zeros((len(X_0),N_t+1)) # Array u[j,:] corresponds to the j-solution
t = np.linspace(0, N_t*dt, N_t + 1)
# Initial conditions
for j in range(len(X_0)):
u[j,0] = X_0[j]
# RK4
for j in range(len(X_0)):
for n in range(N_t):
u1 = f(u[j,n] + 0.5*dt* f(u[j,n], t[n])[j], t[n] + 0.5*dt)[j]
u2 = f(u[j,n] + 0.5*dt*u1, t[n] + 0.5*dt)[j]
u3 = f(u[j,n] + dt*u2, t[n] + dt)[j]
u[j, n+1] = u[j,n] + (1/6)*dt*( f(u[j,n], t[n])[j] + 2*u1 + 2*u2 + u3)
return u, t
def demo_exp():
import matplotlib.pyplot as plt
def f(u,t):
return np.asarray([u])
u, t = ode_RK4(f, [1] , 0.1, 1.5)
plt.plot(t, u[0,:],"b*", t, np.exp(t), "r-")
plt.show()
def demo_osci():
import matplotlib.pyplot as plt
def f(u,t, omega=2):
# u, v = u Here I've got a problem
return np.asarray([v, -omega**2*u])
u, t = ode_RK4(f, [2,0], 0.1, 2)
for i in [1]:
plt.plot(t, u[i,:], "b*")
plt.show()
提前谢谢。
模型是这样的: enter image description here
摘自 Langtangen 的《计算编程》一书 - Python。
您走在正确的道路上,但是当将 time-integration 方法(例如 RK)应用于向量值 ODE 时,基本上与标量情况完全相同,只是使用向量。
因此,您跳过 for j in range(len(X_0))
循环和关联的索引,并确保将初始值作为向量(numpy 数组)传递。
还稍微清理了 t
的索引并将解决方案存储在列表中。
import numpy as np
def ode_RK4(f, X_0, dt, T):
N_t = int(round(T/dt))
# Initial conditions
usol = [X_0]
u = np.copy(X_0)
tt = np.linspace(0, N_t*dt, N_t + 1)
# RK4
for t in tt[:-1]:
u1 = f(u + 0.5*dt* f(u, t), t + 0.5*dt)
u2 = f(u + 0.5*dt*u1, t + 0.5*dt)
u3 = f(u + dt*u2, t + dt)
u = u + (1/6)*dt*( f(u, t) + 2*u1 + 2*u2 + u3)
usol.append(u)
return usol, tt
def demo_exp():
import matplotlib.pyplot as plt
def f(u,t):
return np.asarray([u])
u, t = ode_RK4(f, np.array([1]) , 0.1, 1.5)
plt.plot(t, u, "b*", t, np.exp(t), "r-")
plt.show()
def demo_osci():
import matplotlib.pyplot as plt
def f(u,t, omega=2):
u, v = u
return np.asarray([v, -omega**2*u])
u, t = ode_RK4(f, np.array([2,0]), 0.1, 2)
u1 = [a[0] for a in u]
for i in [1]:
plt.plot(t, u1, "b*")
plt.show()