Classsical Mechanics (comments to: moloney@nextwork.rose-hulman.edu)
MAPLE text, input lines and file downloads (plus 1 Mma download)
A large ball and small ball fall together so that after the large ball hits the floor, it impacts the small ball and sends the small ball high into the air. This can be demonstrated on a ringstand with masses and springs. The large and small masses are separated by a spring, and there is a spring below the large mass.
This worksheet models that situation. It has a spring between the large and small mass, and a spring below the large mass, between it and the floor. It illustrates use of Heaviside functions to model contact between bodies with a spring. Motions of the bodies are found as a function of time.
The idea is to determine the separation between large and small mass for the largest rebound height of the small mass.
y1 and y2 released from rest, y1 above y2.
y1 > y2 y1 is above y2.
k=2000 N/m, m1 = 1, m2 = 2
restart;with(plots):
Spring compression. Force comes on when compression is positive
c2:=-y2(t)+L;
c1:=L+y2(t)-y1(t);
eq1:=+k*c1*Heaviside(c1)-m1*98/10 = m1*diff(y1(t),t,t);
values:={m1=1/5,m2=2,k=2000,L=1/2};
eq1s:=subs(values,eq1);
eq2:=+k*c2*Heaviside(c2)-k*c1*Heaviside(c1) -m2*98/10 = m2*diff(y2(t),t,t);
eq2s:=subs(values,eq2); > eqs:={eq1s,eq2s};
s:=dsolve({eq1s,eq2s,y1(0)=5,D(y1)(0)=0,y2(0)=37/10,D(y2)(0)=0},{y1(t),y2(t)},numeric);
h:=odeplot(s,[t,y1(t)],0..7/2,color=red):
j:=odeplot(s,[t,y2(t)],0..7/2,color=blue):
display({j,h},title=`Bounce of y1(red), y2(blue) `);
Download
bounce4.ms [Use 'File Save']
Download
bounce4.mws [Use 'File Save']
Software: Maple V Release 3.0 Authors: Perry Peters and Greg Williby
Concepts Used: Spherical coordinates
Here are the components of a supposedly conservative force
Fx = x y z^3, Fy = x^2 z^3, Fz=3/2 x^2 y z^2.
a) Convert Fx, Fy, and Fz into spherical polar coordinates using
x = r sin theta cos phi, y = r sin theta sin phi, and z = r cos theta.
b) For integrating in a circle at constant z, both r and theta must
be constant.
Show that an element of length dl along a path at constant r and theta
will be
dl = [ - i sin theta sin phi + j sin theta cos phi ] r d phi
This must be done by means of a sketch, showing dl, and the angles theta and phi . c) Integrate the dot product of the force F with the length element dl around a path at constant z, holding theta and r constant, showing that the value of the integral will be zero for all values of r and theta. [The integral around any closed path should be zero for a conservative force.]
Possible teaching strategies.
Might ask students to show that the potential function U is given by -x^2 y z^3/2 .
Instead of having a circular path at constant z centered on (0,0,0), one could ask for a circular path at constant z centered at (x0,0,0). This reinforces the idea of simple coordinate translations. U(x,y,z) would then be -(x-x0)^2 y z^3/2.
restart; with(linalg):
Enter in the force vector.
F:=vector([x*y*z^3,x^2*z^3/2,3*x^2*y*z^2/2]);
Show that the potential energy of F is:
U:=-x^2*y*z^3/2;
Perform partial derivative tests on U to see if it is the potential energy of F
dUdx:=-diff(U,x); dUdy:=-diff(U,y); dUdz:=-diff(U,z);
U is thus the potential energy of F.
Convert the vector into polar form.
sub1:=subs({x=rho*sin(phi)*cos(theta),y=rho*sin(phi)*sin(theta),z=rho*cos(phi)},op(F));
Direction of travel.
P:=vector([-sin(theta),cos(theta),0]);
Take the dot product of the force and the direction before integrating.
Fcir:=dotprod(sub1,P);
Integrate around the loop.
Int(Fcir,theta=0..2*Pi); int(Fcir,theta=0..2*Pi);
This shows that the work done on the particle around the loop for any constant value of phi and rho is 0.
Download
conserve.ms [Use 'File Save']
Download
conserve.mws [Use 'File Save']
Download conserve.ma
[Use 'File Save']
| A program to illustrate use of Heaviside functions to model contact
between bodies with a spring.
A moving mass m1 has a spring of unstretched length x0 attached to it. m1 has an initial velocity in the +x direction and travels until it encounters a stationary mass m2. The spring compresses during the collision until the masses separate, and we plot the motion of both masses as a function of time. Thanks to Joaquin Casellas for repairing a flaw in the problem! (The original problem has the bodies passing through one another), |
![]() |
With this as a starter problem, students could be asked to work out the problem of two masses falling vertically, one above the other. One spring is attached to each mass, and one mass is directly above the other. The masses are released from rest at the same time, with some separation between them. The lower mass's spring strikes the ground and it rebounds, then encounters the spring of the upper mass. After the collisions the upper mass rebounds to some maximum height. The idea is to find the maximum rebound height of the upper mass, given masses and spring constants. The adjustable parameter is the distance between the masses on release from rest.
a) Given masses, spring constants, and unstretched spring lengths, and the initial height of the lower mass, reason out how the collision should occur so that the upper mass rebounds to a maximum height.
b) After the qualitative considerations are worked out, simulate the drop, and the motion of the two masses.
Contact between a moving mass and a stationary mass via a spring.
restart; with(plots):
d:=-x2(t)+x1(t)+x0; # spring compression
eq1:=-k*d*Heaviside(d) = m1*diff(x1(t),t,t);
eq2:=+k*(d)*Heaviside(d) = m2*diff(x2(t),t,t);
values:={m1=1,m2=1,k=10,x0=2};
eqs:=subs(values,eq1),subs(values,eq2);
s:=dsolve({eqs,x1(0)=0,D(x1)(0)=5,x2(0)=4,D(x2)(0)=0},{x1(t),x2(t)},numeric);
h:=odeplot(s,[t,x1(t)],0..3/2,color=red):
j:=odeplot(s,[t,x2(t)],0..3/2,color=blue):
display({h,j},title=`x1(t)[red], x2(t)[blue] vs t`);
restart;with(plots):
c2:=-y2(t)+L; c1:=L+y2(t)-y1(t);
eq1:=+k*c1*Heaviside(c1)-m1*98/10 = m1*diff(y1(t),t,t);
values:={m1=1/3,m2=1,k=80000,L=1/50};
eq1s:=subs(values,eq1);
eq2:=+k*c2*Heaviside(c2)-k*c1*Heaviside(c1) -m2*98/10 = m2*diff(y2(t),t,t);
eq2s:=subs(values,eq2);
eqs:={eq1s,eq2s};
s:=dsolve({eq1s,eq2s,y1(0)=1/2,D(y1)(0)=0,y2(0)=46/100,D(y2)(0)=0},{y1(t),y2(t)},numeric);
h:=odeplot(s,[t,y1(t)],0..3/2,color=red):
j:=odeplot(s,[t,y2(t)],0..3/2,color=blue):
display({j,h},title=`Bounce of y1(red), y2(blue) `);
Download
contact.ms [Use 'File Save']
Download
contact.mws [Use 'File Save']
coupled oscillators 7/8/96 This 'c' version will do two coupled oscillators between walls
It also teases out the normal modes (x2/x1 at each mode freq)
restart: with(plots):
L:= m1* v1^2/2 +m2*v2^2/2- k1* x1^2 / 2 -kc*(x2-x1)^2/2-k1*x2^2/2 ;
d1:=diff(L,v1 ); d2:=diff(L,v2);
p1:=subs(v1=v1(t),d1); p2:=subs(v2=v2(t),d2);
First do the derivatives, then tell it you have a function of t.
d1:=diff(p1,t)-diff(L,x1)=0;
Same thing for derivative with respect to x1. First the derivative wrt to x1, then tell it that x1 is a function of t.
d2:=diff(p2,t)-diff(L,x2)=0;
f1:=subs(x1=x1(t),x2=x2(t),v1(t)=diff(x1(t),t),d1);
f2:=subs(x1=x1(t),x2=x2(t),v2(t)=diff(x2(t),t),d2);
h1:=subs(v1(t)=diff(x1(t),t),f1);
h2:=subs(v1(t)=diff(x1(t),t),f2);
z:=lhs(h1);
Solve for the simple harmonic oscillator equation.
sol:=dsolve({h1,x1(0)=0,D(x1)(0)=1,h2,x2(0)=0,D(x2)(0)=0},{x1(t),x2(t)});
sb:={m1=1,m2=1,k1=1,kc=1/10};
sol1:=subs(sb,sol);
q1:=simplify(evalf(rhs(sol1[1])));
q2:=simplify(evalf(rhs(sol1[2])));
plot({q1,q2},t=0..50,title=`coupled oscillators`);
hx:=subs(diff(x1(t),t,t)=-omega^2*x1(t),h1);
x21:=solve(hx,x2(t));
hy:=subs(diff(x2(t),t,t)=-omega^2*x2(t),h2);
x22:=solve(hy,x2(t));
eqn2:= r*x1(t) = x22;
ratio1:=solve(eqn2,r);
This puts us in position to substitute frequencies and find the mode configurations!
solfreq:=solve(x22=x21,omega);
frq1:=solfreq[1]; > frq2:=solfreq[3];
omega1:=evalf(subs(sb,frq1));
omega2:=evalf(subs(sb,frq2));
mode2x2_over_x1:=subs(sb,omega=omega2,ratio1);
In mode 2, the masses move together, and the center spring is not compressed or expanded. The amplitude ratio is 1:1
mode1x2_over_x1:=subs(sb,omega=omega1,ratio1);
In mode 1, the masses move oppositely, compressing the spring, and operating at a higher frequency. The amplitude ratio is -1:1.
The 'transfer time' from one oscillator to the other should be argued from 'beats', where the plot looks just the same. Want 1/4 of the 'period' of the difference frequency, (f1-f2)/2
Marion problem 12-5, different masses, same k
solm:=solve((-m*x+2*k)*(-M*x+2*k) = k^2,x);
A_B_ratio:=(-m*x+2*k)/k;
rat1:=subs(x=solm[1],A_B_ratio);
rs:=simplify(rat1);
subs(M=10*m,rs);
Download
cuploscc.ms [Use 'File Save']
Download
cuploscc.mws [Use 'File Save']
|
Plot the phase and amplitude response of a driven, damped oscillator
as a function of frequency.
It is interesting that very heavy damping (b=10, k=10, m=1) crushes the
response away from zero frequency.
restart; with(plots):
assume(k,real); assume(m,real); assume(A,real);
assume(omega>0);assume(t,real);assume(b,real);assume(phi,real);
eqn:=A*exp(I*(omega*t+phi))-k*x(t)-b*diff(x(t),t) = m*diff(x(t),t,t);
s:=dsolve(eqn,x(t)); # (takes a little while)
x:=rhs(s);
values:={A=1,m=1,k=10,b=1/10};
xs:=subs(values,x);
steady:=op(1,xs); # keep only the oscillating terms for steady
state response
ev:=evalc(subs(t=0,phi=0,steady));
Phase of the response as a function of frequency. The conventional definition is the phase of the driver minus the phase of the driven system. The relative amplitude response will be taken as exp(-I alph).
assume(alph,real);
cosal:=op(1,ev); # cos(alph)
sinal:=-op(2,ev)/I; # sin(alph)
alph:=arctan(sinal/cosal);
plot(alph,omega=0..10,title=`response phase vs. omega`);
The driver is in phase with the driven system at very low frequencies, and pulls ahead until it is Pi/2 ahead at resonance, and goes on to be Pi ahead at very high frequencies.
Amplitude response as a function of frequency
xcc:=subs(I=-I,steady); # get complex conjugate
xmag:=simplify(steady*xcc); # get magnitude squared
xev:=simplify(evalc(xmag));
plot(sqrt(xev),omega=0..10,title=`Response amplitude vs freq.`);
Download
drivnosc.ms [Use 'File Save']
Download
drivnosc.mws [Use 'File Save']
Show the effect of a rotation matrix on a vector as a function of time. In particular, implement the euler angle rotations and animate them.
Viewing is done along a polar (Pol) and azimuthal (Az) angle.
Initial angles theta, phi, and psi are specified, and rotation rates for all 3.
The calculation starts from body x3,y3,z3 components, and works backward to the space xyz coordinates. When x,y,z are known for each body axis, a projection is done into the viewing direction, and an animation is made.
Forward rotation thru angle a gives xnew = xold cos(a) + yold sin(a), etc.
restart;with(plots):
with(linalg):
m1 is forward rotation thru x. new coords = m1 * old coords ditto for m2 and m3
m1:=matrix([[1,0,0],[0,cos(x),sin(x)],[0,-sin(x),cos(x)]]);
m2:=matrix([[cos(x),0,sin(x)],[0,1,0],[-sin(x),0,cos(x)]]);
m3:=matrix([[cos(x),sin(x),0],[-sin(x),cos(x),0],[0,0,1]]);
We start with body'x axes in x3,y3,z3 system as (1,0,0) for x axis, etc. To get to components in original space xyz system we must do a reverse rotation thru -psi, then reverse thru -theta, then reverse thru -phi. This will lead us to the xyz components of the body's axes after the body has been rotated in space
r1:=subs(x=-phi,evalm(m3));
r2:=subs(x=-theta,evalm(m1));
r3:=subs(x=-psi,evalm(m3));
r123:=evalm(r1 &* r2 &* r3);
v1:=matrix([[f1],[f2],[f3]]);
v:=evalm(r123 &* v1);
p0:=[0,0]; > pL:=[-a*sin(Az)+b*cos(Az),-cos(Pol)*(a*cos(Az)+b*sin(Az))+c*sin(Pol)];
Viewing angles are set up here, polar and azimuthal
viewsubs:={Pol=2*Pi/10,Az=1*Pi/4};
Now set up the view and plots of the x,y,z axes
ax:=subs(a=1,b=0,c=0,viewsubs,pL):
ay:=subs(a=0,b=1,c=0,viewsubs,pL):
az:=subs(a=0,b=0,c=1,viewsubs,pL):
zax:=plot([p0,az],color=black,axes=NONE,scaling=constrained):
xax:=plot([p0,ax],color=black,axes=NONE,scaling=constrained): yax:=plot([p0,ay],color=black,axes=NONE,scaling=constrained):
Now set up the view of lines which have been rotated
p1:=subs(a=v[1,1],b=v[2,1],c=v[3,1],pL):
p:=subs(viewsubs,p1): > px:=subs(f1=1,f2=0,f3=0,p):
py:=subs(f1=0,f2=1,f3=0,p): > pz:=subs(f1=0,f2=0,f3=1,p):
Nframes:=35; > Psidot:=2*Pi/18; Thetadot:=0;Phidot:=2*Pi/36;
Theta0:=Pi/12;Phi0:=0;Psi0:=0;
for i from 0 to Nframes do
sbs:={theta=Theta0+i*Thetadot,phi=Phi0+i*Phidot,psi=Psi0+i*Psidot}: gx.(i):=plot(subs(sbs,[p0,px]),color=blue,scaling=constrained,thickness=3,axes=NONE):
gy.(i):=plot(subs(sbs,[p0,py]),color=red,scaling=constrained,thickness=3,axes=NONE):
gz.(i):=plot(subs(sbs,[p0,pz]),thickness=3,color=black,scaling=constrained,axes=NONE):
m.(i):=display({gx.(i),gy.(i),gz.(i),xax,yax,zax}): od:
display([m.(0..Nframes)],insequence=true);
Download
eulerAn2.mws [Use 'File Save']
Foucault pendulum simulation - nominal values Consult Marion/Thornton circa p. 400 for treatment
restart;with(plots):
Rotation rate is set at 1/10 to make things visible on a short plot
omega:=1/10;
eq1:=diff(x(t),t,t)+98/20*x(t) = omega*diff(y(t),t);
eq2:=diff(y(t),t,t)+(98/20)*y(t) = -omega*diff(x(t),t); s:=dsolve({eq1,eq2,x(0)=1/10,D(x)(0)=0,y(0)=0,D(y)(0)=0},{x(t),y(t)},numeric);
xp:= z -> rhs(s(z)[2]);
yp:= z -> rhs(s(z)[4]);
plot([xp,yp,0..10],title=`x-y plot of motion`);
Download
fouclt.mws [Use 'File Save']
The following file is a template for students, needing them to fill
in equations to get the plot
Download
foucmt.mws [Use 'File Save']
| Projectile motion in Lagrangian formalism
.
|
![]() |
restart;with(plots);
alias(x1=x1(t),y1=y1(t)):
L := m/2*(diff(x1,t)^2+diff(y1,t)^2)-m*g*y1;
Lsvel:=subs(diff(x1,t)=vx1,diff(y1,t)=vy1,L); # L with symbolic velocities
px1:=diff(Lsvel,vx1); py1:=diff(Lsvel,vy1); # generalized momenta
w/ symbols (pj = dLdqjdot)
px1a:=subs(vx1=diff(x1,t),px1);
py1a:=subs(vy1=diff(y1,t),py1); # generalized p's 'live'
La:=subs(x1=a,y1=b,L); # symbol subs for lagrangian
dLdx:= diff(La,a);dLdy:=diff(La,b); # derivatives wrt to symbolic coordinates (dLdqj)
dLdxa:=subs(a=x1,b=y1,dLdx);
dLdya:=subs(a=x1,b=y1,dLdy); # dL/dqj restored 'live'
eqx:= diff(px1a,t)-dLdxa = 0;
eqy:= diff(py1a,t)-dLdya = 0; # equations of motion
eqxa:=subs(x1=a(t),y1=b(t),eqx);eqya:=subs(x1=a(t),y1=b(t),eqy); # new set of named vars
sol:=dsolve({eqxa,a(0)=0,D(a)(0)=10,eqya,b(0)=0,D(b)(0)=10},{a(t),b(t)});
assign(sol); x:=a(t); y:=b(t); # one more set of names for the plot
plot([x,subs(g=98/10,y),t=0..2],title=`Projectile's path`);
Download
proj.ms [Use 'File Save']
Download proj.mws
[Use 'File Save']
![]() |
![]() |
Two equal masses are connected by a spring, and are rotating about their CM.
rotating mass-spring system in Lagrangian formalism, patterned after proj.ms Maple seems to need a lot of shifting around in the variables.
restart;with(plots):
alias(r=r(t),phi=phi(t)):
x1:=r/2*cos(phi): y1:=r/2*sin(phi): x2:=-x1:y2:=-y1: KE:=simplify(m/2*(diff(x1,t)^2+diff(y1,t)^2+diff(x2,t)^2+diff(y2,t)^2));
PE:=k/2*(r-r0)^2;
L:=KE-PE; # lagrangian
valuesin:={diff(r,t)=rdot,diff(phi,t)=phidot,r=ra,phi=phia};
Lsvel:=subs(valuesin,L); # L with dummy variables
Generalized momenta w/ symbols (pj = dLdqjdot)
pr:=diff(Lsvel,rdot); pphi:=diff(Lsvel,phidot);
dLdr:=diff(Lsvel,ra);dLdphi:=diff(Lsvel,phia); # dL/dqj
valuesback:={rdot=diff(r,t),phidot=diff(phi,t),ra=r,phia=phi};
pra:= subs(valuesback,pr);
pphia:=subs(valuesback,pphi); # generalized p's 'live'
dLdra:=subs(valuesback,dLdr);
dLdphia:=subs(valuesback,dLdphi);
eqr:= diff(pra,t)-dLdra = 0; # lagrange's eqn in r.
eqphi:=diff(pphia,t)-dLdphia = 0; # ditto for phi.
eqra:= subs(r=a(t),phi=b(t),m=1,r0=1,k=2,eqr);
eqphia:=subs(r=a(t),phi=b(t),m=1,r0=1,k=2,eqphi); # new set of named
vars
The square brackets are important in the following dsolve command to keep the solutions in correct order
sol:=dsolve({eqra,a(0)=3/2,D(a)(0)=0,eqphia,b(0)=0,D(b)(0)=10},[a(t),b(t)],numeric);
sol(1); # take a look at the solution when t=1 sec
rp:= z -> rhs(sol(z)[2]); phip:= z -> rhs(sol(z)[4]); # magic assignments (Perry worked this out)
h:=plot(rp,0..3,color=blue):
j:=plot(phip,0..3,color=red):
display({h,j},title=` r(blue) and phi(red) vs t`);
plot([rp,phip,0..12],coords=polar,title=`polar plot of motion`);
Download
rotspr.ms [Use 'File Save']
Download
rotspr.mws [Use 'File Save']
| A mass m on a frictionless tabletop is connected by a string of length
H through a hole in the table to a mass M hanging below the table.
Done via lagrange's equations Students might be asked to a) Identify the two constants of the motion. |
![]() |
restart;with(plots):
alias(r=r(t),phi=phi(t)):
x1:=r*cos(phi): y1:=r*sin(phi): z:=H-r:
KE:=simplify(m/2*(diff(x1,t)^2+diff(y1,t)^2)+M/2*diff(z,t)^2);
PE:=-M*g*z;
L:=KE-PE; # lagrangian
valuesin:={diff(r,t)=rdot,diff(phi,t)=phidot,r=ra,phi=phia};
Lsvel:=subs(valuesin,L); # L with dummy variables
pr:=diff(Lsvel,rdot);
pphi:=diff(Lsvel,phidot); # generalized momenta w/ symbols (pj = dLdqjdot)
dLdr:=diff(Lsvel,ra);dLdphi:=diff(Lsvel,phia); # dL/dqj
valuesback:={rdot=diff(r,t),phidot=diff(phi,t),ra=r,phia=phi};
pra:= subs(valuesback,pr);
pphia:=subs(valuesback,pphi); # generalized p's 'live'
dLdra:=subs(valuesback,dLdr);
dLdphia:=subs(valuesback,dLdphi); # zero, so pphia is a constant of
the motion.
eqr:= diff(pra,t)-dLdra = 0; # lagrange's eqn in r.
eqphi:=diff(pphia,t)-dLdphia = 0; # ditto for phi.
vals:={r=rs(t),phi=phis(t),m=1,M=6,g=98/10};
eqra:= subs(vals,eqr); eqphia:=subs(vals,eqphi); # new set of named
vars
The square brackets are important in the following dsolve command to keep the solutions in correct order
sol:=dsolve({eqra,rs(0)=1,D(rs)(0)=0,eqphia,phis(0)=0,D(phis)(0)=30},[rs(t),phis(t)],numeric);
sol(1); # see exactly what the solution is made of
rp:= z -> rhs(sol(z)[2]); phip:= z -> rhs(sol(z)[4]);
phidotp:=z->rhs(sol(z)[5]); # phi dot for plotting
plot(phidotp,0..2,color=black,title=` d/dt phi vs t`);
h:=plot(rp,0..2,color=blue):
j:=plot(phip,0..2,color=red):
display({h,j},title=` r(blue) and phi(red) vs t`);
plot([rp,phip,0..6],coords=polar,title=`polar plot; dphi/dt=30 @ r=1`);
Download
table.ms [Use 'File Save']
Download table.mws
[Use 'File Save']
main line problems