# Blatt 9 Aufgabe 5 import numpy as np import matplotlib.pyplot as plt # Const m1 = 1.0 # kg m2 = 1.0 # kg l = 1.0 # m g = 9.81 # m/s^2 # Params T = 30.0#s dt = 1e-4 # Timestep dt2 = 1e-5 # Timestep 2 (very long times) # Initial conditions theta1_0 = np.pi / 2 theta2_0 = np.pi omega1_0 = 0.0 omega2_0 = 0.0 def a(theta, omega): # Unpack the params theta1, theta2 = theta omega1, omega2 = omega delta = theta1 - theta2 # Represent the equation in terms of M and Q # L, m1, m2 not used for the matrix equation ?? # Do I need to use the result from task a) ? M = np.array([ [2, np.cos(delta)], [np.cos(delta), 1] ]) Q = np.array([ -omega2**2 * np.sin(delta) - 2 * g * np.sin(theta1), omega1**2 * np.sin(delta) - g * np.sin(theta2) ]) # TODO: better method? return np.linalg.solve(M, Q) # Return the acc in a theta double dot vector # Run the main simulation def run_simulation(theta0, omega0, dt): # Setup state arrays times = np.arange(0, T, dt) theta = np.zeros((len(times), 2)) omega = np.zeros((len(times), 2)) energy = np.zeros(len(times)) # Initialize theta[0] = theta0 omega[0] = omega0 acc = a(theta[0], omega[0]) print(acc) # Iterate for i in range(1, len(times)): # VV-step theta[i] = theta[i-1] + omega[i-1] * dt + 0.5 * acc * dt**2 a_new = a(theta[i], omega[i-1]) omega[i] = omega[i-1] + 0.5 * (acc + a_new) * dt acc = a_new # Energy theta1, theta2 = theta[i] omega1, omega2 = omega[i] E_kin = 0.5 * m1 * (l * omega1)**2 + 0.5 * m2 * ( (l * omega1)**2 + (l * omega2)**2 + 2 * l**2 * omega1 * omega2 * np.cos(theta1 - theta2) ) E_pot = - (m1 + m2) * g * l * np.cos(theta1) - m2 * g * l * np.cos(theta2) # Save the total energy energy[i] = E_kin + E_pot # Return timeline return times, theta, omega, energy # Start simulation theta0 = [theta1_0, theta2_0] omega0 = [omega1_0, omega2_0] times, theta, _, energy = run_simulation(theta0, omega0, dt) theta0 = [theta1_0 + 10 ** -7, theta2_0] omega0 = [omega1_0, omega2_0] _, theta2, _, _ = run_simulation(theta0, omega0, dt) theta0 = [theta1_0, theta2_0] omega0 = [omega1_0, omega2_0] times3, theta3, _, energy3 = run_simulation(theta0, omega0, dt2) # Smaller timestep # Quick plotting # Energy plt.figure(figsize=(12, 6)) plt.plot(times, energy, label='Total energy', color='blue') plt.plot(times3, energy3, label='Total energy smaller dt', color='blue', linestyle="--") plt.xlabel('Time [s]') plt.ylabel('Energy [J]') plt.title('Total energy of the double pendulum') plt.grid(True) plt.legend() plt.tight_layout() plt.savefig("double_energy.svg") # Angles plt.figure(figsize=(12, 6)) # Reduce angles theta_mod = (theta + np.pi) % (2 * np.pi) - np.pi theta2_mod = (theta2 + np.pi) % (2 * np.pi) - np.pi # Plot with module (less information) #plt.figure(figsize=(12, 6)) #plt.plot(times, theta_mod[:, 0], label=r'$\theta_1(t)$', color='red') #plt.plot(times, theta_mod[:, 1], label=r'$\theta_2(t)$', color='green') #plt.plot(times, theta2_mod[:, 0], label=r'$\theta_1(t)$ (small change)', color='blue') #plt.plot(times, theta2_mod[:, 1], label=r'$\theta_2(t)$ (small change)', color='gold') plt.plot(times, theta[:, 0] , label=r'$\theta_1(t)$', color='red') plt.plot(times, theta[:, 1] , label=r'$\theta_2(t)$', color='green') plt.plot(times3, theta3[:, 0] , label=r'$\theta_1(t)$ smaller dt', color='red', linestyle="--") plt.plot(times3, theta3[:, 1] , label=r'$\theta_2(t)$ smaller dt', color='green', linestyle="--") plt.plot(times, theta2[:, 0] , label=r'$\theta_1(t)$ changed', color='blue') plt.plot(times, theta2[:, 1] , label=r'$\theta_2(t)$ changed', color='yellow') plt.xlabel('Time [s]') plt.ylabel('Angle [rad]') plt.title('Trajectories of both pendulums') plt.legend() plt.grid(True) plt.tight_layout() plt.savefig("double_angles.svg")