0% found this document useful (0 votes)
22 views

ODE Notes

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views

ODE Notes

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Department of Physics

University of Dhaka
Computational Physics
ORDINARY DIFFERENTIAL EQUATION

An ODE is an equality involving a function and its derivatives, where the unknown function
is a function of one variable. An ODE of order n is an equation of the form

f (x, y(x), y 0 (x), y 00 (x), ........y n (x)) = 0

where you have a single independent variable x, a vector-valued function, f , and its derivatives.
Problems involving ordinary differential equations can always be reduced to the study of sets
of first-order differential equations. For example, the equation

d2 y dy
2
+ q(x) = r(x)
dx dx
can be written as two first-order equations:
dy
= z(x)
dx
dz
= r(x) − q(x)z(x)
dx
where z is a new variable. The usual new choice for the new variables is to let them just be
derivatives of each other (and the original variable). This exemplifies the procedure for an
arbitrary ODE. Thus, the generic problem for an ordinary differential equation is reduced to a
set of n coupled first-order differential equations.
The second thing to remember with ODEs is that the problem specification is incomplete
without knowledge of the nature of the problems boundary conditions. Boundary conditions
can be as simple as discrete numerical values or as complex as nonlinear equations, but are
not maintained outside of thier specified constraints. Typically, the numerical methods used
in solving ODEs are directed by the nature of the boundary conditions and you usually need
to constrain the solution with one boundary condition per unknown. The two catergories of
boundary conditions are illustrated below.
1. Initial Value Problem: If all of the boundary conditions are specified at the starting
time, its an initial value problem. An example of such a problem arises when trying to
describe a balls vertical movement over time as it is tossed in the air. Here, one must
specify the balls starting position and velocity to have a solution.

2. Boundary Value Problem: A different kind of problem arises if the boundary con-
ditions are specified at more than one x. For instance, say we want to throw a ball in
a waste basketthis involves getting the ball to be at a particular point at a given time.
Another way of phrasing this is that you know where you are throwing from and the
final position, but dont care about the velocity. Explicitly, in this case the boundary
conditions are y(0) = 0 and y(1) = k.

• Euler’s Method This is a numerical methods that will allow us to approximate solu-
tions to differential equations. There are many different methods that can be used to
approximate solutions to a differential equation and in fact whole classes can be taught

1
just dealing with the various methods. We are going to look at one of the oldest and
easiest to use here. This method was originally devised by Euler and is called, oddly
enough, Eulers Method. Let us start with a general first order differential equation along
with the initial condition,
dy
= f (t, y), y(t0 ) = y0
dt
Where f (y, t) is a known function and the values in the initial condition are also known
numbers. If f and fy are continuous functions then there is a unique solution to the ODE
in some surrounding of t = t0 . So let us assume that everything is nice and continuous so
that we know that a solution will in fact exist. And we want to approximate the solution
near t = t0 . Well start with the two pieces of information that we do know about the
solution. First, we know the value of the solution at t = t0 from the initial condition.
Second, we also know the value of the derivative at t = t0 . We can get this by plugging
the initial condition into f (t, y) into the differential equation itself. So, the derivative at
this point is.
dy
= f (t0 , y0 )
dt t=t0
Now, recall from Calculus class that these two pieces of information are enough for us to
write down the equation of the tangent line to the solution at t = t0 . The tangent line is
y = y0 + f (t0 , y0 )(t − t0 )

Figure 1: The tangent line

If t1 is close enough to t0 then the point y1 on the tangent line should be fairly close to
the actual value of the solution at t1 , or y(t1 ). Finding y1 is easy enough. All we need to
do is plug t1 in the equation for the tangent line.
y1 = y0 + f (t0 , y0 )(t1 − t0 )

