19 Jul 2023 - fubar - Sreekar Guddeti
Invented by Leon Foucault in 1851, it demonstrates that the Earth has a rotation axis.
The pendulum has a bob suspended by a wire that can only apply a tensile force $\vec{\mathbf{T}}$. An additional force due to gravity $\vec{\mathbf{F}}_\mathrm{g}$ acts on the bob.
In an inertial frame $F_\mathrm{A}$ fixed at the centre of earth, the pendulum is located at the surface of the earth given by the coordinates $\vec{\mathbf{R}}= R_0 \hat{ \mathbf{R}} + \Theta_0\hat{\mathbf{\Theta}} + \Phi_0 \hat{\mathbf{\Phi}}$, where $R_0$ is the radius of the Earth, $(\Theta_0, \Phi_0)$ is the polar latitude and longitude, $(\hat{\mathbf{R}}, \hat{\mathbf{\Theta}}, \hat{\mathbf{\Phi}}) $ is the spherical polar coordinates. The angular velocity of the earth is $\vec{\mathbf{\Omega}} = \Omega_0 \hat{\mathbf{R}}(\Theta_0=0)$, where $\Omega_0$ is the angular speed.
In frame $F_\mathrm{A}$, therefore, there are two forces acting on the bob with mass $m$. Hence the net force $\vec{\mathbf{F}}_\mathrm{A}$ is given by
\[\vec{\mathbf{F}}_\mathrm{A} = \vec{\mathbf{T}} + \vec{\mathbf{F}}_\mathrm{g}. \tag{1a}\]The equation of motion is given by
\[\vec{\mathbf{F}}_\mathrm{A} = m \vec{\mathbf{a}}_\mathrm{A},\tag{1b}\]where $\vec{\mathbf{a}}_\mathrm{A}$ is the acceleration of bob.
The unit vectors are also rotating with
\[\vec{\mathbf{\Omega}} = \Omega_0 (\cos \Theta_0 \hat{\mathbf{R}} - \sin \Theta_0 \hat{\mathbf{\Theta}}) \tag{1c}\]For a frame $F_\mathrm{B}$ located at the base of pendulum, let the coordinate axes be $(\hat{\mathbf{r}}, \hat{\mathbf{\theta}}, \hat{\mathbf{z}})$ where the base plane of the cylindrical coordinates aligns with the $R=R_0$ plane of $F_\mathrm{A}$ and the $\hat{\mathbf{r}}(\theta=0)$ unit vector aligns with the $\hat{\mathbf{\Theta}}$ unit vector. As a result, the origin of $F_\mathrm{B}$ orbits as well as rotates around $F_\mathrm{A}$ with $\Omega_0$.
If the acceleration of bob in $F_\mathrm{B}$ is $\vec{\mathbf{a}}_\mathrm{B}$, then
\[\vec{\mathbf{a}}_\mathrm{A} = \vec{\mathbf{a}}_\mathrm{B} + \vec{\mathbf{a}}_\mathrm{BA} + \vec{\mathbf{a}}_\mathrm{Coriolis} + \vec{\mathbf{a}}_\mathrm{centrifugal} \tag{2a},\]where $\vec{\mathbf{a}}\mathrm{BA}$ is the acceleration of origin of $F\mathrm{B}$ due to orbiting and given by
\[\vec{\mathbf{a}}_\mathrm{BA} = - \Omega_0 \vec{\mathbf{R}}_\mathrm{eff} , \tag{2b}\]where $\vec{\mathbf{R}}_\mathrm{eff}$ is the effective radius of bob from the Earth’s axis and given by
\[\vec{\mathbf{R}}_\mathrm{eff} = R_\mathrm{eff} \hat{\mathbf{R}}_\mathrm{eff}, \tag{2c}\]where
\[\begin{array}{} R_\mathrm{eff} &= R_0 \sin \Theta_0 , \\ \hat{\mathbf{R}}_\mathrm{eff} &= \sin \Theta \hat{\mathbf{r}} + \cos \Theta \hat{\mathbf{\Theta}}, \end{array}\]and $\vec{\mathbf{a}}_\mathrm{Coriolis}$ is the Coriolis acceleration arising due to relative velocity and given by
\[\vec{\mathbf{a}}_\mathrm{Coriolis} = 2 (\vec{\mathbf{\Omega}} \times \vec{\mathbf{v}}_\mathrm{B}), \tag{2d}\]where $\vec{\mathbf{v}}\mathrm{B}$ is the velocity of the particle in $F\mathrm{B}$ and $\vec{\mathbf{a}}_\mathrm{centrifugal}$ is the centripetal acceleration arising due to relative radial extent and given by
\[\vec{\mathbf{a}}_\mathrm{centripetal} = \vec{\mathbf{\Omega}} \times (\vec{\mathbf{\Omega}} \times \vec{\mathbf{r}}_\mathrm{B}), \tag{2e}\]$\vec{\mathbf{r}}\mathrm{B}$ is the position of the particle in $F\mathrm{B}$.
In frame $F_\mathrm{A}$, the equation of motion is given by
\[\vec{\mathbf{F}}_\mathrm{B} = m \vec{\mathbf{a}}_\mathrm{B}, \tag{3a}\]where $\vec{\mathbf{F}}_\mathrm{B}$ is the net force. Using Equations 1b and 2a, the net force is given by
\[\vec{\mathbf{F}}_\mathrm{B} = \vec{\mathbf{F}}_\mathrm{A} + \vec{\mathbf{F}}_\mathrm{pseudo}, \tag{3b}\]where $\vec{\mathbf{F}}_\mathrm{pseudo}$ is the additional pseudo or fictitious force experienced and given by
\[\vec{\mathbf{F}}_\mathrm{pseudo} = - m \vec{\mathbf{a}}_\mathrm{BA} - m \vec{\mathbf{a}}_\mathrm{Coriolis} - m \vec{\mathbf{a}}_\mathrm{centripetal}. \tag{3c}\]In terms of $(\hat{\mathbf{r}}, \hat{\mathbf{\theta}}, \hat{\mathbf{z}})$, the $(\hat{\mathbf{R}}, \hat{\mathbf{\Theta}}, \hat{\mathbf{\Phi}}) $ is given by
\[\begin{array}{} \hat{\mathbf{R}} &= \hat{\mathbf{z}},\\ \hat{\mathbf{\Theta}} &= \cos \Theta_0 \hat{\mathbf{R}} - \sin \Theta_0 \hat{\mathbf{\Theta}}, \\ \hat{\mathbf{\Phi}} &= \sin \Theta_0 \hat{\mathbf{R}} + \cos \Theta_0 \hat{\mathbf{\Theta}}. \end{array} \tag{4}\]If we assume that the length of the pendulum $L_0$ is large enough compared to the maximum radial motion of bob, then we can approximate the motion to the $z=0$ plane. Under this approximation, we can neglect the $z-$components of position, velocity and acceleration of bob in $F_B$.
Further under this approximation, the $r-$ and $\theta-$ components have an angular velocity $\vec{\mathbf{\omega}}\mathrm{B}$ and acceleration $\vec{\mathbf{\alpha}}\mathrm{B}$ only along the $z-$ component and given by
\[\begin{array} \vec{\mathbf{\omega}} &= \omega_\mathrm{B} \hat{\mathbf{z}}, \\ \vec{\mathbf{\alpha}} &= \alpha_\mathrm{B} \hat{\mathbf{z}}, \end{array} \tag{5a}\]As a result, the position, velocity and acceleration is reduced to
\[\begin{array} \vec{\mathbf{r}}_\mathrm{B} &= r \hat{\mathbf{r}}, \\ \vec{\mathbf{v}}_\mathrm{B} &= \dot{r} \hat{\mathbf{r}} + r \omega \hat{\mathbf{\theta}}, \\ \vec{\mathbf{a}}_\mathrm{B} &= (\ddot{r} - r \omega^2 ) \hat{\mathbf{r}} + (r \alpha + 2 \dot{r}\omega) \hat{\mathbf{\theta}}. \end{array} \tag{5b}\]It is to be noted that the subscript B in the radius $f$ and angular speed $\omega$ and angular acceleration $\alpha$ is dropped for brevity.
Hence, under the small angle approximation, we have two degrees of freedom, the radial extent $r$ and the angular deviation $\theta$. Hence the generalized coordinates are
\[\vec{\mathbf{q}} = \{r, \theta\},\]and the corresponding velocities are
\[\dot{\vec{\mathbf{q}}} = \{\dot{r}, \omega\}.\]The objective is to find the equations for the rate of change of the generalized coordinates and their corresponding velocities.
Let the tension $\vec{\mathbf{T}}$ be
\[\vec{\mathbf{T}} = T_\mathrm{r} \hat{\mathbf{r}} + T_\mathrm{\theta} \hat{\mathbf{\theta}} + T_\mathrm{z} \hat{\mathbf{z}}.\]The force due to gravity is
\[\vec{\mathbf{F}}_\mathrm{g} = -m g \hat{\mathbf{z}}.\]Using the Equations 2 and 5b, the terms in the pseudo force are given by
\[\begin{array}{} - m \vec{\mathbf{a}}_\mathrm{BA} &= m \Omega^2 R_\mathrm{eff} \left( \cos \Theta \cos \theta \hat{\mathbf{r}} - \cos \Theta \sin \theta \hat{\mathbf{\theta}} + \sin \Theta \hat{\mathbf{z}} \right), \\ - m \vec{\mathbf{a}}_\mathrm{Coriolis} &= 2 m \Omega \left( r \omega \cos \Theta \hat{\mathbf{r}} - \dot{r} \cos \Theta \hat{\mathbf{\theta}} + \overline{\dot{r}\sin\Theta \sin\theta + r \omega \sin \Theta \cos \theta} \hat{\mathbf{z}} \right), \\ - m \vec{\mathbf{a}}_\mathrm{centripetal} &= m r \Omega^2 \left( \overline{\cos^2 \Theta + \sin^2 \Theta \sin^2 \theta} \hat{\mathbf{r}} + \sin^2\Theta \cos \theta \sin \theta \hat{\mathbf{\theta}} + \sin \Theta \cos^2 \theta \hat{\mathbf{z}} \right). \end{array}\]Hence the resolution of the reduced equation of motion into its components is given by
\[\left( \begin{array}{} T_\mathrm{r} + m \Omega^2 R_\mathrm{eff} \cos \Theta \cos \theta + 2 m \Omega r \omega \cos \Theta + m r \Omega^2 \overline{\cos^2 \Theta + \sin^2 \Theta \sin^2 \theta} \\ T_\mathrm{\theta} - m \Omega^2 R_\mathrm{eff}\cos \Theta \sin \theta - 2 m \Omega \dot{r} \cos \Theta + m r \Omega^2 \sin^2\Theta \cos \theta \sin \theta \\ T_\mathrm{z} - m g + m \Omega^2 R_\mathrm{eff} \sin \Theta + 2 m \Omega \overline{\dot{r}\sin\Theta \sin\theta + r \omega \sin \Theta \cos \theta} + m r \Omega^2 \sin \Theta \cos^2 \theta \end{array} \right) = \left( \begin{array}{} \ddot{r} - r \omega^2 \\ r \alpha + 2 \dot{r}\omega \\ 0 \end{array} \right) \tag{6}\]Due to the tensile nature of $\vec{\mathbf{T}}$,
\[T_\mathrm{\theta} = 0 \tag{7a}\]and
\[T_\mathrm{z} \tan \varphi = - T_\mathrm{r}, \tag{7b}\]where $\varphi$ is the angular deviation of the wire from the mean position and given by
\[\varphi = \frac{r}{L_0}. \tag{7c}\]Under small angle approximation,
\[\tan \varphi \approx \varphi.\]Using expressions for $T_\mathrm{r}, T_\mathrm{z}$ from Equation 6 and subsituting in Equations. 7a, 7b we have
\[\left( \begin{array}{} \ddot{r} \\ r \alpha \end{array} \right) = \left( \begin{array}{} a_\mathrm{r} + r \omega^2 \\ a_\mathrm{\theta} - 2 \dot{r}\omega \end{array} \right)\]where $m a_\mathrm{r}, m a_\mathrm{\theta}$ are respectively the radial and tangential components of the reduced net force and given by
\[\left( \begin{array}{} a_\mathrm{r} \\ a_\mathrm{\theta} \end{array} \right) = \left( \begin{array}{} - \frac{r}{L_0} g + R_\mathrm{eff} \Omega^2 \left( \frac{r}{L_0} \sin \Theta + \cos \Theta \cos \theta \right) + 2 \Omega \left( \frac{r}{L_0} \overline{ \dot{r} \sin \Theta \sin \theta + r \omega \sin \Theta \cos \theta } + r \omega \cos \Theta \right) + r \Omega^2 \left( \frac{r}{L_0} \sin \Theta \cos^2 \theta + \overline{ \cos^2 \Theta + \sin^2 \Theta \sin^2 \theta } \right) \\ - R_\mathrm{eff} \Omega^2 \cos \Theta \sin \theta - 2 \Omega \dot{r} \cos \Theta + r \Omega^2 \sin^2 \Theta \cos\theta \sin \theta. \end{array} \right)\]If we denote the generalized coordinates and the corresponding velocities as generic variables
\[\{ r, \theta, \dot{r}, \omega \} = \{y_1, y_2, y_3, y_4 \},\]then then the rate of change of these variables is given by
\[\left( \begin{array}{} \dot{y}_1 \\ \dot{y}_2 \\ \dot{y}_3 \\ \dot{y}_4 \end{array} \right) = \left( \begin{array}{} y_3 \\ y_4 \\ a_\mathrm{r} + y_1y_4^2 \\ \frac{1}{y_1} \left(a_\mathrm{\theta} - 2 y_3y_4 \right) \end{array} \right),\]where
\[\left( \begin{array}{} a_\mathrm{r} \\ a_\mathrm{\theta} \end{array} \right) = \left( \begin{array}{} - \frac{y_1}{L_0} g + R_\mathrm{eff} \Omega^2 \left( \frac{y_1}{L_0} \sin \Theta + \cos \Theta \cos y_2 \right) + 2 \Omega \left( \frac{y_1}{L_0} \overline{ y_3 \sin \Theta \sin y_2 + y_1 y_4 \sin \Theta \cos y_2 } + y_1 y_4 \cos \Theta \right) + y_1 \Omega^2 \left( \frac{y_1}{L_0} \sin \Theta \cos^2 y_2 + \overline{ \cos^2 \Theta + \sin^2 \Theta \sin^2 y_2 } \right) \\ - R_\mathrm{eff} \Omega^2 \cos \Theta \sin y_2 - 2 \Omega y_3 \cos \Theta + y_1 \Omega^2 \sin^2 \Theta \cos y_2 \sin y_2. \end{array} \right)\]Hence, we have a set of four first-order non-linear differential equations in four variables that can be succintly in the vector form
\[\dot{\vec{\mathbf{y}}} = \tilde{\mathrm{D}}\vec{\mathbf{y}}, \tag{8}\]where $\vec{\mathbf{y}} = (y_1, y_2, y_3, y_4)$ is generalized position in the coordinate space and $\tilde{\mathrm{D}}$ is the differential operator. If we know the initial condition $\vec{\mathbf{y}}^0$, we can in principle solve the first order differential equation.
In order to test the veracity of the above analysis, let us compare the form of the equations in limiting conditions with physical behaviour.
If the Earth is not rotating, then the motion of the bob should be akin to that of a simple pendulum in 2D.
\[\left( \begin{array}{} a_\mathrm{r} \\ a_\mathrm{\theta} \end{array} \right) = \left( \begin{array}{} - \frac{r}{L_0} g \\ 0 \end{array} \right).\]We can solve Equation 8 using Scipy package’s interpolate’ module solve_ivp
function.
import numpy as np
from scipy.integrate import solve_ivp
from scipy.interpolate import interp1d
import matplotlib as mpl
import matplotlib.pyplot as plt
# magic command to convert matplotlib plots into Base64 string images
%matplotlib notebook
# Constants
RADIUS = 6.4e6 # Radius of earth (in m)
DAY = 24 * 3600 # time period (in s)
OMEGA = 2*np.pi/DAY
LATITUDE = 61.4/180*np.pi # polar latitude (in rad)
MASS = 1 # mass of pendulum (in kg)
LENGTH = 100 # length of pendulum (in m)
GRAVITY = 9.8 # acceleration due to gravity (in ms-2)
# Default particle trajectory conditions
STATE_0 = (1, 0, 0, 0)
T_SPAN = (0, 100)
MIN_TIMESTAMPS = T_SPAN[1]*10
class Particle:
"""
This particle is under the influence of a radial force.
Particle's attributes are -
- Mass
- Initial coordinates
- External force
- time interval
Particle's methods are -
- solution
- trajectory
"""
def __init__(self, force, mass=MASS, state0=STATE_0, t_span=T_SPAN):
self.mass = mass
self.state0 = state0
self.t_span = t_span
self.force = force
self.ts, self.states = self.solution()
def motion(self, t, state):
"""
The velocity vector for a particle under a 2D radial force.
The parameter t is used by the ODE solver from scipy.
"""
m = self.mass
# generalized coordinates
y1, y2, y3, y4 = state
# force components
f_r, f_t = self.force(state)
v1 = y3
v2 = y4
v3 = f_r/m + y1*y4**2
v4 = 1/y1*(f_t/m - 2*y3*y4)
# generalized velocity
v = (v1, v2, v3, v4)
return v
def solution(self):
"""
ODE solver from scipy.
"""
global MIN_TIMESTAMPS
max_step = self.t_span[1]/MIN_TIMESTAMPS
solver = solve_ivp(self.motion, self.t_span, self.state0, max_step=max_step)
ts, states = solver.t, solver.y
return ts, states
def trajectory(self):
"""
Trajectory of motion.
"""
# time stamps
ts = self.ts
# Generalized coordinates.
radii, thetas, speeds, omegas = self.states
# time profiles of coordinates.
fig, ax = plt.subplots()
ax.plot(ts, radii, label='r')
ax.plot(ts, thetas%(2*np.pi), label=r'$\theta$')
ax.plot(ts, speeds, label='v')
ax.plot(ts, omegas, label=r'$\omega$')
ax.axhline(0, color ='k')
ax.legend()
# Cartesian coordinates
xs = [radius*np.cos(theta) for radius, theta in zip(radii, thetas)]
ys = [radius*np.sin(theta) for radius, theta in zip(radii, thetas)]
# Interpolate the data
f = interp1d(xs, ys, kind='cubic')
xs_int = xs
ys_int = f(xs_int)
# Trajectory
fig1, ax1 = plt.subplots()
ax1.plot(xs, ys, 'o', label='trajectory')
ax1.plot(xs_int, ys_int, '-')
ax1.axhline(0, color ='k')
ax1.axvline(0, color ='k')
ax1.set_aspect('equal')
ax1.legend()
Any force in general depends on the coordinates ${ r, \theta, \dot{r}, \omega }$. Let us define commonly experienced forces and test the validity of the trajectory solver of the Particle
class as defined above.
To test the viability of the motion solver, let us test the motion of a particle in 2D under Hooke’s force
\[\vec{\mathbf{F}}_\mathrm{Hooke} = -r\]The solution is a Simple Harmonic Motion (SHM) in 2D with angular speed $\omega = 1$ as shown below.
# hooke's law
def hooke(state):
"""
The force in general depends on the coordinates (r, theta)=(y1, y2) and the velocity (v, omega)=(y3, y4).
This is a radial force.
"""
y1, y2, y3, y4 = state
# force components in polar coordinates.
f_r = -1*y1
f_t = 0
force = (f_r, f_t)
return force
# Particle under hooke's law
state_0 = (1, 0, 0, 0)
t_span = (0, 20)
MIN_TIMESTAMPS = T_SPAN[1]*10
p = Particle(hooke, state0=state_0, t_span=t_span)
p.trajectory()
The time period of SHM is given by
\[T_\mathrm{SHM} = 2 \pi / \omega.\]For a particle having a tangential component of velocity, we have SHM in 2D.
For a particle having a tangential component of velocity, we have SHM in 2D. Consider a particle with initial conditions ${ r_0, \theta_0, \dot{r}_0, \omega_0 } = {1, 0, 1, 2}$ so that it also has zero component of tangential velocity, thereby, resulting in a tangential trajectory.
# tangential trajectory
state0 = (1, 0, 1, 2)
t_span = (0, 20)
MIN_TIMESTAMPS = t_span[1]*10
p_hooke1 = Particle(hooke, state0=state0, t_span=t_span)
p_hooke1.trajectory()
NOTE: The time period is still the same.
To check the robustness of the motion solver in polar coordinates, let us test the motion of a particle in 2D under the gravitational force
\[\vec{\mathbf{F}}_\mathrm{Newton} = - \frac{1}{r^2}\]The solution is a conic as shown below:
def newton(state):
"""
inverse square force that is radial in nature.
"""
y1, y2, y3, y4 = state
# force components in polar coordinates.
f_r = -1/y1**2
f_t = 0
force = (f_r, f_t)
return force
If the particle has sufficient kinetic energy to overcome the gravitational potential particle, it will escape. The minimum initial kinetic energy required for escape must be such that at infinity the total energy is zero so that
\[\frac{1}{2} m v_0^2 - \frac{1}{r_0^2} = T_\infty + U_\infty = 0,\]where $v_0$ is the initial speed given by
\[v_0^2 = \dot{r}^2 + r^2\omega^2.\] \[\therefore \quad v_0 = \frac{1}{r_0}\sqrt{\frac{2}{m}}.\]m = 1
r_0 = 1
r_dot = 0
v_0 = np.sqrt(2/m)/r_0
v_0
1.4142135623730951
Therefore, the escape speed is 1.414.
To be bounded, therefore, consider a particle with initial conditions ${ r_0, \theta_0, \dot{r}_0, \omega_0 } = {1, 0, 0, 1.3}$ so that it has initial speed less than escape speed, thereby, resulting in a bounded trajectory.
# tangential trajectory
state0 = (1, 0, 0, 1.3)
t_span = (0, 20)
MIN_TIMESTAMPS = t_span[1]*10
p_newton = Particle(newton, state0=state0, t_span=t_span)
p_newton.trajectory()
NOTE: The trajectory for a bounded particle is elliptical.
To be unbounded, therefore, consider a particle with initial conditions ${ r_0, \theta_0, \dot{r}_0, \omega_0 } = {1, 0, 0, 1.5}$ so that it has initial speed greater than escape speed, thereby, resulting in a unbounded trajectory.
state0 = (1, 0, 0, 1.5)
t_span = (0, 6)
MIN_TIMESTAMPS = t_span[1]*10
p_newton1 = Particle(newton, state0=state0, t_span=t_span)
p_newton1.trajectory()
NOTE: The trajectory for an unbounded particle is parabolic.
The constants relevant to the motion are
The net force acting on the Foucault pendulum is described by Equation 8. The solution is computed below.
# foucault force
def foucault(state):
"""
Foucault force that is the net combination of gravity and pseudo force experience due to observer located at the location.
"""
y1, y2, y3, y4 = state
# force components in polar coordinates.
global MASS
global RADIUS
global LATITUDE
global OMEGA
global GRAVITY
global LENGTH
m = MASS
R = RADIUS
th = LATITUDE
w = OMEGA
g = GRAVITY
l = LENGTH
r_eff = R * np.sin(th)
f_cf = m*r_eff*w**2
dy1= y1/l
a_g = -1*g*dy1
a_o = r_eff*w**2 * (dy1*np.sin(th) + np.cos(th)*np.cos(y2))
a_c = 2*w*(dy1*(y3*np.sin(th)*np.sin(y2) + y1*y4*np.sin(th)*np.cos(y2)) + y1*y4*np.cos(th))
a_cf = y1*w**2*(dy1*np.sin(th)*np.cos(y2)**2 + (np.cos(th)**2 + np.sin(th)**2 * np.sin(y2)**2))
a_r = a_g + a_o + a_c + a_cf
a_t = -r_eff*w**2*np.cos(th)*np.sin(y2) - 2*w*y3*np.cos(th) + y1*w**2*np.sin(th)**2*np.cos(y2)*np.sin(y2)
f_r = m*a_r
f_t = m*a_t
force = (f_r, f_t)
return force
# particle under Foucault force
state0 = (1, 0, 0, 0)
t_span = (0, 3600)
MIN_TIMESTAMPS = t_span[1]*10
pendulum = Particle(foucault, state0=state0, t_span=t_span)
# trajectory of pendulum
pendulum.trajectory()
NOTE: At zero crossing, the solver becomes unstable due to the presence $1/r$ term.
Hence, it is recommended to provide a slight tangential component to the initial velocity to avoid zero crossing.
# tangential trajectory
state0 = (1, 0, 0, 0.05)
t_span = (0, 100)
MIN_TIMESTAMPS = t_span[1]*10
stable_pendulum = Particle(foucault, state0=state0, t_span=t_span)
# trajectory of pendulum
stable_pendulum.trajectory()
The approximate time period of oscillation within the so-called plane of oscillation is roughly equal to the time period of SHM motion
\[T_\mathrm{SHM} = 2 \pi \sqrt{\frac{L_0}{g}}\]# approximate time period of oscillation
T = 2*np.pi*np.sqrt(LENGTH/GRAVITY)
T
20.07089923154493
The effect of Earth’s rotation is not evident due to the low angular speed. Let us artificially speed up the Earth’s rotation by 10 times.
OMEGA = 2*np.pi/DAY*10
state0 = (1, 0, 0, 0.05)
t_span = (0, 360)
MIN_TIMESTAMPS = t_span[1]*10
p_at_10w = Particle(foucault, state0=state0, t_span=t_span)
p_at_10w.trajectory()
Hence, the plane of oscillation rotates in a clockwise manner.
How to calculate it analytically?
As the mean position is off-centred from origin, let us look at the effect of latitude on the mean position
At the north pole, the non-inertial frame $F_\mathrm{B}$ only rotates and does not orbit. Hence the only pseudo forces are due to the Coriolis and centripetal acceleration of $F_\mathrm{B}$.
… … (needs analysis)
The angular speed $\omega_\mathrm{B}$ turns out to be
\[\omega_\mathrm{B} = - \Omega\]To demonstrate this condition numerically, let us solve the equation of motion until $\Delta T = 1/4 T_0$, where
\[T_0 = \frac{2\pi}{\Omega}\]is one Earth Day. In this time, the plane of oscillation should rotate by $\pi/2$.
LATITUDE = 0
OMEGA = 2*np.pi/DAY
state0 = (10, 0, 0, 0.05)
t_span = (0, 6*3600)
MIN_TIMESTAMPS = 6*3600*10
p_at_0 = Particle(foucault, state0=state0, t_span=t_span)
p_at_0.trajectory()
The plane of oscillation has rotated clockwise by $\pi/2$. Hence, the plane of oscillation has angular speed of $-\Omega$.
At the equator, the non-inertial frame $F_\mathrm{B}$ rotates as well as orbits. Hence pseudo forces are due to the accelerating origin, Coriolis acceleration and centripetal acceleration of $F_\mathrm{B}$. However, the equation of motion is reduced to
...
... (needs analysis)
The angular speed on the average should be zero.
To demonstrate this condition numerically, let us solve the equation of motion until $\Delta T = 1/4 T_0$.
LATITUDE = np.pi/2
state0 = (10, 0, 0, 0.05)
t_span = (0, 3600)
MIN_TIMESTAMPS = 3600*10
p_at_90 = Particle(foucault, state0=state0, t_span=t_span)
p_at_90.trajectory()
Consider the pendulum at the new Parliament building of India. The latitude is $61.4 ^{o}$.
The angular speed on the average should be $\Omega \cos\Theta$. To demonstrate this condition numerically, let us solve the equation of motion until
\[\Delta T = \frac{1}{4} \frac{T_0}{\cos \Theta}.\]In this time, the plane of oscillation should rotate by $\pi/2$.
LATITUDE = 61.4/180*np.pi
state0 = (10, 0, 0, 0.05)
t_span = (0, DAY/np.cos(LATITUDE)/4)
MIN_TIMESTAMPS = t_span[1]*10
p_at_parliament = Particle(foucault, state0=state0, t_span=t_span)
p_at_parliament.trajectory()
With no initial angular speed, in the absence of rotation of Earth, the motion is simple 2D harmonic motion. Let us check how the motion changes with a finite initial angular speed
OMEGA = 0
state0 = (1, np.pi/2, 0, 0)
t_span = (0, 100)
MIN_TIMESTAMPS = t_span[1]*10
p_at_w_0 = Particle(foucault, state0=state0, t_span=t_span)
p_at_w_0.trajectory()
/tmp/ipykernel_20147/3747781934.py:65: RuntimeWarning: More than 20 figures have been opened. Figures created through the pyplot interface (`matplotlib.pyplot.figure`) are retained until explicitly closed and may consume too much memory. (To control this warning, see the rcParam `figure.max_open_warning`).
fig, ax = plt.subplots()
To avoid the instability in integration at cross-over, let us reformulate the equation of motion in the Cartesian coordinates.
class CartesianParticle:
"""
This particle is under the influence of a 2D force.
Particle's attributes are -
- Mass
- Initial coordinates
- External force
- time interval
Particle's methods are -
- solution
- trajectory
"""
def __init__(self, force, state0, t_span, mass=MASS):
self.mass = mass
self.state0 = state0
self.t_span = t_span
self.force = force
self.ts, self.states = self.solution()
def motion(self, t, state):
"""
The velocity vector for a particle under a 2D radial force.
The parameter t is used by the ODE solver from scipy.
"""
m = self.mass
# generalized coordinates
y1, y2, y3, y4 = state
# force components
f_x, f_y = self.force(state)
v1 = y3
v2 = y4
v3 = f_x/m
v4 = f_y/m
# generalized velocity
v = (v1, v2, v3, v4)
return v
def solution(self):
"""
ODE solver from scipy.
"""
global MIN_TIMESTAMPS
max_step = self.t_span[1]/MIN_TIMESTAMPS
solver = solve_ivp(self.motion, self.t_span, self.state0, max_step=max_step)
ts, states = solver.t, solver.y
return ts, states
def trajectory(self):
"""
Trajectory of motion.
"""
# time stamps
ts = self.ts
# Generalized coordinates.
xs, ys, v_xs, v_ys = self.states
# time profiles of coordinates.
fig, ax = plt.subplots()
ax.plot(ts, xs, label='x')
ax.plot(ts, ys, label='y')
ax.plot(ts, v_xs, label=r'$v_x$')
ax.plot(ts, v_ys, label=r'$v_y$')
ax.axhline(0, color ='k')
ax.legend()
# Interpolate the data
f = interp1d(xs, ys, kind='cubic')
xs_int = xs
ys_int = f(xs_int)
# Trajectory
fig1, ax1 = plt.subplots()
ax1.plot(xs, ys, 'o', label='trajectory')
ax1.plot(xs_int, ys_int, '-')
ax1.axhline(0, color ='k')
ax1.axvline(0, color ='k')
ax1.legend()
ax1.set_aspect('equal')
def cartesian_foucault(state):
"""
Foucault force that is the net combination of gravity and pseudo force experience due to observer located at the location.
"""
y1, y2, y3, y4 = state
# force components in polar coordinates.
global MASS
global RADIUS
global LATITUDE
global OMEGA
global GRAVITY
global LENGTH
m = MASS
R = RADIUS
th = LATITUDE
w = OMEGA
g = GRAVITY
l = LENGTH
s, c = np.sin(th), np.cos(th)
r_eff = R * s
r_sq = y1**2 + y2**2
r_a_r = -1*r_sq/l*(g - r_eff*w**2*s - 2*w*y4*s) + r_eff*w**2*c*y1 + 2*w*(-1*y3*y2 + y4*y1)*c
r_a_th = -1*r_eff*w**2*c*y2 - 2*w*(y3*y1 + y4*y2)*c + w**2*s**2*y1*y2
a_x = (y1*r_a_r - y2*r_a_th)/r_sq
a_y = (y2*r_a_r + y1*r_a_th)/r_sq
f_x = m*a_x
f_y = m*a_y
force = (f_x, f_y)
return force
LATITUDE = 0
state0 = (10, 0, 0, 0.01)
t_span = (0, 6*3600)
MIN_TIMESTAMPS = t_span[1]*10
cartesian_particle = CartesianParticle(cartesian_foucault, state0, t_span)
cartesian_particle.trajectory()