Documentos de Académico
Documentos de Profesional
Documentos de Cultura
1 Introdu
tion
This is a tutorial on solving the ordinary dierential equations of me
hani
s by
numeri
al methods. I will be very straightful: we will learn how to solve se
ond
order ODE (ordinary dierential equations) using a very good routine developed,
years ago, by Shampine and Gordon. It is based on the Adams method, but we
ouldn't
are less. Su
e it to say that the routine is of ex
ellent reliability. It
is in Fortran. If you don't know Fortran, it's OK. Fortran is the best language
to ignore, as you
an learn it in two days: I know, I learnt it in three days, and
I am really slow!
Don't try to understand the routine: it is enormous and sophisti
ated. It
does the following: you supply the dierential equation, the initial
onditions,
the initial and end values of the independent variable (the time, in our
ase) and
the pre
ision you want. The routine then
al
ulates the integration step so that
the required pre
ision is attained, and produ
es the position and velo
ity at the
end point. (A
tually, the step varies along the
omputation, being determined
anew at ea
h step).
In
ase you want to know more about the numeri
al treatment of ODE's, take a good look at
Hamming, Numeri
al Methods for S
ientists and Engineers. This is a great book! Its
hapter
on dierential equations is illuminating, even if you don't
are about numeri
al methods.
= f (y; t)
(1)
The exe
utable will be
alled main.out. This is, of
ourse, the optimisti
version. Probably error messages will
rop up, as always. . . You'll have to debug.
(I think it was Marvin Minsky who said \Programming is debugging a white
sheet of paper!").
Let us pro
eed by parts.
2.1
derivs.f
= f (y; t)
(2)
with f (y; t) = y y .
We have to write this equation in the way required by ode.f. This means
writing a routine like this:
subroutine derivs(
,a,b)
integer nt
parameter(nt=1)
double pre
ision a(nt),b(nt),
b(1) = a(1)*a(1)
return
end
d y
2
dt
= f (y;
dy
dt
;t
(3)
The best way to solve it is transforming it into a system of two rst order
2
equations. Suppose f (y; dy
dt ; t) = y . The tri
k is dening an auxiliary variable
through
dy
w =
(4)
dt
(5)
f y; w; t
(6)
(7)
(8)
Let's put this in the language required by ode.f. Here we will have two equations,
so nt=2. The array a(2) will have two elements,
(1) =
a(2)
=
a
(9)
(10)
y
w
dy
(2) =
dw
(11)
dt
(12)
dt
Let us now move to a more
on
rete example: a parti
le moving under the
a
tion of the gravitational eld. We treat the problem as a 3-dimensional one
for generality (though it is 2-dimensional, the orbits being plane
urves). The
equationas are:
2
d ~
r
dt
d x
dt
d y
2
dt
2
d z
dt
r
mM ~
r
(13)
mM x
r
mM y
r
mM z
r
(14)
(15)
(16)
subroutine ode(f,neqn,y,t,tout,relerr,abserr,iflag,work,iwork)
impli
it real*8(a-h,o-z)
double pre
ision subroutine ode integrates a system of neqn
first order ordinary differential equations of the form:
dy(i)/dt = f(t,y(1),y(2),...,y(neqn))
y(i) given at t .
the subroutine integrates from t to tout . on return the
parameters in the
all list are set for
ontinuing the integration.
the user has only to define a new value tout and
all ode again.
the differential equations are a
tually solved by a suite of
odes
de , step , and intrp . ode allo
ates virtual storage in the
relerr,abserr -- relative and absolute lo
al error toleran
es
iflag -- +1,-1. indi
ator to initialize the
ode. normal input
is +1. the user should set iflag=-1 only if it is
impossible to
ontinue the integration beyond tout .
all parameters ex
ept f , neqn and tout may be altered by the
ode on output so must be variables in the
alling program.
output from ode -
neqn -- un
hanged
y(*) -- solution at t
t -- last point rea
hed in integration. normal return has
t = tout .
tout -- un
hanged
relerr,abserr -- normal return has toleran
es un
hanged. iflag=3
signals toleran
es in
reased
iflag = 2 -- normal return. integration rea
hed tout
= 3 -- integration did not rea
h tout be
ause error
toleran
es too small. relerr , abserr in
reased
appropriately for
ontinuing
= 4 -- integration did not rea
h tout be
ause more than
500 steps needed
= 5 -- integration did not rea
h tout be
ause equations
appear to be stiff
= 6 -- invalid input parameters (fatal error)
the value of iflag is returned negative when the input
value is negative and the integration does not rea
h tout ,
i.e., -3, -4, -5.
work(*),iwork(*) -- information generally of no interest to the
user but ne
essary for subsequent
alls.
subsequent
alls to ode -
subroutine ode returns with all information needed to
ontinue
the integration. if the integration rea
hed tout , the user need
only define a new tout and
all again. if the integration did not
rea
h tout and the user wants to
ontinue, he just
alls again.
the output value of iflag is the appropriate input value for
subsequent
alls. the only situation in whi
h it should be altered
is to stop the integration internally at the new tout , i.e.,
hange output iflag=2 to input iflag=-2 . error toleran
es may
be
hanged by the user before
ontinuing. all other parameters must
remain un
hanged.
***********************************************************************
* subroutines de and step
ontain ma
hine dependent
onstants. *
dimension y(neqn),yy(neqn),wt(neqn),phi(neqn,16),p(neqn),yp(neqn),
1 ypout(neqn),psi(12),alpha(12),beta(12),sig(13),v(12),w(12),g(13)
external f
***********************************************************************
* the only ma
hine dependent
onstant is based on the ma
hine unit *
* roundoff error u whi
h is the smallest positive number su
h that *
* 1.0+u .gt. 1.0 . u must be
al
ulated and fouru=4.0*u inserted *
* in the following data statement before using de . the routine
*
* ma
hin
al
ulates u . fouru and twou=2.0*u must also be
*
* inserted in subroutine step before
alling de .
*
data fouru/.888d-15/
***********************************************************************
the
onstant maxnum is the maximum number of steps allowed in one
all to de . the user may
hange this limit by altering the
following statement
data maxnum/500/
***
***
***
test for improper parameters
fouru = 4.0 * d1ma
h(4)
***
if(neqn .lt. 1) go to 10
if(t .eq. tout) go to 10
if(relerr .lt. 0.0d0 .or. abserr .lt. 0.0d0) go to 10
eps = dmax1(relerr,abserr)
if(eps .le. 0.0d0) go to 10
if(iflag .eq. 0) go to 10
isn = isign(1,iflag)
iflag = iabs(iflag)
if(iflag .eq. 1) go to 20
if(t .ne. told) go to 10
if(iflag .ge. 2 .and. iflag .le. 5) go to 20
10 iflag = 6
return
on ea
h
all set interval of integration and
ounter for number of
steps. adjust input error toleran
es to define weight ve
tor for
subroutine step
20 del = tout - t
absdel = dabs(del)
tend = t + 10.0d0*del
if(isn .lt. 0) tend = tout
nostep = 0
kle4 = 0
stiff = .false.
releps = relerr/eps
abseps = abserr/eps
if(iflag .eq. 1) go to 30
if(isnold .lt. 0) go to 30
if(delsgn*del .gt. 0.0d0) go to 50
on start and restart also set work variables x and yy(*), store the
dire
tion of integration and initialize the step size
30 start = .true.
x = t
do 40 l = 1,neqn
40 yy(l) = y(l)
delsgn = dsign(1.0d0,del)
h = dsign(dmax1(dabs(tout-x),fouru*dabs(x)),tout-x)
if already past output point, interpolate and return
50 if(dabs(x-t) .lt. absdel) go to 60
all intrp(x,yy,tout,y,ypout,neqn,kold,phi,psi)
iflag = 2
t = tout
told = t
isnold = isn
return
if
annot go past output point and suffi
iently
lose,
extrapolate and return
60 if(isn .gt. 0 .or. dabs(tout-x) .ge. fouru*dabs(x)) go to 80
h = tout - x
all f(x,yy,yp)
do 70 l = 1,neqn
70 y(l) = yy(l) + h*yp(l)
iflag = 2
t = tout
told = t
isnold = isn
return
test for too many steps
80 if(nostep .lt. maxnum) go to 100
iflag = isn*4
10
11
12
13
rash = .true.
if(dabs(h) .ge. fouru*dabs(x)) go to 5
h = dsign(fouru*dabs(x),h)
return
5 p5eps = 0.5d0*eps
round = 0.0d0
do 10 l = 1,neqn
10 round = round + (y(l)/wt(l))**2
round = twou*dsqrt(round)
if(p5eps .ge. round) go to 15
eps = 2.0*round*(1.0d0 + fouru)
return
15
rash = .false.
g(1)=1.0d0
g(2)=0.5d0
sig(1)=1.0d0
if(.not.start) go to 99
initialize.
ompute appropriate step size for first step
all f(x,y,yp)
sum = 0.0d0
do 20 l = 1,neqn
phi(l,1) = yp(l)
phi(l,2) = 0.0d0
20 sum = sum + (yp(l)/wt(l))**2
sum = dsqrt(sum)
absh = dabs(h)
if(eps .lt. 16.0d0*sum*h*h) absh = 0.25d0*dsqrt(eps/sum)
h = dsign(dmax1(absh,fouru*dabs(x)),h)
hold = 0.0d0
k = 1
kold = 0
start = .false.
phase1 = .true.
nornd = .true.
if(p5eps .gt. 100.0d0*round) go to 99
nornd = .false.
do 25 l = 1,neqn
25 phi(l,15) = 0.0d0
14
99 ifail = 0
***
end blo
k 0
***
***
begin blo
k 1
***
ompute
oeffi
ients of formulas for this step. avoid
omputing
those quantities not
hanged when step size is not
hanged.
***
100 kp1
kp2
km1
km2
=
=
=
=
k+1
k+2
k-1
k-2
15
do 115 iq
temp3 =
v(iq) =
115 w(iq) =
go to 140
= 1,k
iq*(iq+1)
1.0d0/temp3
v(iq)
140 nsp2 = ns + 2
if(kp1 .lt. nsp2) go to 199
do 150 i = nsp2,kp1
limit2 = kp2 - i
temp6 = alpha(i-1)
do 145 iq = 1,limit2
145
w(iq) = w(iq) - temp6*w(iq+1)
150 g(i) = w(1)
199
ontinue
***
end blo
k 1
***
***
begin blo
k 2
***
predi
t a solution p(*), evaluate derivatives using predi
ted
solution, estimate lo
al error at order k and errors at orders k,
k-1, k-2 as if
onstant step size were used.
***
hange phi to phi star
16
17
265
18
19
20
hnew = absh*dmax1(0.5d0,dmin1(0.9d0,r))
hnew = dsign(dmax1(hnew,fouru*dabs(x)),h)
465 h = hnew
return
***
end blo
k 4
***
end
subroutine intrp(x,y,xout,yout,ypout,neqn,kold,phi,psi)
impli
it real*8(a-h,o-z)
the methods in subroutine step approximate the solution near x
by a polynomial. subroutine intrp approximates the solution at
xout by evaluating the polynomial there. information defining this
polynomial is passed from step so intrp
annot be used alone.
this
ode is
ompletely explained and do
umented in the text,
omputer solution of ordinary differential equations: the initial
value problem by l. f. shampine and m. k. gordon.
input to intrp -
all floating point variables are double pre
ision
the user provides storage in the
alling program for the arrays in
the
all list
dimension y(neqn),yout(neqn),ypout(neqn),phi(neqn,16),psi(12)
and defines
xout -- point at whi
h solution is desired.
the remaining parameters are defined in step and passed to intrp
from that subroutine
output from intrp -
yout(*) -- solution at xout
ypout(*) -- derivative of solution at xout
the remaining parameters are returned unaltered from their input
values. integration with step may be
ontinued.
dimension g(13),w(13),rho(13)
data g(1)/1.0d0/,rho(1)/1.0d0/
hi = xout - x
ki = kold + 1
kip1 = ki + 1
initialize w(*) for
omputing g(*)
do 5 i = 1,ki
21
temp1 = i
w(i) = 1.0d0/temp1
term = 0.0d0
ompute g(*)
do 15 j = 2,ki
jm1 = j - 1
psijm1 = psi(jm1)
gamma = (hi + term)/psijm1
eta = hi/psijm1
limit1 = kip1 - j
do 10 i = 1,limit1
10
w(i) = gamma*w(i) - eta*w(i+1)
g(j) = w(1)
rho(j) = gamma*rho(jm1)
15 term = psijm1
interpolate
20
25
30
35
do 20 l = 1,neqn
ypout(l) = 0.0d0
yout(l) = 0.0d0
do 30 j = 1,ki
i = kip1 - j
temp2 = g(i)
temp3 = rho(i)
do 25 l = 1,neqn
yout(l) = yout(l) + temp2*phi(l,i)
ypout(l) = ypout(l) + temp3*phi(l,i)
ontinue
do 35 l = 1,neqn
yout(l) = y(l) + hi*yout(l)
return
end
22
PARAMETER(nneqn=6)
DOUBLE PRECISION yy(nneqn),tt,ttout,rrelerr,aabserr
REAL*8 wwork(100+21*nneqn)
INTEGER*4 iiflag,iiwork(5)
EXTERNAL f
OPEN (unit=12, file='kepler.dat')
iiflag=1
rrelerr=1.0d-8
aabserr=1.0d-15
tt=0.D0
ttout=tt+0.1D0
yy(1)=1.D0
yy(2)=0.D0
yy(3)=0.D0
yy(4)=1.D0
yy(5)=0.D0
yy(6)=0.D0
do i=1,1000
all ode(derivs, nneqn, yy, tt, ttout, rrelerr, aabserr, iiflag,
&
wwork,iiwork)
ttout=tt+0.1D-1
write(12,*) yy(3),yy(1)
end do
CLOSE(unit=12)
stop
END
5 What to do?
1. Using
opy and paste,
reate the les derivs:f , ode:f and, in this
ase,
, in the same dire
tory.
2.Exe
ute the
ommand: g77 kepler.f ode.f derivs.f -o kepler.out
3.Exe
ute the
ommand: kepler.out
4.Exe
ute the
ommand: gnuplot
5.In gnuplot, exe
ute: plot \kepler.dat"
kepler:f
23
24