-------------------------------------------------------------------------
PHYS210 2009-11-03 LAB SUMMARY
NOTE: Item 1) below can be worked "automatically" via the instructor
supplied script, 'tp'. I.e. type 'tp' at the octave prompt.
1) Studying / using instructor-supplied octave functions to solve
nonlinear & linear pendulum equations
2) Use of instructor-supplied bash scripts to expedite binary search
3) Finding critical omega0 value, omega0*, for nonlinear pendulum using
binary search (level 6)
4) Investigating dependence of omega0* on level
NOTE: In the following, '>>' denotes the octave prompt
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1) Studying / using instructor-supplied octave functions to solve
nonlinear & linear pendulum equations
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Change to your ~/octave directory and start octave
% cd ~/octave
% octave
>> % Examine definition of 'pendulum' which solves the nonlinear
>> % pendulum equation using O(h^2) finite difference techniques
>> % as discussed in class. Recall that 'type '
>> % will display the definition of a function, as well as the
>> % location of the .m file
>> % Disable pager
>> more off
>> type pendulum
pendulum is the user-defined function defined from: /home/phys210/octave/pendulum.m
function [t theta omega] = pendulum(tmax, level, theta0, omega0)
% Solves nonlinear pendulum equation using second order finite difference
% approximation as discussed in class.
%
% Input arguments
%
% tmax: (real scalar) Final solution time.
% level: (integer scalar) Discretization level.
% theta0: (real scalar) Initial angular displacement of pendulum.
% omega0: (real scalar) Initial angular velocity of pendulum.
%
% Output arguments
%
% t: (real vector) Vector of length nt = 2^level + 1 containing
% discrete times (time mesh).
% theta: (real vector) Vector of length nt containing computed
% angular displacement at discrete times t(n).
% omega: (real vector) Vector of length nt containing computed
% angular velocity at discrete times t(n).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% trace controls "tracing" output. Set 0 to disable, non-0 to enable.
trace = 1;
% tracefreq controls frequency of tracing output in main time step loop.
tracefreq = 100;
if trace
fprintf('In pendulum: Argument dump follows\n');
tmax, level, theta0, omega0
pause(1)
end
% Define number of time steps and create t, theta and omega arrays of
% appropriate size for efficiency.
nt = 2^level + 1;
t = linspace(0.0, tmax, nt);
theta = zeros(1,nt);
omega = zeros(1,nt);
% Determine discrete time step from t array.
deltat = t(2) - t(1);
% Intialize first two values of the pendulum's angular displacement.
theta(1) = theta0;
theta(2) = theta0 + deltat * omega0 - 0.5 * deltat^2 * sin(theta0);
if trace
fprintf('deltat=%g theta(1)=%g theta(2)=%g\n',...
deltat, theta(1), theta(2));
end
% Initialize first value of the angular velocity.
omega(1) = omega0;
% Evolve the oscillator to the final time using the discrete equations
% of motion. Also compute an estimate of the angular velocity at
% each time step.
for n = 2 : nt-1
% This generates tracing output every 'tracefreq' steps.
if rem(n, tracefreq) == 0
fprintf('pendulum: Step %d of %d\n', n, nt);
end
theta(n+1) = 2 * theta(n) - theta(n-1) - deltat^2 * sin(theta(n));
omega(n) = (theta(n+1) - theta(n-1)) / (2 * deltat);
end
% Use linear extrapolation to determine the value of omega at the
% final time step.
omega(nt) = 2 * omega(nt-1) - omega(nt-2);
end
>> % There is a similar function, lpendulum, which solves the
>> % *linear* pendulum equation (i.e. the one that you study in
>> % elementary physics courses.
>> type lpendulum
lpendulum is the user-defined function defined from: /home/phys210/octave/lpendulum.m
function [t theta omega] = lpendulum(tmax, level, theta0, omega0)
% Solves linear pendulum equation using second order finite difference
% approximation.
%
% Input arguments
%
% tmax: (real scalar) Final solution time.
% level: (integer scalar) Discretization level.
% theta0: (real scalar) Initial angular displacement of pendulum.
% omega0: (real scalar) Initial angular velocity of pendulum.
%
% Output arguments
%
% t: (real vector) Vector of length nt = 2^level + 1 containing
% discrete times (time mesh).
% theta: (real vector) Vector of length nt containing computed
% angular displacement at discrete times t(n).
% omega: (real vector) Vector of length nt containing computed
% angular velocity at discrete times t(n).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% trace controls "tracing" output. Set 0 to disable, non-0 to enable.
trace = 1;
% tracefreq controls frequency of tracing output in main time step loop.
tracefreq = 100;
if trace
fprintf('In lpendulum: Argument dump follows\n');
tmax, level, theta0, omega0
pause(1)
end
% Define number of time steps and create t, theta and omega arrays of
% appropriate size for efficiency.
nt = 2^level + 1;
t = linspace(0.0, tmax, nt);
theta = zeros(1, nt);
omega = zeros(1, nt);
% Determine discrete time step from t array.
deltat = t(2) - t(1);
% Intialize first two values of the pendulum's angular displacement.
theta(1) = theta0;
theta(2) = theta0 + deltat * omega0 - 0.5 * deltat^2 * theta0;
if trace
fprintf('deltat=%g theta(1)=%g theta(2)=%g\n',...
deltat, theta(1), theta(2));
end
% Initialize first value of the angular velocity.
omega(1) = omega0;
% Evolve the oscillator to the final time using the discrete equations
% of motion. Also compute an estimate of the angular velocity at
% each time step.
for n = 2 : nt-1
% This generates tracing output every 'tracefreq' steps.
if rem(n, tracefreq) == 0
fprintf('lpendulum: Step %d of %d\n', n, nt);
end
theta(n+1) = 2 * theta(n) - theta(n-1) - deltat^2 * theta(n);
omega(n) = (theta(n+1) - theta(n-1)) / (2 * deltat);
end
% Use linear extrapolation to determine the value of omega at the
% final time step.
omega(nt) = 2 * omega(nt-1) - omega(nt-2);
end
>> % Try using the functions: in all cases below, we will start with
>> % theta0 = 0 (i.e. so that the pendulum is hanging vertically), and
>> % will vary the initial angular velocity omega0
>> % Start with a small value of omega0, and compute with input arguments
>> % as follows
>> tmax = 40.0; theta0 = 0; level = 8; omega0 = 0.01;
>> [t theta omega] = pendulum(tmax, level, theta0, omega0);
In pendulum: Argument dump follows
tmax = 40
level = 8
theta0 = 0
omega0 = 0.010000
deltat=0.15625 theta(1)=0 theta(2)=0.0015625
pendulum: Step 100 of 257
pendulum: Step 200 of 257
>> [t ltheta lomega] = lpendulum(tmax, level, theta0, omega0);
In lpendulum: Argument dump follows
tmax = 40
level = 8
theta0 = 0
omega0 = 0.010000
deltat=0.15625 theta(1)=0 theta(2)=0.0015625
lpendulum: Step 100 of 257
lpendulum: Step 200 of 257
>> % Plot the results
>> clf; hold on; plot(t, theta, 'r'); plot(t, ltheta, '.og');
>> % Observe how there is very little difference between the results,
>> % as one would expect.
>> % Perform a basic convergence test for the nonlinear pendulum using
>> % levels 6, 7 and 8
>> [t6 theta6 omega6] = pendulum(tmax, 6, theta0, omega0);
In pendulum: Argument dump follows
tmax = 40
level = 6
theta0 = 0
omega0 = 0.010000
deltat=0.625 theta(1)=0 theta(2)=0.00625
>> [t7 theta7 omega7] = pendulum(tmax, 7, theta0, omega0);
In pendulum: Argument dump follows
tmax = 40
level = 7
theta0 = 0
omega0 = 0.010000
deltat=0.3125 theta(1)=0 theta(2)=0.003125
pendulum: Step 100 of 129
>> [t8 theta8 omega8] = pendulum(tmax, 8, theta0, omega0);
In pendulum: Argument dump follows
tmax = 40
level = 8
theta0 = 0
omega0 = 0.010000
deltat=0.15625 theta(1)=0 theta(2)=0.0015625
pendulum: Step 100 of 257
pendulum: Step 200 of 257
>> % First graph theta from the 3 calculations on the same plot
>> clf; hold on; plot(t6, theta6, 'r-.o');
>> plot(t7, theta7, 'g-.+'); plot(t8, theta8, 'b-.*');
>> % "Filter" the level 7 and 8 theta arrays so that they have the same
>> % length as the level 6 arrays (with values defined at the times in t6)
>> theta7 = theta7(1:2:length(theta7));
>> theta8 = theta8(1:4:length(theta8));
>> % Compute the differences in the grid functions from level to level ...
>> dtheta67 = theta6 - theta7;
>> dtheta78 = theta7 - theta8;
>> % ... and make a plot of those functions
>> clf; hold on; plot(t6, dtheta67, 'r-.o'); plot(t6, dtheta78, 'g-.+');
>> % Now scale dtheta78 by 4 and replot with dtheta67.
>> % If the convergence is second order, the curves should be
>> % nearly coincident
>> dtheta78 = 4 * dtheta78;
>> clf; hold on; plot(t6, dtheta67, 'r-.o'); plot(t6, dtheta78, 'g-.+');
>> % ARE THEY NEARLY COINCIDENT? (YES). Also note how the magnitude
>> % of the error increases with time
>> % Now use a sequence of ever larger values of omega0 at level 8
>> % Remember, this means that we will be giving the pendula ever
>> % increasing initial angular velocities, so the resulting amplitude
>> % of the oscillation will also increase.
>> %
>> % A key result that you can see immediately is whereas the period
>> % (frequency) of the linear pendulum (green) stays constant (i.e. is NOT
>> % dependent on the amplitude of the oscillation), the period of
>> % the nonlinear pendulum (red) DOES depend on the amplitude (or,
>> % equivalently, on omega0)
>>
>> tmax = 40; level = 8; theta0 = 0;
>> for omega0 = [0.1 0.3 1.0 1.5 1.9]
[t theta omega] = pendulum(tmax, level, theta0, omega0);
[t ltheta lomega] = lpendulum(tmax, level, theta0, omega0);
clf; hold on; ptitle = sprintf('omega_0 = %g',omega0);
plot(t, theta, 'r'); plot(t, ltheta, '-.og');
title(ptitle);
input('Type ENTER to continue: ');
clf; hold on; ptitle = sprintf('Phase space plot: omega_0 = %g',omega0);
plot(theta, omega, 'r'); plot(ltheta, lomega, '-.og');
title(ptitle);
input('Type ENTER to continue: ');
end
>> % Now, let's give the nonlinear pendulum an even larger initial kick ..
>> omega0 = 2.05;
>> [t theta omega] = pendulum(tmax, level, theta0, omega0);
>> clf; plot(t,theta,'r');
>> % Can you explain this result physically?
>> % Note that we have now seen two distinct types of behaviour in
>> % the nonlinear oscillator as illustrated by the following ...
>> [t thetalo omegalo] = pendulum(tmax, level, theta0, 1.9);
>> [t thetahi omegahi] = pendulum(tmax, level, theta0, 2.05);
>> clf; hold on;
>> plot(t, thetalo, 'g'); plot(t, thetahi, 'r');
>> title('"lo(w)" \& "hi(gh)" behaviour');
>> % ... so somewhere in the interval [1.9, 2.05] there should
>> % be a "critical value" of omega0 where the behaviour type
>> % changes.
>> % We will try to find this value using the technique of binary
>> % search, or bisection.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2) Use of instructor-supplied bash scripts to expedite binary search
(also known as the "bisection method"
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
There are a set of scripts in ~/phys210/bin (which should therefore
be in your path) that can be used to expedite a binary search (google
"bisection method" if this concept is unfamiliar to you)
They are
1) bsnew
2) bscurr
3) bslo
4) bshi
5) bslohi
6) bsfrac
With usages and functions as follows
1) bsnew
usage: bsnew
FUNCTION: Initializes a new binary search in the current directory
with initial interval [, ]
2) bscurr
usage: bscurr
FUNCTION: Returns current midpoint of interval
3) bslo
usage: bslo
FUNCTION: Updates interval so that current midpoint becomes new "lo" value
4) bshi
usage: bshi
FUNCTION: Updates interval so that current midpoint becomes new "hi" value
4) bslohi
usage: bslohi
FUNCTION: Echoes interval end-point values ("lo" and "hi")
5) bsfrac
usage: bsfrac
FUNCTION: Returns normalized width of current interval. Tells you to
how many digits you have narrowed the search. When bsfrac returns
something of order 10^{-16} you have narrowed the search about as far
as you can
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3) Finding critical omega0 value, omega0*, for nonlinear pendulum using
binary search (level 6)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Have at least two terminal windows open, and ensure that you are in
your ~/octave directory in both
Use one window to use the above scripts to manage the binary search,
and the other to run pendulum with the value returned by bscurr for
omega0
WINDOW 1
% cd ~/octave
% # Initialize the search: Note that the script returns the
% # values defining the initial interval
% bsnew 1.9 2.05
1.9
2.05
% # Get the current midpoint
% bscurr
1.975000000000000e+00
WINDOW 2
% cd ~/octave
% octave
>> format long
>> % Set fixed problem parameters
>> tmax = 40; level = 6; theta0 = 0;
>> % Set omega0 to midpoint
>> omega0 = 1.975000000000000e+00
>> % Solve the pendulum equation, plot the angular displacement
>> % and from the plot, determine which type of behaviour it
>> % exhibited
>> [t theta omega] = pendulum(tmax, level, theta0, omega0); clf; plot(t,theta);
>> % In this case you should see the displacement growing with time (i.e.
>> % "hi" behaviour, so in WINDOW 1 execute
WINDOW 1
% bshi
1.9
1.975000000000000e+00
% # ... note how the updated interval values are echoed.
% # Generate the new midpoint value ...
% bscurr
1.937500000000000e+00
% # ... and go back to WINDOW 2 (the octave session), repeat the
% # process with the new value of omega0
WINDOW 2
>> omega0 = 1.937500000000000e+00
>> [t theta omega] = pendulum(tmax, level, theta0, omega0); clf; plot(t,theta);
>> # Observed hi behaviour
WINDOW 1
% bshi; echo; bscurr
1.9
1.937500000000000e+00
1.918750000000000e+00
WINDOW 2
>> omega0 = 1.918750000000000e+00;
>> [t theta omega] = pendulum(tmax, level, theta0, omega0); clf; plot(t,theta);
>> # Observed lo behaviour
WINDOW 1
% bslo; echo; bscurr
1.918750000000000e+00
1.937500000000000e+00
1.928125000000000e+00
AND CONTINUE UNTIL YOU HAVE DETERMINED THE CRITICAL VALUE, omega0*, TO AT LEAST
SIX DECIMAL PLACES
WHAT DO YOU NOTICE ABOUT THE PERIOD OF OSCILLATION (for "lo" values)
AS omega0 -> omega0*?
CAN YOU EXPLAIN WHAT IS HAPPENING PHYSICALLY?
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4) Investigating dependence of omega0* on level
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Repeat the above search procedure for levels 7 and 8 and record
your estimates for omega0* as a function of level in README.pendulum
in ~/octave.
CAN YOU MAKE A CONJECTURE ABOUT THE CONTINUUM VALUE OF omega0* (i.e.
THE VALUE FOR level -> infinity, deltat -> 0) AND, IF SO, CAN YOU
PROVE THAT THIS IS WHAT ONE SHOULD EXPECT??