Now, we would like to proceed in a similar manner, but we dont have the value of the
solution at t1 and so we wont know the slope of the tangent line to the solution at this
point. This is a problem. We can partially solve it however, by recalling that y1 is an
approximation to the solution at t1 . If y1 is a very good approximation to the actual
value of the solution then we can use that to estimate the slope of the tangent line at t1 .
So, lets hope that y1 is a good approximation to the solution and construct a line through
the point (t1 , y1 ) that has slope f (t1 , y1 ). This gives
y = y1 + f (t1 , y1 )(t − t1 )

2
Now, to get an approximation to the solution at t = t2 we will hope that this new line
will be fairly close to the actual solution at t2 and use the value of the line at t2 as an
approximation to the actual solution. This gives.

y2 = y1 + f (t1 , y1 )(t2 − t1 )

We can continue in this fashion. Use the previously computed approximation to get the
next approximation. So,

y3 = y2 + f (t2 , y2 )(t3 − t2 )
y4 = y3 + f (t3 , y3 )(t4 − t3 )
and so on In general, if we have tn and the approximation to the solution at this point,
yn , and we want to find the approximation at tn+1 all we need to do is use the following.

yn+1 = yn + f (tn , yn )(tn+1 − tn )

If we define f (tn , yn ) = fn and (tn+1 − tn ) = h , then the formula become,

yn+1 = yn + hfn

So, how do we use Eulers Method? Its fairly simple. We start with the first equation and
then decide if we want to use a uniform step size or not. Then starting with (t0 , y0 ) we
repeatedly evaluate the last equation depending on whether we chose to use a uniform
step size or not. We continue until weve gone the desired number of steps or reached the
desired time. This will give us a sequence of numbers y1 , y2 , y3 , yn that will approximate
the value of the actual solution at t1 , t2 , t3 , tn .
What do we do if we want a value of the solution at some other point than those used
here? One possibility is to go back and redefine our set of points to a new set that will
include the points we are after and redo Eulers Method using this new set of points.
However this is cumbersome and could take a lot of time especially if we had to make
changes to the set of points more than once.
In practice you would need to write a computer program to do these computations for
you. In most cases the function f(t,y) would be too large and/or complicated to use by
hand and in most serious uses of Eulers Method you would want to use hundreds of steps
which would make doing this by hand prohibitive. So, here is a bit of pseudo-code that
you can use to write a program for Eulers Method that uses a uniform step size, h.

? define f (t, y)
? input t0 and y0
? input step size, h and the number os steps, n.
? for i form 1 to n do
 m = f (t0 , y0 )
 y1 = y0 + h ∗ m
 t1 = t0 + h
 Print t1 and y1
 t0 = t1

3
 y0 = y1
? end

The pseudo-code for a non-uniform step size would be a little more complicated, but it
would essentially be the same.
? Solve the differential equation
dy
+ 2y = 2 − e−4t , y(0) = 1
dt
#include<iostream>
#include<fstream>
#include<cmath>
using namespace std;
ofstream fout(”euler1.dat”);
double N=500, h=0.1;
double f(double t, double y){
return 2-exp(-4*t)-2*y; }
void euler1(double h, double t0, double y0){
double y=y0;
for (double t=t0;t<=5.0; t+=h){
fout<<t<<” ”<<y<<” ”<< (1 + 0.5 ∗ exp(−4 ∗ t) − 0.5 ∗ exp(−2 ∗ t)) <<endl;
y+=h*f(t,y); }
}
int main(){
euler1(0.1,0.0,1.0);
return 0; }
The obtained result is plotted with the exact result below;

Figure 2: The green line is the exact result and red dot is the calculation using Euler’s method.

It is clear from the figure that the Euler’s method does not work where the function
is oscillatory. And it works better where the function is smooth. The exact solution
of the above equation is

y(t) = 1 + 0.5e−4t − 0.5e−2t

? Let us solve another example;


