Uploaded by 簡千翔

大角度單擺程式模擬(範例)

advertisement
大角度單擺程式模擬
內容更新:
畫出大角度單擺的 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
Download