我正在使用scipy.odint()模拟双摆翻转时间。我的代码是结构化的,scipy在给定的时间内解决了整个系统;那么我必须检查阵列,看看是否发生了翻转。我想检查,在解决每个步骤后,是否满足条件,然后不需要解决数组的其余部分。
这是我当前的代码:
from matplotlib.colors import LogNorm, Normalize
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from tqdm import tqdm
import seaborn as sns
import numpy as np
def ode(y, t, length_1, length_2, mass_1, mass_2, gravity):
angle_1, angle_1_d, angle_2, angle_2_d = y
angle_1_dd = (-gravity * (2 * mass_1 + mass_2) * np.sin(angle_1) - mass_2 * gravity * np.sin(angle_1 - 2 * angle_2) - 2 * np.sin(angle_1 - angle_2) * mass_2 * (angle_2_d ** 2 * length_2 + angle_1_d ** 2 * length_1 * np.cos(angle_1 - angle_2))) / (length_1 * (2 * mass_1 + mass_2 - mass_2 * np.cos(2 * angle_1 - 2 * angle_2)))
angle_2_dd = (2 * np.sin(angle_1 - angle_2) * (angle_1_d ** 2 * length_1 * (mass_1 + mass_2) + gravity * (mass_1 + mass_2) * np.cos(angle_1) + angle_2_d ** 2 * length_2 * mass_2 * np.cos(angle_1 - angle_2))) / (length_2 * (2 * mass_1 + mass_2 - mass_2 * np.cos(2 * angle_1 - 2 * angle_2)))
return [angle_1_d, angle_1_dd, angle_2_d, angle_2_dd]
def double_pendulum(length_1, length_2, mass_1, mass_2, angle_1_init, angle_2_init, angle_1_d_init, angle_2_d_init, gravity, dt, num_steps):
time_span = np.linspace(0, dt*num_steps, num_steps)
y0 = [np.deg2rad(angle_1_init), np.deg2rad(angle_1_d_init), np.deg2rad(angle_2_init), np.deg2rad(angle_2_d_init)]
sol = odeint(ode, y0, time_span, args=(length_1, length_2, mass_1, mass_2, gravity))
return sol
def flip(length_1, length_2, mass_1, mass_2, angle_1_init, angle_2_init, angle_1_d_init, angle_2_d_init, gravity, dt, num_steps):
solution = double_pendulum(length_1, length_2, mass_1, mass_2, angle_1_init, angle_2_init, angle_1_d_init, angle_2_d_init, gravity, dt, num_steps)
#angle_1 = solution[:, 0]
angle_2 = solution[:, 2]
for index, angle2 in enumerate(angle_2):
if abs(angle2 - angle_2_init) >= 2*np.pi:
return index*dt
return dt*num_steps
angle_1_range = np.arange(-172, 172, 1)
angle_2_range = np.arange(-172, 172, 1)
fliptime_matrix = np.zeros((len(angle_1_range), len(angle_2_range)))
for i, angle_1 in tqdm(enumerate(angle_1_range), desc='angle_1'):
for j, angle_2 in tqdm(enumerate(angle_2_range), desc='angle_2', leave=False):
fliptime = flip(1, 1, 1, 1, angle_1, angle_2, 0, 0, 9.81, 0.01, 10000)
fliptime_matrix[i, j] = fliptime
sns.heatmap(fliptime_matrix, square=True, cbar_kws={'label': 'Divergence'}, norm=LogNorm())
plt.xlabel('Angle 2 (degrees)')
plt.ylabel('Angle 1 (degrees)')
plt.title('Fliptime Heatmap')
plt.gca().invert_yaxis()
plt.show()
我想在每个状态求解后检查翻转条件(差值大于2*pi),而不是在整个系统(在给定时间内)求解后。我需要指导的主要函数是double_pendulum()和flip()。
谢谢