dy
− y = −0.5et/2 sin(5t) + 5et/2 cos(5t) y(0) = 0
dt
4
The exact solution of the above equation is y(t) = et/2 sin(5t)
#include<iostream>
#include<fstream>
#include<cmath>
using namespace std;
ofstream fout(”euler2.dat”);
double N=500, h=0.1;
double f(double t, double y){
return y-0.5*exp(0.5*t)*sin(5*t)+5*exp(0.5*t)*cos(5*t); }
void euler1(double h, double t0, double y0){
double y=y0;
for (double t=t0;t<=5.0; t+=h){
fout<<t<<” ”<<y<<” ”<<(exp(0.5*t)*sin(5*t))<<endl;
y+=h*f(t,y); }
}
int main(){
euler1(0.1,0.0,0.0);
return 0;
}
The obtained results are presented in the figure below.

Figure 3: The green line is the exact result and red dot is the calculation using Euler’s method.

However, unlike the last example increasing t sees an increasing error. This behavior
is fairly common in the approximations. We shouldnt expect the error to decrease
as t increases as we saw in the last example. Each successive approximation is found
using a previous approximation. Therefore, at each step we introduce error and so
approximations should, in general, get worse as t increases.
So, what is the difference betwen yn+1 and the real yn+1 ? Lets look at the accuracy
of this method. The standard approach to do this is to expand in Taylor series and
compare.
h
y(xn + h) = y(xn ) + hy 0 (xn ) + 2 y 00 (xn ) + O(h3 )
2
h
yn+1 − y(xn + h) = 2 y 00 (xn ) + O(h3 ) = O(h2 )
2
2
The error is of order h and this makes it a first order accurate method (the method
cancels out errors up to order 1). We can think of this error intuitively, that the
method assumes the function is straight, which will systematically wander towards
the outside of the curve.

5
 Backward Euler method: Instead of using

yn+1 = yn + hf (xn , yn )

Use
yn+1 = yn + hf (xn+1 , yn+1 )
This time use a backward difference for approximating the derivative at t = tn+1 .
The unknown yn+1 appears implicitly in this equation hence named implicit. It
still needs to be solved for as a function of yn .
 Trapezoidal rule:
h
yn+1 = yn + [f (xn , yn ) + f (xn+1 , yn+1 )]
2
#include<iostream>
#include<fstream>
#include<cmath>
using namespace std;
ofstream fout(”euler2.dat”);
double N=500, h=0.001;

double f(double t, double y){


return y-0.5*exp(0.5*t)*sin(5*t)+5*exp(0.5*t)*cos(5*t);
}
void euler1(double h, double t0, double y0){
double y1=y0;
double y=0.0;
for (double t=t0;t<=5.0; t+=h){
fout<<t<<” ”<<y1<<” ”<<y<<” ”<<(exp(0.5*t)*sin(5*t))<<endl;
y1+=h*f(t,y);
y+=0.5*h*(f(t,y)+f(t+h,y1)); }
}
int main(){
euler1(0.1,0.0,0.0);

return 0; }

• 2nd order ODE: For second order ODE one need to decouple the equation into two
first order ODE. For example
d2 x
= −kx
dt2
can be written as
dx dv
v= and = −kx
dt dt
And, one apply Euler’s method on both v and x simultaneously as follows,

xn+1 = xn + f (v, x, t) ∗ h

vn+1 = vn + f (x, t) ∗ h

6
Simple Harmonic Pendulum
A very widely used problem in computational physics is to solve the 2nd order differential
equation of a Simple Harmonic Pendulum. The 2nd order differential equation of a simple
pendulum can be given as
d2 θ g
2
+ θ=0
dt L
st
, One can decouple the equation into two 1 order differential equation as follows:


dt
dω g
=− θ
dt L
• One can rightly use Euler’s method for this as follows:

? initialize t = 0, θ(0) and ω(0)


? repeat until t ≤ tmax
 ω(t + dt) = ω(t) − Lg ∗ θ(t) ∗ dt
 θ(t + dt) = θ(t) + ω(t) ∗ dt
 t = t + dt

Euler algorithm is unstable- energy does not conserved in this approach (You Will See in
a Few Seconds!!)

