Nasser Abbasi
» nma_orbit
nma_orbit - Program to compute the orbit of a comet.
Enter initial radial distance (AU): 1
Enter initial tangential velocity (AU/yr): pi/2
Enter alpha constant for the problem:0.02
Enter number of steps: 300
Enter time step (yr): 0.005
Max r occured at time step=1, norm(r)=1 AU, angle=0 degree
formula says -46.6602 degree
Max r occured at time step=34, norm(r)=0.998302 AU, angle=-47.6152 degree
formula says -44.488 degree
Max r occured at time step=65, norm(r)=0.994744 AU, angle=-91.8046 degree
formula says -41.6312 degree
Max r occured at time step=99, norm(r)=0.999155 AU, angle=-140.422 degree
formula says -46.1857 degree
Max r occured at time step=130, norm(r)=0.99318 AU, angle=175.068 degree
formula says -40.4269 degree
Max r occured at time step=163, norm(r)=0.99966 AU, angle=126.568 degree
formula says -46.6301 degree
Max r occured at time step=194, norm(r)=0.999733 AU, angle=80.069 degree
formula says -46.6631 degree
Max r occured at time step=228, norm(r)=0.996806 AU, angle=32.1933 degree
formula says -43.5446 degree
Max r occured at time step=258, norm(r)=0.98758 AU, angle=-15.6186 degree
formula says -36.5409 degree
Max r occured at time step=293, norm(r)=0.999583 AU, angle=-59.831 degree
formula says -46.6148 degree
SOURCE CODE
%
nma_orbit - Program to compute the orbit of a comet.
clear all; help nma_orbit; % Clear memory and print header
%
% Nasser
Abbasi, HW 3.14 Modified from teacher orbit.m
%
%* Set
initial position and velocity of the comet.
r0 = input('Enter initial radial distance (AU): ');
v0 = input('Enter initial tangential velocity (AU/yr): ');
r_now = [r0 0];
v_now = [0 v0];
%
% Save
initial angle, since I'll need this to find
% the
number of time steps it takes to cycle back to it.
% which
tells me how long one revolution it
%
initialAngleInRadian =
atan2(r_now(2),r_now(1));
alpha = input('Enter alpha constant for the problem:');
state = [ r_now(1)
r_now(2) v_now(1) v_now(2) ]; % Used by R-K routines
%
%
Parameter to pass to the R-K integrator via rk4.
%
param = struct( 'alpha',0, ...
'GM',0);
%* Set
physical parameters (mass, G*M)
param.GM = 4*pi^2; % Grav. const. * Mass of Sun
(au^3/yr^2)
param.alpha = alpha;
% constant for the force factor, see
problem description.
mass = 1.; % Mass of comet
adaptErr = 1.e-3; %
Error parameter used by adaptive Runge-Kutta
time = 0;
%* Loop
over desired number of steps using specified
% numerical method.
nStep = input('Enter number of steps: ');
tau = input('Enter
time step (yr): ');
numberOfSignChanges = 0;
lastAngle = initialAngleInRadian;
revolutionNumber = 0;
numberOfStepsLastRevolution
= 0;
iStepUpToLastRevolution = 0;
for iStep=1:nStep
%timeValue(iStep)= time;
%* Record position and energy for plotting.
rplot(iStep) = norm(r_now); % Record position for
polar plot
thplot(iStep) =
atan2(r_now(2),r_now(1));
%
% L, the anguler momentum is tracked.
L(iStep) = norm(r_now) * norm(v_now);
%
% This is extra, I keep track of how many
time steps it
% takes to make one revolution to
plot at the end.
%
if(
thplot(iStep) * lastAngle < 0 )
numberOfSignChanges = numberOfSignChanges + 1;
if( numberOfSignChanges == 2
)
revolutionNumber = revolutionNumber + 1;
numberOfStepsLastRevolution = iStep -
iStepUpToLastRevolution;
iStepUpToLastRevolution = iStep;
numberOfStepsPerRevolution( revolutionNumber ) =
numberOfStepsLastRevolution;
numberOfSignChanges = 0;
end;
end;
lastAngle =
thplot(iStep);
tplot(iStep) = time;
kinetic(iStep) = .5*mass*norm(v_now)^2; % Record
energies
potential(iStep) = -
param.GM*mass/norm(r_now);
[state time tau] = rka(state,time,tau,adaptErr,'nma_HW_3_14_deriv',param);
r_now = [state(1)
state(2)]; % 4th order Runge-Kutta
v_now = [state(3) state(4)];
end
%
% ignore
the first revolution, since it could have started anywhere, then look
% for 2
complete revlutions, and use always revolution 2 and 3 to find the
%
precesses angle
%
if(
revolutionNumber < 3 )
fprintf('Please run the
simulation for longer time, need at least 2 complete revolutions!');
return;
end
%
% extra:
I have at least 2 revolutions, plot time it takes to make one
%
revolution. We will see each revolution is taking less time to compelte
% than
the last one
%
figure;
stem(numberOfStepsPerRevolution);
title('number of time steps to complete one revolution');
xlabel('Revolution number');
ylabel('Number time steps to complete the revolution');
Axis([1 revolutionNumber 0
max(numberOfStepsPerRevolution)]);
%
% find
the all the indexes where max norm(r) occured
% I need
to do this, since this tells me the angles needed
%
j=0;
i=1;
maxRecorded=0;
while(1)
i=i+1;
if( i > length(rplot))
break;
end
if(rplot(i) < rplot(i-1))
if( ~maxRecorded)
j=j+1;
maxNorm(j,1) = rplot(i-1); %column
1 has the norm
maxNorm(j,2) =
i-1; %column
2 has the index
maxRecorded =1;
end
else
maxRecorded =0;
end
end
%
% Plot
the time steps at which max norm(r) occured
%
figure;
stem(maxNorm(:,2),maxNorm(:,1));
title('Time steps where position vector was maximum');
xlabel('Time step');
ylabel('Norm(r) in AU');
for(i=1:length(maxNorm))
angleInDegree= thplot(maxNorm(i,2)) * 180 / pi;
fprintf('Max r occured at time
step=%d, norm(r)=%g AU, angle=%g degree\n', ...
maxNorm(i,2),maxNorm(i,1),
angleInDegree );
a = sqrt( 1 + ((param.GM * param.alpha)/
L(maxNorm(i,2))^2) );
formulaPrecess= 360*(1-a)/a;
fprintf('formula says %g degree\n',formulaPrecess);
end
%* Graph
the trajectory of the comet.
figure;
polar(thplot,rplot,'-'); % Use polar plot for graphing orbit
xlabel('Distance (AU)'); grid;
S=sprintf('Initial radial=%g (AU), Initial V=%g (AU/yr), tau=%g
(AU yr), nStep=%d, Alpha=%g',r0,v0,tau,nStep,alpha);
title(S);
pause(1) % Pause for
1 second before drawing next plot
%* Graph
the energy of the comet versus time.
figure;
totalE = kinetic +
potential; %
Total energy
plot(tplot,kinetic,'-.',tplot,potential,'--',tplot,totalE,'-')
legend('Kinetic','Potential','Total');
xlabel('Time (yr)'); ylabel('Energy
(M AU^2/yr^2)');
function deriv
= nma_HW_3_14_deriv(s,t,param)
% Returns right-hand side of Kepler ODE; used
by Runge-Kutta routines
% Moified for problem 3.14
%
% Inputs
% s
State vector [r(1) r(2) v(1) v(2)]
% t
Time (not used)
% param
Parameter struct
% Output
% deriv
Derivatives [dr(1)/dt dr(2)/dt dv(1)/dt dv(2)/dt]
% Nasser
Abbasi, feb 19. 2002.
%*
Compute acceleration
r = [s(1) s(2)]; % Unravel
the vector s into position and velocity
v = [s(3) s(4)];
accel = -
param.GM*r/norm(r)^3; % Gravitational acceleration
accel = accel * (1 -
(param.alpha/norm(r)) );
%*
Return derivatives [dr(1)/dt dr(2)/dt dv(1)/dt dv(2)/dt]
deriv = [v(1) v(2) accel(1)
accel(2)];
return;