Exercise 1.21: A dumbbell
blockquote not implementedThe uneven dumbbell. We've just made it through four exercises which embrace the idea that you can bake constraints into the coordinate transformation. But why should we believe that this is allowed?
First, load the sicmutils
environment:
(nextjournal.env/load! :sicmutils)
This exercise tries to do a coordinate change that is really careful about not changing the dimension of the configuration space, so that we can show that this move is allowed. Here's the setup:
The idea here is to take the distance between the particles inline_formula not implemented and treat it as a new dimension inline_formula not implemented.
Goal is to assume that Newtonian mechanics' approach to constraints, shown here, I think, is correct, and then show that the resulting equations of motion let us treat the distance coordinate inline_formula not implemented as a constant.
Multiple Particle API
Many exercises have been dealing with multiple particles so far. Let's introduce some functions that let us pluck the appropriate coordinates out of the local tuple.
If we have the velocity and mass of a particle, its kinetic energy is easy to define:
(defn KE-particle [m v]
(* (/ 1 2) m (square v)))
This next function, extract-particle
, takes a number of components – 2 for a particle with 2 components, 3 for a particle in space, etc – and returns a function of local
and i
, a particle index. This function can be used to extract a sub-local-tuple for that particle from a flattened list.
(defn extract-particle [pieces]
(fn [[t q v] i]
(let [indices (take pieces
(iterate
inc (* i pieces)))
extract (fn [tuple]
(mapv (fn [i]
(ref tuple i))
indices))]
(up t (extract q) (extract v)))))
Part A: Newton's Equations
blockquote not implementedTODO: Write these down from the notebook!
Part B: Dumbbell Lagrangian
blockquote not implementedHere is how we model constraint forces. Each pair of particles has some constraint potential acting between them:
(defn U-constraint [q0 q1 F l]
(* (/ F (* 2 l))
(- (square (- q1 q0))
(square l))))
And here's a Lagrangian for two free particles, subject to a constraint potential inline_formula not implemented acting between them.
(defn L-free-constrained [m0 m1 l]
(fn [local]
(let [extract (extract-particle 2)
[_ q0 qdot0] (extract local 0)
[_ q1 qdot1] (extract local 1)
F (ref (coordinate local) 4)]
(- (+ (KE-particle m0 qdot0)
(KE-particle m1 qdot1))
(U-constraint q0 q1 F l)))))
Finally, the path. This is rectangular coordinates for each piece, plus inline_formula not implemented between them.
(def q-rect
(up
(literal-function x_0)
(literal-function y_0)
(literal-function x_1)
(literal-function y_1)
(literal-function F)))
This shows the Lagrangian itself, which answers part b:
(let [L (L-free-constrained m_0 m_1 l)
f (compose L (Gamma q-rect))]
(f t))
Here are the Lagrange equations, which, if you squint, are like Newton's equations from part a.
(let [L (L-free-constrained m_0 m_1 l)
f ((Lagrange-equations L) q-rect)]
(f t))
Part C: Coordinate Change
blockquote not implementedThis is a coordinate change that is very careful not to reduce the degrees of freedom.
First, the coordinate change:
(defn cm-theta->rect [m0 m1]
(fn [[_ [x_cm y_cm theta c F]]]
(let [total-mass (+ m0 m1)
m0-distance (* c (/ m1 total-mass))
m1-distance (* c (/ m0 total-mass))]
(up (- x_cm (* m0-distance (cos theta)))
(- y_cm (* m0-distance (sin theta)))
(+ x_cm (* m1-distance (cos theta)))
(+ y_cm (* m1-distance (sin theta)))
F))))
Then the coordinate change applied to the local tuple:
(let [local (up t
(up x_cm y_cm theta c F)
(up xdot_cm ydot_cm thetadot cdot Fdot))
C (F->C (cm-theta->rect m_0 m_1))]
(C local))
Then the Lagrangian in the new coordinates;
(defn L-free-constrained* [m0 m1 l]
(compose (L-free-constrained m0 m1 l)
(F->C (cm-theta->rect m0 m1))))
This shows the Lagrangian itself, after the coordinate transformation:
(let [q (up (literal-function x_cm)
(literal-function y_cm)
(literal-function theta)
(literal-function c)
(literal-function F))
L (L-free-constrained* m_0 m_1 l)
f (compose L (Gamma q))]
(f t))
Here are the Lagrange equations:
(let [q (up (literal-function x_cm)
(literal-function y_cm)
(literal-function theta)
(literal-function c)
(literal-function F))
L (L-free-constrained* m_0 m_1 l)
f ((Lagrange-equations L) q)]
(f t))
That final equation states that inline_formula not implemented. Amazing!
Part D: Substitute inline_formula not implemented
blockquote not implementedWe can substitute the constant value of inline_formula not implemented using a function that always returns inline_formula not implemented to get simplified equations:
(let [q (up (literal-function x_cm)
(literal-function y_cm)
(literal-function theta)
(fn [t] l)
(literal-function F))
L (L-free-constrained* m_0 m_1 l)
f ((Lagrange-equations L) q)]
(f t))
This is saying that the acceleration on the center of mass is 0.
The fourth equation, the equation of motion for the inline_formula not implemented, is interesting here. We need to pull in the definition of "reduced mass" from exercise 1.11:
(defn reduced-mass [m1 m2]
(/ (* m1 m2)
(+ m1 m2)))
If we let inline_formula not implemented be the reduced mass, this equation states:
formula not implementedWe can verify this with Scheme by subtracting the two equations:
(let [F (literal-function F)
theta (literal-function theta)
q (up (literal-function x_cm)
(literal-function y_cm)
theta
(fn [_] l)
F)
L (L-free-constrained* m_0 m_1 l)
f ((Lagrange-equations L) q)
m (reduced-mass m_0 m_1)]
(- (ref (f t) 3)
(- (F t)
(* m l (square ((D theta) t))))))
Part E: New Lagrangian
blockquote not implementedFor part e, I wrote this in the notebook - it is effectively identical to the substitution that is happening on the computer, so I'm going to ignore this. You just get more cancellations.
But let's go at it, for fun.
Here's the Lagrangian of 2 free particles:
(defn L-free2 [m0 m1]
(fn [local]
(let [extract (extract-particle 2)
[_ q0 qdot0] (extract local 0)
[_ q1 qdot1] (extract local 1)]
(+ (KE-particle m0 qdot0)
(KE-particle m1 qdot1)))))
Then a version of cm-theta->rect
where we ignore inline_formula not implemented, and sub in a constant inline_formula not implemented:
(defn cm-theta->rect* [m0 m1 l]
(fn [[_ [x_cm y_cm theta]]]
(let [total-mass (+ m0 m1)
m0-distance (* l (/ m1 total-mass))
m1-distance (* l (/ m0 total-mass))]
(up (- x_cm (* m0-distance (cos theta)))
(- y_cm (* m0-distance (sin theta)))
(+ x_cm (* m1-distance (cos theta)))
(+ y_cm (* m1-distance (sin theta)))))))
The Lagrangian:
(defn L-free-constrained2 [m0 m1 l]
(compose (L-free2 m0 m1)
(F->C (cm-theta->rect* m0 m1 l))))
Equations:
(let [q (up (literal-function x_cm)
(literal-function y_cm)
(literal-function theta)
(fn [_] l)
(literal-function F))
L1 (L-free-constrained* m_0 m_1 l)
L2 (L-free-constrained2 m_0 m_1 l)]
((- ((Lagrange-equations L1) q)
((Lagrange-equations L2) q))
t))
The only remaining equation is \eqref{eq:constraint-force} from above. This remains because the simplified Lagrangian ignores the inline_formula not implemented term.