• Euler-Cromer method. A very simple modification of Euler’s method is done by Cromer,


and it work very nicely for 2nd order differential equation. The modification is to Use the
Updated velocity while calculating updated position. The euler-cromer algorithm
is as follows.

? initialize t = 0, θ(0) and ω(0)


? repeat until t ≤ tmax
 ω(t + dt) = ω(t) − Lg ∗ θ(t) ∗ dt
 θ(t + dt) = θ(t) + ω(t + dt) ∗ dt
 t = t + dt
Euler-Cromer method conserve energy in each period of a simple harmonic motion.

Example:In the following example we will solve the equation of a simple harmonic motion
by using both the Euler method and Euler-Cromer method. And will compare the results.
#include <cmath>
#include <cstdlib>
#include <fstream>
#include <iostream>
using namespace std;
const double g = 9.80;
const double L = 1;
double t;
double theta;
double omega;

7
void EulerStep( double t, double theta, double omega, double dt){
double omegaOld;
ofstream file(”euler-file.dat”);
for(int i=0;i<=100;i++){
omegaOld=omega;
omega -= (g/L) * theta * dt;
theta += omegaOld * dt;
t += dt;
file<< t <<” ” << theta <<” ” << omega<<endl; } }
void EulerCromerStep( double t, double theta, double omega,double dt){
ofstream file(”cromer-file.dat”);
for(int i=0;i <=100;i++){
omega -= (g/L) * theta * dt;
theta += omega * dt;
t += dt;
file<< t <<” ” << theta <<” ” << omega<<endl;
}}
int main(){
t = 0;
theta = 0;
omega = 1;
double dt=0.1;
EulerCromerStep(t, theta, omega,dt);
EulerStep(t, theta, omega,dt);
return 0; }

Figure 4: The green line is the Displacement vs Time graph and the Green line is the Velocity
vs Time graph, Obtained from the Euler’s method.

It is clear from the figure that the displacement amplitude and also the velocity amplitude
is increasing with time, which means that the energy is not conserved in the system. Now
let us see the same results obtained in the Euler-Cromer method. In the Euler-Cromer
method (figure below) we see that both the displacement and the velocity amplitude
remain constant over time. So, in the Euler-Cromer method the energy remain constant.

8
One can plot the phase diagram obtained in both the above to check if energy
really conserve or not.

Figure 5: The green line is the Displacement vs Time graph and the Green line is the Velocity
vs Time graph, Obtained from the Euler-Cromer method.

Runge-Kutta Method
Runge-Kutta (RK) methods are based on Taylor expansion formulae, but yield in general
better algorithms for solutions of an ODE. The basic philosophy is that it provides an
intermediate step in the computation of yi+1
Consider the following differential equation
dy
= f (t, y)
dt
and Z
y(t) = f (t, y)dt

and Z ti+1
yi+1 = yi + f (t, y)dt
ti

To demonstrate the philosophy behind RK methods, let us consider the second-order RK


method, RK2. The first approximation consists in Taylor expanding f (t, y) around the
center of the integration interval ti to ti+1 , i. e at ti + h/2, h being the step size. Using
the midpoint formula for an integral, defining y(ti + h/2) = yi+1/2 and ti + h/2 = ti+1/2 ,
we obtain Z ti+1
f (t, y)dt ≈ hf (ti+1/2 , yi+1/2 ) + O(h3 )
ti

Which means that we have

yi+1 = yi + hf (ti+1/2 , yi+1/2 ) + O(h3 )

