0% found this document useful (0 votes)
3 views

Assignment 9

The document presents a simulation of a nonlinear pendulum and a driven pendulum using the Runge-Kutta 4th order method for numerical integration. It includes code for plotting the angle of the pendulum over time and creating animations for both types of pendulums. Additionally, it explores the resonant frequency of the driven pendulum and visualizes the results through various plots.

Uploaded by

Sougata Halder
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Assignment 9

The document presents a simulation of a nonlinear pendulum and a driven pendulum using the Runge-Kutta 4th order method for numerical integration. It includes code for plotting the angle of the pendulum over time and creating animations for both types of pendulums. Additionally, it explores the resonant frequency of the driven pendulum and visualizes the results through various plots.

Uploaded by

Sougata Halder
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 4

Assignment-9

March 27, 2025

[9]: import numpy as np


import matplotlib.pyplot as plt
from matplotlib import animation, rc
import math

# Parameters for nonlinear pendulum


g = 9.8
l = 0.1 # 10 cm
theta0 = np.radians(179) # Initial angle in radians
omega0 = 0.0
t_start = 0
t_end = 20 # Simulate for 20 seconds
dt = 0.01 # Time step

# Define the ODE system for the nonlinear pendulum


def pendulum_ode(y, t):
theta, omega = y
dtheta = omega
domega = -(g / l) * np.sin(theta)
return np.array([dtheta, domega])

# RK-4 Method (your version)


def RK4(t0, tn, y0, f, n=10000):
t = np.linspace(t0, tn, n)
h = (tn - t0) / n
y = np.zeros(shape=(n, y0.size))
y[0, :] = y0
for i in range(1, n):
k1 = h * f(y[i-1], t[i-1])
k2 = h * f(y[i-1] + k1/2, t[i-1] + h/2)
k3 = h * f(y[i-1] + k2/2, t[i-1] + h/2)
k4 = h * f(y[i-1] + k3, t[i-1] + h)
y[i] = y[i-1] + (k1 + 2*k2 + 2*k3 + k4) / 6
return y, t

# Perform RK4 integration for the nonlinear pendulum


n_steps = int((t_end - t_start) / dt)

1
y_values, t_values = RK4(t_start, t_end, np.array([theta0, omega0]),␣
↪pendulum_ode, n_steps)

theta_values = y_values[:, 0]

# Plot � vs. time for the nonlinear pendulum


plt.figure(figsize=(10, 5))
plt.plot(t_values, np.degrees(theta_values))
plt.xlabel('Time (s)')
plt.ylabel('� (degrees)')
plt.title('Nonlinear Pendulum (�� = 179°)')
plt.grid(True)
plt.show()

# Animation for the nonlinear pendulum


def animate_pendulum(t_values, theta_values, l):
fig, ax = plt.subplots()
ax.set_xlim((-1.1*l, 1.1*l))
ax.set_ylim((-1.1*l, 1.1*l))
ax.set_aspect('equal')
line, = ax.plot([], [], 'o-', lw=2, markersize=10)

def init():
line.set_data([], [])
return line,

def update(frame):
theta = theta_values[frame]
x = l * np.sin(theta)
y = -l * np.cos(theta) # Negative because y-axis points upward
line.set_data([0, x], [0, y])
return line,

# Downsample frames for smoother animation (~50 FPS)


frame_step = max(1, int(0.02 / dt))
ani = animation.FuncAnimation(fig, update, frames=range(0, len(t_values),␣
↪frame_step),

init_func=init, blit=True, interval=20)


plt.close()
return ani

rc('animation', html='jshtml')
animate_pendulum(t_values, theta_values, l)

2
[9]: <matplotlib.animation.FuncAnimation at 0x105cc7e10>

[7]: # Parameters for driven pendulum


C = 2.0 # s�²
Omega = 5.0 # s�¹ (initial value)
theta0_driven = 0.0
omega0_driven = 0.0
t_end_driven = 100.0

# Modified driven pendulum ODE function (argument order: state, time,␣


↪parameters)

def driven_pendulum_ode(y, t, C, Omega):


theta, omega = y
dtheta = omega
domega = -(g / l) * np.sin(theta) + C * np.cos(theta) * np.sin(Omega * t)
return np.array([dtheta, domega])

# For the driven case, we now use RK4 with extra parameters.
def RK4_driven(t0, tn, y0, f, n, *params):
t = np.linspace(t0, tn, n)
h = (tn - t0) / n
y = np.zeros((n, y0.size))
y[0, :] = y0
for i in range(1, n):
k1 = h * f(y[i-1], t[i-1], *params)
k2 = h * f(y[i-1] + k1/2, t[i-1] + h/2, *params)
k3 = h * f(y[i-1] + k2/2, t[i-1] + h/2, *params)

3
k4 = h * f(y[i-1] + k3, t[i-1] + h, *params)
y[i] = y[i-1] + (k1 + 2*k2 + 2*k3 + k4) / 6
return y, t

n_steps_driven = int((t_end_driven - t_start) / dt)


y_values_driven, t_values_driven = RK4_driven(t_start, t_end_driven,
np.array([theta0_driven,␣
↪omega0_driven]),

driven_pendulum_ode,
n_steps_driven, C, Omega)
theta_values_driven = y_values_driven[:, 0]

# Plot � vs. time for the driven pendulum


plt.figure(figsize=(10, 5))
plt.plot(t_values_driven, np.degrees(theta_values_driven))
plt.xlabel('Time (s)')
plt.ylabel('� (degrees)')
plt.title(f'Driven Pendulum (C={C} s�², Ω={Omega} s�¹)')
plt.grid(True)
plt.show()

# Find resonant Ω (example using Ω � natural frequency)


Omega_resonant = np.sqrt(g / l) # Approx 9.899 rad/s
y_values_resonant, t_values_resonant = RK4_driven(t_start, t_end_driven,
np.array([theta0_driven,␣
↪omega0_driven]),

driven_pendulum_ode,
n_steps_driven, C,␣
↪Omega_resonant)

theta_values_resonant = y_values_resonant[:, 0]

# Plot resonant case for the driven pendulum


plt.figure(figsize=(10, 5))
plt.plot(t_values_resonant, np.degrees(theta_values_resonant))
plt.xlabel('Time (s)')
plt.ylabel('� (degrees)')
plt.title(f'Resonant Driven Pendulum (Ω={Omega_resonant:.2f} s�¹)')
plt.grid(True)
plt.show()

total_distance = y[b, 0]
print("Total horizontal distance traveled:", total_distance, "m")

You might also like