Prog 4
Prog 4
Programming Assignment 4
due Tues, Nov 27
Our goal is to solve a stiff, nonlinear system of differential equations using a 4th
order diagonally implicit Runge-Kutta method. The first step is to write a multi-
dimensional Newton solver. The generalization from the scalar case is quite simple:
f (xn ) ∂fi
xn+1 = xn − 0 becomes xn+1 = xn − J(xn )−1 f (xn ), Jij = .
f (xn ) ∂xj
Here is a simple implementation that will be good enough for our purposes:
function p = newton(f,J,p0,tol)
for i=1:50
p = p0 - J(p0)\f(p0);
if norm(p-p0)<tol, break; end
p0=p;
end
The backslash operator A\b gives the solution x of Ax = b. The function norm gives
the 2-norm of a vector.
Part 1. Start by testing
the
PNewton
solver on the 4 dimensional nonlinear system
4
of equations xi = exp cos i j=1 xj , i = 1, 2, 3, 4. Write this system in the form
f (x) = 0 by defining
f = @(x) x - exp(cos([1:4]’*sum(x))); # x is a 4-component column vector
Then define the Jacobian of f by creating a file called JJ.m with the following lines
of code:
function J = JJ(x)
J = eye(4); % 4x4 identity matrix
u = sum(x);
for i=1:4
for j=1:4
J(i,j) = J(i,j) + ???; % replace ??? appropriately
end
end
Finally, solve the system of equations using Newton’s method:
p1 = newton(f,@JJ,[2.5;2;1.4;.9],1.0e-12);
P4
The starting
P4 guess was found by plotting g(u) = u − i=1 exp(cos(iu)), where
u = x
i=1 i , observing that u = 6.7 is an approximate root of g, defining xi =
exp(cos(6.7i)), and rounding to two digits, which gave x = [2.5; 2.0; 1.4; 0.9]. (This
problem could have been done by solving g(u) = 0 using the scalar version of Newton’s
method, but the point is to test the multi-dimensional code for use below.)
Part 2. Next, consider the following stiff system of ODE’s:
y10 = −0.04y1 + y2 y3 ,
1
y20 = 400y1 − 10000y2 y3 − 3000y22 , y(0) = 0 ,
0 ≤ t ≤ 3.
y30 = 0.3y22 , 0
We will solve this using both the Runge-Kutta-Fehlberg method and a 4th order
L-stable singly diagonally implicit Runge-Kutta method. The code could be run as
follows:
f = @(y) [ -.04*y(1) + y(2)*y(3); 400*y(1) - 1e4*y(2)*y(3) - 3000*y(2)^2; .3*y(2)^2 ];
J = @(y) [ ?, ?, ?; ?, ?, ?; ?, ?, ?]; % you fill in the question marks
The file rkf.m has been provided for you on bCourses. Make a duplicate copy of this
file called sdirk.m. Change the first line to
Make sure bb and b1 are stored as column vectors. (Don’t delete the ’ in bb = [...]’;)
These coefficients define the Runge-Kutta scheme via
i
!
X
ki = f w n + h aij kj , i = 1, . . . , s
j=1
s
X s
X
wn+1 = wn + h bj kj , w̃n+1 = wn + h b̃j kj ,
j=1 j=1
where s = 5 in this case and s = 6 in the RKF scheme. As discussed in section 5.5
of our book, w̃n+1 is an alternative estimate of the solution which is used together
with wn+1 to choose the next step size. The main difference between RKF and this
SDIRK scheme is that the diagonal entries of A are not zero in the SDIRK scheme.
This means that the ki equations are of the form
ki = f (z + haii ki ) ,
where z = wn + h i−1
P
j=1 aij kj is known and aii = 1/4 for this scheme. Thus, if we
define g(k) = k − f (z + haii k), we can use Newton’s method to solve for k. As a
starting guess, f (wn ) works well. So, replace the following line in rkf.m
kk(:,i) = f(z);
with
ah = h*A(i,i);
g = @(k) ???; % you figure out what goes here (involves f)
dg = @(k) ???; % and here.. (involves J)
kk(:,i) = newton(g,dg,f(y0),1.0e-12);
in sdirk.m. The stepsize control works the same for SDIRK as it does for RKF, so
the rest of the code should not be modified. Plots of the results are as follows:
1 1
0.9 0.9
0.8 0.8
0.7 0.7
0.6 0.6
0.5 0.5
0.4 0.4
0.3 0.3
0.2 0.2
0.1 0.1
0 0
0 0.5 1 1.5 2 2.5 3 0 0.5 1 1.5 2 2.5 3
RKF SDIRK
The RKF scheme requires 2185 steps while the SDIRK scheme requires only 84 steps.
Thus, the extra cost of solving the equations implicitly pays off through a drastic
reduction in the number of timesteps required to achieve the same accuracy.
Your write-up should include your result p1 from part 1 (with each number re-
ported with 14-16 digits of precision), your version of the above plots, and derivations
of the missing formulas in JJ.m, J, g, and dg. For the codes, upload JJ.m, sdirk.m
and the driver file prog4.m that you wrote to call these routines.