However, we do not know the value of yi+1/2 . Here comes thus the next approximation,
namely, we use Euler’s method to approximate yi+1/2 . We then have
h dy h
y(i+1/2) = yi + = y(ti ) + f (ti , yi )
2 dt 2
9
This means that we can define the following algorithm for the second-order Runge-Kutta
method, RK2.
k1 = hf (ti , yi )
,
k2 = hf (t(i+1/2) , yi + k1 /2)
with the final value
yi+1 ≈ yi + k2 + O(h3 ).
The difference between the previous one-step methods is that we now need an intermediate
step in our evaluation, namely t(i+h/2) = t(i+1/2) where we evaluate the derivative f. This
involves more operations, but the gain is a better stability in the solution. The fourth-
order Runge-Kutta, RK4, which we will employ in the solution of various differential
equations below, is easily derived. The steps are as follows. We start again with the
equation Z ti+1
yi+1 = yi + f (t, y)dt
ti

but instead of approximating the integral with the midpoint rule, we use now Simpsons
rule at ti + h/2 , h being the step. Using Simpsons formula for an integral, defining
y(ti + h/2) = y(i+1/2) and ti + h/2 = t(i+1/2) , we obtain
Z ti+1
h
f (t, y)dt ≈ [f (ti , yi ) + 4f (ti+1/2 , yi+1/2 ) + f (ti+1 , yi+1 )] + O(h5 )
ti 6
This means that, we have
h
yi+1 = yi + [f (ti , yi ) + 4f (ti+1/2 , yi+1/2 ) + f (ti+1 , yi+1 )] + O(h5 )
6
However, we do not know the values of yi+1/2 and yi+1 . The fourth-order Runge-Kutta
method splits the midpoint evaluations in two steps, that is we have
h
yi+1 = yi + [f (ti , yi ) + 2f (ti+1/2 , yi+1/2 ) + f (ti+1 , yi+1 ) + 2f (ti+1/2 , yi+1/2 ) + f (ti+1 , yi+1 )]
6
since we want to approximate the slope at yi+1/2 in two steps. The first two function
evaluations are as for the second order Runge-Kutta method. The algorithm is as follows
? We compute first
k1 = hf (ti , yi )
which is nothing but the slope at ti . If we stop here we have Euler’s method.
? Then we compute the slope at the midpoint using Eulers method to predict yi+1/2 ,
as in the secondorder Runge-Kutta method. This leads to the computation of

k2 = hf (ti + h/2, yi + k1 /2).

? The improved slope at the midpoint is used to further improve the slope of yi+1/2 by
computing
k3 = hf (ti + h/2, yi + k2 /2).
? With the latter slope we can in turn predict the value of yi+1 via the computation
of
k4 = hf (ti + h, yi + k3 ).

10
? The final algorithm becomes then
1
yi+1 = yi + (k1 + 2k2 + 2k3 + k4 )
6
Thus, the algorithm consists in first calculating k1 with ti , y1 and f as inputs.
Thereafter, we increasethe step size by h/2 and calculate k2 , then k3 and finally k4 .
With this caveat, we can then obtain the new value for the variable y. It results in
four function evaluations, but the accuracy is increased by two orders compared with
the second-order Runge-Kutta method. The fourth order Runge-Kutta methodhas a
global truncation error which goes like O(h4 ). Fig. gives a geometrical interpretation
of the fourth-order Runge-Kutta method.

Figure 6: Geometrical interpretation of the fourth-order Runge-Kutta method. The derivative


is evaluated at four points, once at the intial point, twice at the trial midpoint and once at the
trial endpoint. These four derivatives constitute one Runge-Kutta step resulting in the final
value.

Example1:
Solve the differential equation
dx √
=t x
dt
with the initial condition t0 = 0, and x0 = 1. Given the exact solution is

(t2 + 4)2
x=
16
Solution:
#include<iostream>
#include<fstream>
#include<cmath>

using namespace std;

double f(double indep, double dep){


return indep*sqrt(dep);

11
}
double rk4(double h, double t0, double x0){
double k1=h*f(t0,x0);
double k2=h*f(t0+(h/2.0), x0+(k1/2.0));
double k3=h*f(t0+(h/2.0),x0+(k2/2.0));
double k4=h*f(t0+h,x0+k3);
return x0+(k1+2*k2+2*k3+k4)/6.0;
}
int main(){
ofstream fout(”rk1.dat”);
double t=0.0, x=1.0, dt=0.1;
for(t=0.0;t≤10.0; t+=dt){
fout<<t<<” ”<<x<<” ”<<((t*t)+4)*((t*t)+4)/16.0<<endl;
x=rk4(dt,t,x);
}
return 0;
}

