大角度單擺程式模擬 內容更新: 畫出大角度單擺的 phase diagram,並分析初始角速度𝜔𝜔不同的情形。 前三頁的內容皆是更新的內容,四到七頁的內容則與上次相同。 簡易描述: 初始角速度𝜔𝜔 = 0,從初始擺角𝜃𝜃 = 15°開始,每15°將角速度𝜔𝜔對角度𝜃𝜃作一次 圖直到初始擺角𝜃𝜃 = 360°,結果如圖(一),並對比網路資料的 phase diagram 如 圖(二)。 圖(一)程式模擬出的 phase diagram,初始角速度𝜔𝜔 = 0 參考網路的 phase diagram 如圖(二): 圖(二)網路資料上的 phase diagram 1 內容分析: 對比之後可以發現兩者有兩個差異,首先是我的 phase diagram 沒有 separatrix 那條通過𝜃𝜃 = 𝜋𝜋的紅線,其原因在於當初始擺角𝜃𝜃 = 𝜋𝜋時,單擺根本不會往下掉 落而產生震盪,而是筆直地待在上方,雖然其狀態為不穩定狀態,在現實中會 隨機朝一邊落下,但程式無法模擬這點,因此𝜃𝜃 = 𝜋𝜋沒有圖形。 第二則是我並沒有 open 那幾條紫色的線,其原因在於單擺初始角速度𝜔𝜔 = 0, 其運動能量皆從位能轉變為動能而來,因此擺盪高度的最極限即為初始高度, 不會出現單擺順時針或逆時針轉動的狀況,自然也沒有後續的圖形。 在簡單分析後,我發現第一個問題可能無法解決,或者說這樣的情況根本不會 發生,因為若要貼近網路資料上的 phase diagram,這兩個問題皆可以透過令初 始角速度𝜔𝜔 ≠ 0,只要單擺在運動前有個初始的角速度,即可突破回到原位置的 限制而轉進行轉動,為方便模擬此處即令𝜔𝜔 = 2,為了展示得更清楚,從初始擺 角𝜃𝜃 = −360°開始,每15°將角速度𝜔𝜔對角度𝜃𝜃作一次圖直到初始擺角𝜃𝜃 = 360°, 結果如圖(三),可以看到 phase diagram 上方多了一些代表逆時針旋轉的線條。 圖(三)程式模擬出的 phase diagram,初始角速度𝜔𝜔 = 2 相反的,只要將令初始擺角𝜔𝜔 = −2,即可得到開放線條在下方的 phase diagram,如圖(四)。 2 圖(三)程式模擬出的 phase diagram,初始角速度𝜔𝜔 = −2 程式碼改動: while angle <= 360: while t < tf: theta, omega = runge_kutta_step(theta, omega, t, dt) time_points.append(t) theta_points.append(theta) omega_points.append(omega) t += dt theta_degrees = np.degrees(theta_points) plt.plot(theta_degrees, omega_points) t = t0 angle += 15 theta0_deg = angle theta0 = np.radians(theta0_deg) theta = theta0 omega = omega0 time_points = [t0] theta_points = [theta0] omega_points = [omega0] plt.show() 3 公式: (1) 𝑑𝑑𝑑𝑑 (2) 𝑑𝑑𝑑𝑑 = 𝜔𝜔 𝑑𝑑𝑑𝑑 𝑑𝑑𝑑𝑑 𝑔𝑔 = − 𝑠𝑠𝑠𝑠𝑠𝑠𝜃𝜃 𝐿𝐿 Runge-Kutta 4th order method: 𝑑𝑑𝑑𝑑 𝑑𝑑𝑑𝑑 = 𝑓𝑓(𝑥𝑥, 𝑡𝑡) xk+1=xk + t/6(f1+2f2+2f3+f4) f1=(xk, tk) f2=(xk + dt/2*f1, tk + dt/2) f3=(xk + dt/2*f2, tk + dt/2) f4=(xk + dt*f3, tk + dt) where 摘要: 在程式中利用式(1)、式(2)定義微分,再利用上述公式定義 Runge-Kutta 4th order method,重複對 與 執行 Runge-Kutta 4th order method,將角度對時間作 圖,以模擬大角度單擺的角度與時間關係,並計算其週期。其中此模型假設擺長 =1m、dt=0.00001s、紀錄時間=10s、初始擺角=10 度,以上四項參數皆可調整, 程式碼(已詳細加上註解)與作圖將附在以下數頁。 不同初始擺角之週期計算(由於 dt=0.00001,取到小數點第五位): 1. 10 度: 2.00944 s 2. 30 度: 2.04073 s 3. 50 度: 2.10572 s 4. 70 度: 2.21079 s 5. 90 度: 2.36766 s 4 import numpy as np import matplotlib.pyplot as plt # Constants g = 9.81 # g L = 1.0 # Length of the pendulum # Initial conditions theta0_deg = 10.0 # Initial angle in degrees theta0 = np.radians(theta0_deg) # Convert to radians omega0 = 0.0 # Initial angular velocity # Time parameters t0 = 0.0 # Initial time tf = 10.0 # Final time dt = 0.00001 # Time step # Function to compute derivatives of theta and omega def derivatives(theta, omega, t): dtheta_dt = omega domega_dt = -(g / L) * np.sin(theta) return dtheta_dt, domega_dt # Runge-Kutta 4th order method def runge_kutta_step(theta, omega, t, dt): k1_theta, k1_omega = derivatives(theta, omega, t) k2_theta, k2_omega = derivatives(theta + 0.5 * k1_theta * dt, omega + 0.5 * k1_omega * dt, t + 0.5 * dt) k3_theta, k3_omega = derivatives(theta + 0.5 * k2_theta * dt, omega + 0.5 * k2_omega * dt, t + 0.5 * dt) k4_theta, k4_omega = derivatives(theta + k3_theta * dt, omega + k3_omega * dt, t + dt) theta_new = theta + (dt / 6.0) * (k1_theta + 2 * k2_theta + 2 * k3_theta + k4_theta) omega_new = omega + (dt / 6.0) * (k1_omega + 2 * k2_omega + 2 * k3_omega + k4_omega) return theta_new, omega_new 5 # Initialize arrays to store the results time_points = [t0] theta_points = [theta0] omega_points = [omega0] # Initialize a flag to detect when the pendulum returns to its initial position returning = False # Perform the simulation using RK4 t = t0 theta = theta0 omega = omega0 while t < tf: theta, omega = runge_kutta_step(theta, omega, t, dt) t += dt time_points.append(t) theta_points.append(theta) omega_points.append(omega) # Check if the pendulum has returned to its initial position (within a small tolerance) if not returning and abs(theta - initial_theta) < np.radians(0.00001) and t>1 : period = t - t0 print(f'Period of the pendulum:{period:.5f} seconds') returning = True # Convert theta back to degrees for plotting theta_degrees = np.degrees(theta_points) # Plot the pendulum's motion plt.figure() plt.plot(time_points, theta_degrees) plt.xlabel('Time (s)') plt.ylabel('Angle (degrees)') plt.title('Pendulum Simulation (RK4) - Initial Angle = 10 degrees') plt.grid(True) plt.show() 6 參考資料: https://www.youtube.com/watch?v=HOWJp8NV5xU https://www.youtube.com/watch?v=vNoFdtcPFdk https://stackoverflow.com/questions/52985027/runge-kutta-4-and-pendulumsimulation-in-python 7