Differential-Algebraic Equation Modeling of a Double Pendulum (B)
Part 1: Simple Introduction to DAEs: Mass-Matrix Robertson Equations
using DifferentialEquations, Plots, Sundials
function f(du, u, p, t)
du[1] = -p[1]*u[1] + p[2]*u[2]*u[3]
du[2] = p[1]*u[1] - p[2]*u[2]*u[3] - p[3]*u[2]*u[2]
du[3] = u[1] + u[2] + u[3] - 1.
end
M = [1 0 0; 0 1 0; 0 0 0.]
p = [0.04, 10^4, 3e7]
u0 = [1.,0.,0.]
tspan = (0., 1e6)
prob = ODEProblem(ODEFunction(f, mass_matrix = M), u0, tspan, p)
sol = solve(prob, Rodas5())
plot(sol, xscale=:log10, tspan=(1e-6, 1e5), layout=(3,1))
Part 2: Solving the Implicit Robertson Equations with IDA
# Robertson Equation DAE Implicit form
function h(out, du, u, p, t)
out[1] = -p[1]*u[1] + p[2]*u[2]*u[3] - du[1]
out[2] = p[1]*u[1] - p[2]*u[2]*u[3] - p[3]*u[2]*u[2] - du[2]
out[3] = u[1] + u[2] + u[3] - 1.
end
p = [0.04, 10^4, 3e7]
du0 = [-0.04, 0.04, 0.0]
u0 = [1.,0.,0.]
tspan = (0., 1e6)
differential_vars = [true, true, false]
prob = DAEProblem(h, du0, u0, tspan, p, differential_vars = differential_vars)
sol = solve(prob, IDA())
plot(sol, xscale=:log10, tspan=(1e-6, 1e5), layout=(3,1))
Part 3: Manual Index Reduction of the Single Pendulum
Consider the equation: $ x^2 + y^2 = L $ Differentiating once with respect to time: $ 2x\dot{x} + 2y\dot{y} = 0 $ A second time:
\[\begin{align*} {\dot{x}}^2 + x\ddot{x} + {\dot{y}}^2 + y\ddot{y} &= 0 \\ u^2 + v^2 + x(\frac{x}{mL}T) + y(\frac{y}{mL}T - g) &= 0 \\ u^2 + v^2 + \frac{x^2 + y^2}{mL}T - yg &= 0 \\ u^2 + v^2 + \frac{T}{m} - yg &= 0 \end{align*}\]
Our final set of equations is hence
\[\begin{align*} \ddot{x} &= \frac{x}{mL}T \\ \ddot{y} &= \frac{y}{mL}T - g \\ \dot{x} &= u \\ \dot{y} &= v \\ u^2 + v^2 -yg + \frac{T}{m} &= 0 \end{align*}\]
We finally obtain $T$ into the third equation. This required two differentiations with respect to time, and so our system of equations went from index 3 to index 1. Now our solver can handle the index 1 system.
Part 4: Single Pendulum Solution with IDA
function f(out, da, a, p, t)
(L, m, g) = p
u, v, x, y, T = a
du, dv, dx, dy, dT = da
out[1] = x*T/(m*L) - du
out[2] = y*T/(m*L) - g - dv
out[3] = u - dx
out[4] = v - dy
out[5] = u^2 + v^2 - y*g + T/m
nothing
end
# Release pendulum from top right
u0 = zeros(5)
u0[3] = 1.0
du0 = zeros(5)
du0[2] = 9.81
p = [1,1,9.8]
tspan = (0.,100.)
differential_vars = [true, true, true, true, false]
prob = DAEProblem(f, du0, u0, tspan, p, differential_vars = differential_vars)
sol = solve(prob, IDA())
plot(sol, idxs=(3,4))
Part 5: Solving the Double Pendulum DAE System
For the double pendulum: The equations for the second ball are the same as the single pendulum case. That is, the equations for the second ball are:
\[\begin{align*} \ddot{x_2} &= \frac{x_2}{m_2L_2}T_2 \\ \ddot{y_2} &= \frac{y_2}{m_2L_2}T_2 - g \\ \dot{x_2} &= u \\ \dot{y_2} &= v \\ u_2^2 + v_2^2 -y_2g + \frac{T_2}{m_2} &= 0 \end{align*}\]
For the first ball, consider x_1^2 + y_1^2 = L $
\[\begin{align*} x_1^2 + x_2^2 &= L \\ 2x_1\dot{x_1} + 2y_1\dot{y_1} &= 0 \\ \dot{x_1}^2 + \dot{y_1}^2 + x_1(\frac{x_1}{m_1L_1}T_1 - \frac{x_2}{m_1L_2}T_2) + y_1(\frac{y_1}{m_1L_1}T_1 - g - \frac{y_2}{m_1L_2}T_2) &= 0 \\ u_1^2 + v_1^2 + \frac{T_1}{m_1} - \frac{x_1x_2 + y_1y_2}{m_1L_2}T_2 &= 0 \end{align*}\]
So the final equations are:
\[\begin{align*} \dot{u_2} &= x_2*T_2/(m_2*L_2) \dot{v_2} &= y_2*T_2/(m_2*L_2) - g \dot{x_2} &= u_2 \dot{y_2} &= v_2 u_2^2 + v_2^2 -y_2*g + \frac{T_2}{m_2} &= 0 \dot{u_1} &= x_1*T_1/(m_1*L_1) - x_2*T_2/(m_2*L_2) \dot{v_1} &= y_1*T_1/(m_1*L_1) - g - y_2*T_2/(m_2*L_2) \dot{x_1} &= u_1 \dot{y_1} &= v_1 u_1^2 + v_1^2 + \frac{T_1}{m_1} + \frac{-x_1*x_2 - y_1*y_2}{m_1L_2}T_2 - y_1g &= 0 \end{align*}\]
function f(out, da, a, p, t)
L1, m1, L2, m2, g = p
u1, v1, x1, y1, T1,
u2, v2, x2, y2, T2 = a
du1, dv1, dx1, dy1, dT1,
du2, dv2, dx2, dy2, dT2 = da
out[1] = x2*T2/(m2*L2) - du2
out[2] = y2*T2/(m2*L2) - g - dv2
out[3] = u2 - dx2
out[4] = v2 - dy2
out[5] = u2^2 + v2^2 -y2*g + T2/m2
out[6] = x1*T1/(m1*L1) - x2*T2/(m2*L2) - du1
out[7] = y1*T1/(m1*L1) - g - y2*T2/(m2*L2) - dv1
out[8] = u1 - dx1
out[9] = v1 - dy1
out[10] = u1^2 + v1^2 + T1/m1 +
(-x1*x2 - y1*y2)/(m1*L2)*T2 - y1*g
nothing
end
# Release pendulum from top right
u0 = zeros(10)
u0[3] = 1.0
u0[8] = 1.0
du0 = zeros(10)
du0[2] = 9.8
du0[7] = 9.8
p = [1,1,1,1,9.8]
tspan = (0.,100.)
differential_vars = [true, true, true, true, false,
true, true, true, true, false]
prob = DAEProblem(f, du0, u0, tspan, p, differential_vars = differential_vars)
sol = solve(prob, IDA())
plot(sol, idxs=(3,4))
plot(sol, idxs=(8,9))