Example 2:
Solve the 2nd order differential equation
d2 x kx
2
=−
dt m
using rk4 method. Use the initial condition t0 = 0, x0 = 0.5 v0 = 4.0 and also given
m=7.2 and k=150.
Note: One need to write this 2nd order differential equation into two coupled 1st order
differential equation. dx
dt
= v and dv
dt
= kx/m.
#include<iostream>
#include<fstream>
#include<cmath>

using namespace std;


ofstream fout(”rk2.dat”);
double k=150.0, m=7.2, t=0.0, x=0.5, v=4.0, dt=0.01;

double f(double t, double x, double v){


return v;
}
double g(double t, double x, double v){
return -k*x/m;
}
void rk4(double h, double t0, double x0, double v0){
double k1=h*f(t0,x0,v0);
double l1=h*g(t0,x0,v0);
double k2=h*f(t0+(h/2.0), x0+(k1/2.0),v0+(l1/2.0));
double l2=h*g(t0+(h/2.0), x0+(k1/2.0),v0+(l1/2.0));
double k3=h*f(t0+(h/2.0),x0+(k2/2.0),v0+(l2/2.0));
double l3=h*g(t0+(h/2.0),x0+(k2/2.0),v0+(l2/2.0));

12
double k4=h*f(t0+h,x0+k3,v0+l3);
double l4=h*g(t0+h,x0+k3,v0+l3);
t=t0+h;

x= x0+(k1+2*k2+2*k3+k4)/6.0;
v= v0+(l1+2*l2+2*l3+l4)/6.0;
fout<<t<<” ”<<x<<” ”<<v<<endl;
}
int main(){
fout<<t<<” ”<<x<<” ”<<v<<endl;
while(t¡5){
rk4(dt,t,x,v);
}
return 0;
}

Results:
The time vs displacement and time vs velcity graph,

Figure 7: Time vs displacement(small amplitude), and time vs velocity(big amplitude) graph.

The phase digram is shown below

13
Figure 8: displacement vs velocity. The circular shape of the graph ensure the energy conser-
vation during the SHM

Verlet Algorithm
In this section, the Störmer-Verlet method is presented, with some of its interesting prop-
erties, in the special case of a second order ODE of the form q̈ = F (q), where the right-hand
side does not depend on q. This equation is common in physics.
history: Verlet integration is a numerical method used to integrate Newton’s equations of
motion. It is frequently used to calculate trajectories of particles in molecular dynamics sim-
ulations and video games. The verlet integrator offers greater stability than the much simpler
Euler method, as well as other properties that are important in physical systems such as time-
reversibility and area preserving properties. At first it may seem natural to simply calculate
trajectories using Euler integration. However, this kind of integration suffers from many prob-
lems, as discussed at Euler integration. Stability of the technique depends fairly heavily upon
either a uniform update rate, or the ability to accurately identify positions at a small time delta
into the past. Verlet integration was used by Carl Störmer to compute the trajectories of parti-
cles moving in a magnetic field (hence it is also called Störmer’s method) and was popularized
in molecular dynamics by French physicist Loup Verlet in 1967.
Consider the Taylor expansion of q(t + h),

dq(t) 1 d2 q(t) 2 1 d3 q(t) 3


q(t + h) = q(t) + h+ h + h + O(h4 )
dt 2 dt2 3! dt3
and
dq(t) 1 d2 q(t) 2 1 d3 q(t) 3
q(t − h) = q(t) − h+ h − h + O(h4 )
dt 2 dt2 3! dt3
After adding together we have,

