我正在尝试使用弹簧质量耦合系统编写程序。解决使用ODE的问题
import numpy as np
import matplotlib.pyplot as plt
kitchen1 = 2.0
kitchen2 = 2.0
money1 = 2.0
money2 = 2.0
walk1 = 5.0
walk2 = 5.0
Lenon1 = 2.0
Lenon2 = 2.0
def f1(x1, v1, x2, v2, t):
return v1
def f2 (x1, v1, x2, v2, t):
return ((-kitchen1/money1)*(x1-Lenon1)) + (kitchen2/money1*(x2-x1-walk1- Lenon2))
def f3(x1, v1, x2, v2, t):
return v2
def f4(x1, v1, x2, v2, t):
return (-kitchen2/money2) * (x2-x1-walk1-Lenon2)
def rk4_gen(x1_arr, v1_arr, x2_arr, v2_arr, t_arr, h):
x1, v1, x2, v2, t = t_arr[0], x1_arr[0], v1_arr[0], x2_arr[0], v2_arr[0]
for i in range(1,len(t)):
t, h = t[i-1], t[i]-t[i-1]
k11 = h*f1(x1, v1, x2, v2, t)
k12 = h*f2(x1, v1, x2, v2, t)
k13 = h*f3(x1, v1, x2, v2, t)
k14 = h*f4(x1, v1, x2, v2, t)
k21 = h*f1(x1+k11/2.0, v1+k12/2.0,x2+k13/2.0,v2+k14/2.0, t+h/2.0)
k22 = h*f2(x1+k11/2.0, v1+k12/2.0,x2+k13/2.0,v2+k14/2.0, t+h/2.0)
k23 = h*f3(x1+k11/2.0, v1+k12/2.0,x2+k13/2.0,v2+k14/2.0, t+h/2.0)
k24 = h*f4(x1+k11/2.0, v1+k12/2.0,x2+k13/2.0,v2+k14/2.0, t+h/2.0)
k31 = h*f1(x1+k21/2.0, v1+k22/2.0,x2+k23/2.0,v2+k24/2.0, t+h/2.0)
k32 = h*f2(x1+k21/2.0, v1+k22/2.0,x2+k23/2.0,v2+k24/2.0, t+h/2.0)
k33 = h*f3(x1+k21/2.0, v1+k22/2.0,x2+k23/2.0,v2+k24/2.0, t+h/2.0)
k34 = h*f4(x1+k21/2.0, v1+k22/2.0,x2+k23/2.0,v2+k24/2.0, t+h/2.0)
k41 = h*f1(x1+k31, v1+k32,x2+k33,v2+k34, t+h)
k42 = h*f2(x1+k31, v1+k32,x2+k33,v2+k34, t+h)
k43 = h*f3(x1+k31, v1+k32,x2+k33,v2+k34, t+h)
k44 = h*f4(x1+k31, v1+k32,x2+k33,v2+k34, t+h)
x1 = x1 + (k11 + 2*k12 + 2*k13 + k14)/6.0
v1 = v1 + (k21 + 2*k22 + 2*k23 + k24)/6.0
x2 = x2 + (k31 + 2*k32 + 2*k33 + k34)/6.0
v2 = v2 + (k41 + 2*k42 + 2*k43 + k44)/6.0
x1_arr[i], v1_arr[i], x2_arr[i], v2_arr[i] = x1, v1, x2, v2
return x1_arr, v1_arr , x2_arr , v2_arr, t_arr
def grafik_ciz(t,y,x_baslik,y_baslik,baslik):
plt.figure(figsize = [12, 9])
plt.plot(t,y)
plt.xlabel(x_baslik)
plt.ylabel(y_baslik)
plt.title(baslik)
plt.grid()
plt.show()
ti = 0
tf = 20
x1 = 2
v1 = 0
x2 = 15
v2 = 0
h = 0.5
t = np.arange(ti,tf+h,h)
x1 = np.zeros(len(t))
v1 = np.zeros(len(t))
x2 = np.zeros(len(t))
v2 = np.zeros(len(t))
x1[0] = x1i
v1[0] = v1i
x2[0] = x2i
v2[0] = v2i
x1 = rk4_gen(x1_arr, v1_arr, x2_arr, v2_arr, t_arr, h
print x1
使用四阶Runge-Kutta方法
我需要绘制一个图表,显示x和y随时间的变化,从t = 0到t = 20。
错误m.ValueError:太多值无法解压缩
到目前为止,这是我的代码,但图中没有显示任何内容。
我认为,此错误是t = np.arange(ti,tf+h,h)
。
我需要绘制一个图表,显示x1和v1随时间的变化,从t = 0到t = 20。
答案 0 :(得分:0)
除了在正确实施算法,使用一致的函数接口,使用正确的函数名称等方面存在许多错误之外。
您报告的问题是,您在执行单个RK4步骤时不会解压缩传递给rk4_gen
的数组。您可以做的太多更改就是重命名in
def rk4_gen(t_arr, x1_arr, v1_arr, x2_arr, v2_arr, h):
(为什么要通过h
?在每一步中您都可以计算出正确的h=t[i]-t[i-1]
)。然后初始化运行变量
t, x1, v1, x2, v2 = t_arr[0], x1_arr[0], v1_arr[0], x2_arr[0], v2_arr[0]
执行(更正的)RK4步骤,并在每个步骤结束时将计算值保存到数组中
def rk4_gen(x1_arr, v1_arr, x2_arr, v2_arr, t_arr, h):
t, x1, v1, x2, v2 = t_arr[0], x1_arr[0], v1_arr[0], x2_arr[0], v2_arr[0]
for i in range(1,len(t_arr)):
# Do the RK4 step, it is from i-1 to i
t, h = t_arr[i-1], t_arr[i]-t_arr[i-1]
k11 = h*f1(...)
...
v2 = v_2+(k14+2*k24+2*k34+k44)/6.0
x1_arr[i], v1_arr[i], x2_arr[i], v2_arr[i] = x1, v1, x2, v2
return x1_arr, v1_arr , x2_arr , v2_arr, t_arr
还请注意,您的精加工计算具有k
个值,它们的顺序相反。
您可以使用scipy.integrate
方法以更紧凑的方式解决此问题,例如
from scipy.integrate import solve_ivp
def spring_ode(t,u):
x1,v1,x2,v2 = u
a1 = ((-kitchen1/money1)*(x1-Lenon1)) + (kitchen2/money1*(x2-x1-walk1- Lenon2))
a2 = (-kitchen2/money2) * (x2-x1-walk1-Lenon2)
return [v1,a1,v2,a2]
res = solve_ivp(spring_ode, [ti,tf], [x1i,v1i,x2i,v2i], dense_output=True, rtol=1e-12, atol=1e-14)
h=0.02
t = np.arange(ti,tf+h/2,h)
u = res.sol(t)
x1,v1,x2,v2 = u
plt.figure(figsize = [8, 5])
plt.plot(t,x1,t,x2); plt.legend(["$x_1$","$x_2$"])
plt.grid(); plt.show()
及其结果图