d2 q(t) 2
q(t + h) = 2q(t) − q(t − h) + h + O(h4 )
dt2
So we can write q(t + h) − 2q(t) + q(t − h) = h2 F (qn ) It is a two-step method since qn+1 is
computed using qn and qn−1 . This formulation is not very interesting.

14
Figure 9: Störmer-Verlet method. Left: two-step formulation. Right: one-step formulation.

We know that we can transform a second order ODE into a first order system of differential
equations of dimension 2, in order to do so, we introduce the unknown function v = q̇ and the
system becomes v = q̇, v̇ = F (q).
In physics often this type of system is closely related to the motion of a physical body. In
this sense, we can see v as the velocity, q as the displacement (as functions of the time) and F
describes some kind of force acting on the physical body. From the central difference method
we can write
qn+1 − qn−1
vn =
2h
• Position at time t + δt require postion of two more previous steps namely at t and t = δt

• A two steps method, not self-starting.

• It is very simple and stable.

• Global error is of the O(δt2 )

Velocity Verlet Algorithm: Improved accuracy compared to standard Verlet Start with
position and velocity expansions:
1
q(t + h) = q(t) + v(t)h + a(t)h2 + .....
2
and
1
v(t + h) = v(t) + [a(t) + a(t + h) + ...
2
In each integration cycle:

• Calculate velocity at mid-point


δt 1
v(t + ) = v(t) + a(t)δt
2 2

• Calculate position at the next step


δt
q(t + δt) = q(t) + v(t + )δt
2
δt
q(t + δt) = q(t) + [v(t) + a(t)]δt
2
15
Now from the orginal forced equation a(t) = F (q(t)), So,

δt
q(t + δt) = q(t) + [v(t) + F (q(t))]δt
2
Which can be write as
h
qn+1 = qn + h[vn + F (qn )]
2
• Update velocity
δt δt
v(t + δt) = v(t + ) + a(t + δt)
2 2
Which can be write as
h h
vn+1 = vn + F (qn ) + F (qn+1 )
2 2
Example-1: Solve the differential equation of SHM by using Verlet algorithm:

# include<iostream>
# include<cmath>
# include<fstream>
using namespace std;
ofstream fout (”verlet.dat”);
double k=150.0,m=7.2,t=0.0,x=0.5,v=4.0,h=0.01;
double fn1(double t,double x,double v) {
double F=(-k*x)/m;
return F; }
double fn2(double t,double x,double v)
{ return v; }
void verlet(double h,double t0,double x0,double v0) {
for(double t=t0;t<10;t+=h)
{
double xold=x;
cout<<t<<” ”<<x<<” ”<<v<<endl;
fout<<t<<” ”<<x<<” ”<<v<<endl;
x+=h*v+((h*h)/2.0)*fn1(t,x,v);
v+=(h/2.0)*(fn1(t,xold,v)+fn1(t,x,v));
}
}
int main() {
verlet(h,t,x,v);
return 0; }

Example-2 Verlet method to solve dampled harmonic motion:

# include<iostream>
# include<cmath>
# include<fstream>
using namespace std;
double verlet(double m,double gamma,double k,double t) {
double h=0.01,x=2,v=0;

16
for(double i=0;i<=t; i+=h)
{
double xold=x;
x+=h*v+((h*h)/2.0)*((k*x+gamma*v)*h)/m;
v-=(h/(2*m))*((k*xold+gamma*v)+(k*x+gamma*v));
}
return x;
}
int main()
{
ofstream fout (”damp-verlet.dat”);
double dt=0.1;
for(double t=0; t<=50;t+=dt)
{
cout <<t<<” ”<< verlet(1,sqrt(0.5),2,t) <<” ”<< verlet(1,sqrt(8),2,t) <<” ”<< verlet(1,sqrt(18),2,t)
fout <<t<<” ”<< verlet(1,sqrt(0.05),2,t) <<” ”<< verlet(1,sqrt(8),2,t) <<” ”<< verlet(1,sqrt(18),2,t
endl;
}
return 0;
}

17

You might also like