Download as pdf or txt
Download as pdf or txt
You are on page 1of 9

MATH-459 Numerical Methods for Conservation Laws by Prof. Jan S.

Hesthaven

Solution proposal to Project 1:

Finite Volume Methods for Conservation laws


Question 1.1 (a) See Matlab/Octave code attached. (b) Large amount of numerical diusion, shocks are getting
smeared out to a level where they are hard to locate. (c) With the initial data eq. 2, the initial condition is
smooth and the solution remains smooth over the time interval. With initial data eq. 3 the initial condition
is also smooth but two discontinuities arises in the time interval 0 ≤ t ≤ 2 and appears in the solution at
T = 2. Initial condition eq. 4 contains two shocks, one in the midle and one at the periodic boundary, that
remains troughout the time interval 0 ≤ t ≤ 2. (d) See Matlab/Octave code attached. Order of accuracy is
less than 1.
Question 1.2 (a) We have previously seen that when the generalized upwind method for a linear system conser-
vation law resolves and propagate information in a proper up-winded manner yielding less numerical diusion
than other schemes that return monotone solutions over discontinuities, such as the Lax-Friedrich's used in
Question 1.1. However, we are now faced with a nonlinear system where we can not just use the straight
forward generalization of the upwind method. By using the Godunov's method with the Roe's approximate
Riemann solver we are able to estimate the ux at each cell boundary in an up-winded manner even for
nonlinear systems such as the shallow water equations. (b) The Roe's matrix  (ul , ur ) must satisfy the three
conditions stated below
i)Â (ul , ur ) (ul − ur ) = f (ur ) − f (ul )
ii)Â (ul , ur ) is diagonalizable with real eigenvalues
ii)Â (ul , ur ) → f 0 (ū) smoothly as (ul , ur ) → ū.

To derive the matrix, follow the same procedure as presented in the solutionset to exercise set 6, here the
Roe's matrix for the Isothermal ow equation was derived. (c) For each cell boundary we are linearising the
equations and solving a Riemann problem upwind style. We can ensure that the CFL condition is satised by
choosing the time-step k so that |λ| ∆x
k
≤ 1 is satised for all eigenvalues at all cell boundaries. This condition
we can write as
∆x
  ≥ k ∀ i (1)
max ūi− 12 + c̄i− 21 , ūi− 21 − c̄i− 12

√ √ q p √ 
where ūi− 21 = √ and c̄i = g2 hi−1 + hi . (d) See Matlab/Octave code attached. The
h u
i−1 i−1 + h u
i i

hi−1 + hi
initial conditions are presented in gure 1, and the solution at T = 2 to the three dierent sets of initial
conditions are presented in gure 2 using ∆x = 0.02 and in gure 3 using ∆x = 0.01. (e) When applying the
Roe's method and our discretization to initial condition 1, we nd that the largest eigenvalue to arise over
all cell boundaries in the entire solution domain is 1.0984. Simply by checking vi see that by choosing k = h,
thereby violating CFL, the method becomes unstable. Choosing k = 0.9h, which satises the CFL condition
eq. 1, the method solves the equations. Same behavior is seen when experimenting with the other initial
data sets. (f ) See accuracy tests presented in gure 4 for all three datasets. When applying the methods
to a smooth initial condition that remains smooth until T = 2, the order of accuracy is roughly 1. When
applying the methods to initial conditions containing discontinuities, the order of accuracy is less than one.
(g) The two methods of roughly of the same order of accuracy, the error is however separated by a fairly large
constant, as the Roe's method experiences substantially less numerical diusion. To get an error < 2 · 10−2 at
T = 2 when using the Lax-Friedrichs method on initial condition 2, around 400 grid cells are needed. When
using the Roe's method only around 100 grid cells are needed to get the same accuracy.

1
2
h
u
1.5

0.5

−0.5
0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2
x
(a) Initial condition 1

2
h
u
1.5

0.5

−0.5
0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2
x
(b) Initial condition 2

2
h
u
1.5

0.5

−0.5
0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2
x
(c) Initial condition 3

Figure 1: The initial conditions q(x, 0).

2
2 2
h h
u u
1.5 ref 1.5 ref

1 1

0.5 0.5

0 0

−0.5 −0.5
0 0.5 1 1.5 2 0 0.5 1 1.5 2
x x
(a) Lax-Friedrichs and initial data set 1. (b) Roe's method and initial data set 1.

2 2
h h
u u
1.5 ref 1.5 ref

1 1

0.5 0.5

0 0

−0.5 −0.5
0 0.5 1 1.5 2 0 0.5 1 1.5 2
x x
(c) Lax-Friedrichs and initial data set 2. (d) Roe's method and initial data set 2.

2 2
h h
u u
1.5 ref 1.5 ref

1 1

0.5 0.5

0 0

−0.5 −0.5
0 0.5 1 1.5 2 0 0.5 1 1.5 2
x x
(e) Lax-Friedrichs and initial data set 3. (f ) Roe's method and initial data set 3.

Figure 2: Solution at T = 2 using ∆x = 0.02.

3
2 2
h h
u u
1.5 ref 1.5 ref

1 1

0.5 0.5

0 0

−0.5 −0.5
0 0.5 1 1.5 2 0 0.5 1 1.5 2
x x
(a) Lax-Friedrichs and initial data set 1. (b) Roe's method and initial data set 1.

2 2
h h
u u
1.5 ref 1.5 ref

1 1

0.5 0.5

0 0

−0.5 −0.5
0 0.5 1 1.5 2 0 0.5 1 1.5 2
x x
(c) Lax-Friedrichs and initial data set 2. (d) Roe's method and initial data set 2.

2 2
h h
u u
1.5 ref 1.5 ref

1 1

0.5 0.5

0 0

−0.5 −0.5
0 0.5 1 1.5 2 0 0.5 1 1.5 2
x x
(e) Lax-Friedrichs and initial data set 3. (f ) Roe's method and initial data set 3.

Figure 3: Solution at T = 2 using ∆x = 0.01.

4
100
Lax-Friedrichs
Roes-Method
O(dx1)
10−1

Error
10−2

10−3 1
10 102 103
Cells
(a) Lax-Friedrichs: -0.91, Roe's method: -1.01

100
Lax-Friedrichs
Roes-Method
O(dx1)
10−1
Error

10−2

10−3 1
10 102 103
Cells
(b) Lax-Friedrichs: -0.87, Roe's method: -0.93

100
Lax-Friedrichs
Roes-Method
O(dx1)
10−1
Error

10−2

10−3 1
10 102 103
Cells
(c) Lax-Friedrichs: -0.78, Roe's method: -0.83

Figure 4: Accuracy as measured in the 1-norm against a Roe's method solution using 4000 grid cells. The slope of
the best linear t to the error measured when using 100 to 400 grid cells is stated in captions. Initial condition (a)
1 (b) 2 (c) 3.

5
clear all,clc

% In this DEMO script for project 1 we attempt to solve the one dimensional shallow
% water equation. The problem can be formulated as a conservatioin law in the form
% of a system of two coupled nonlinear partial differential equations. The solution
% can be visualized and the accuracy of the used method can be measured.

% Visualize and estimate accuracy


Visualize = 0;
Accuracy = 1;

% Numerical flux functions available


types = {'Lax−Friedrichs','Roes−Method'};

% Physical constants
g = 1;

% Choose initial dataset 1 to 3


data = 3;

% Do magic
if Visualize
view = [ 0 2 −0.5 2];
h = 0.02;
[k,X,nX,T,nT] = Setup(h);

for i = 1:numel(types)

Q = InitialData(data,X,nX,h/2);
F = zeros(2,nX+1);

figure;
plot(X,Q(1,:),'−b',X,Q(2,:)./Q(1,:),'−r');
axis(view);
grid on;
xlabel('x');legend('h','u');
%matlab2tikz([num2str(data),'_Initial.tikz'], 'height', '\figureheight', 'width', '\figurewidth');

for t = 1:nT
% Temporary state
Qt = [Q(:,nX),Q,Q(:,1)];
% CFL ok ?
if CFL(Qt,nX,h,g)<=k
warning('CFL condition not satisfied')
end
% Get flux based on type
F = Flux(F,Qt,nX,g,h/k,types{i});
% Integrate a timestep
Q(:,:) = Qt(:,2:nX+1)−k/h*(F(:,2:nX+1)−F(:,1:nX));
% Generate plot
plot(X,Q(1,:),'−b',X,Q(2,:)./Q(1,:),'−r');
axis(view)
drawnow
end
[Qref,Xref] = GetRef(types,data,g);
Qplot(1,:) = interp1(Xref,Qref(1,:),X);
Qplot(2,:) = interp1(Xref,Qref(2,:),X);
hold on;plot(X,Qplot(1,:),'k',X,Qplot(2,:)./Qplot(1,:),'k');
grid on;
xlabel('x');legend('h','u','ref');
name = [types{i},num2str(data),'_Solution.tikz'];
%matlab2tikz(name, 'height', '\figureheight', 'width', '\figurewidth');
end
end
if Accuracy

% Calculate ref solution


[Qref,Xref] = GetRef(types,data,g);

% Measure accuracy of methods


figure;

6
%h = [0.08,0.04,0.02,0.01,0.005];
n = 10.^(1:0.1:2.6);
h = 2./ceil(n);

error = zeros(numel(h),1);
cells = zeros(numel(h),1);
slope = zeros(numel(types),2);
legen = {'−ob','−or','−k'};
for i = 1:numel(types)
for j = 1:numel(h)
[k,X,nX,T,nT] = Setup(h(j));
Q = InitialData(data,X,nX,h(j)/2);
F = zeros(2,nX+1);
for t = 1:nT
Qt = [Q(:,nX),Q,Q(:,1)];
F = Flux(F,Qt,nX,g,h(j)/k,types{i});
Q(:,:) = Qt(:,2:nX+1)−k/h(j)*(F(:,2:nX+1)−F(:,1:nX));
end
% Measure error
error(j) = norm(interp1(Xref,Qref(1,:),X) − Q(1,:),1)/nX;
cells(j) = nX;
end
% Plot
slope(i,:) = polyfit(log(cells(end−6:end)),log(error(end−6:end)),1);
loglog(cells,error,legen{i});hold on;
end
switch data
case 1
ebar = 10^(0.4)*(1./n).^(1);
loglog(n,ebar,legen{3})
axis([10^1 10^3 10^(−3) 10^(−0)])
lgdstring = 'O(dx1)';
case 2
ebar = 10^(−0.2)*(1./n).^(1);
loglog(n,ebar,legen{3})
axis([10^1 10^3 10^(−3) 10^(−0)])
lgdstring = 'O(dx1)';
case 3
ebar = 10^(0.1)*(1./n).^(1);
loglog(n,ebar,legen{3})
axis([10^1 10^3 10^(−3) 10^(−0)])
lgdstring = 'O(dx1)';
end
xlabel('Cells');ylabel('Error');grid on;
axis([10^1 10^3 10^(−3) 10^(0)])
legend(num2str(types{1}),num2str(types{2}),lgdstring);
slope(:,1)
name = ['data_',num2str(data),'_Acc.tikz'];
matlab2tikz(name,'height', '\figureheight', 'width', '\figurewidth');
end

function Q = InitialData(data,X,nX,dx)

% Initial pressure distribution


switch data
case 1
H = @(x) 1 − 0.1*sin(pi*x);
HU = @(x) zeros(size(x));
case 2
H = @(x) 1 − 0.2*sin(2*pi*x);
HU = @(x) 0.5*ones(size(x));
case 3
H = @(x) (x<1) .* 1.5 + (x>=1) .* 0.5;
HU = @(x) zeros(size(x));
end

% Integrate data
Q = zeros(2,nX);
for i = 1:numel(X)
Q(1,i) = integral(H,X(i)−dx,X(i)+dx,'AbsTol',1e−10)/(dx*2);
Q(2,i) = integral(HU,X(i)−dx,X(i)+dx,'AbsTol',1e−10)/(dx*2);
end

7
end

function [ k,X,nX,T,nT ] = Setup(h)


k = 0.5*h;
X = 0:h:2;
nX = numel(X);
T = 0:k:2;
nT = numel(T)−1;
end

function F = Flux(F,Qt,nX,g,r,type)
switch type
case 'Lax−Friedrichs'
F(:,:) = 0.5*r*( Qt(:,1:nX+1) − Qt(:,2:nX+2) ) + 0.5*( f(Qt(:,1:nX+1),g) + f(Qt(:,2:nX+2),g));
case 'Approximate Rieman A'
for i = 1:nX+1
Ql = Qt(:,i);
Qr = Qt(:,i+1);
rQl = sqrt(Ql);
rQr = sqrt(Qr);
uavg = (Ql(2)/rQl(1)+Qr(2)/rQr(1))/(rQl(1)+rQr(1));
cavg = sqrt(g*(Ql(1)+Qr(1))/2);
L = [uavg−cavg,0;0,uavg+cavg];
R = [1,1;L(1,1),L(2,2)];
Ri = 0.5/cavg*[L(2,2),−1;−L(1,1),1];
L(L>0) = 0;An = R*L*Ri;
F(:,i) = f(Ql,g) + An*(Qr−Ql);
end
case 'Approximate Rieman B'
for i = 1:nX+1
Ql = Qt(:,i);
Qr = Qt(:,i+1);
rQl = sqrt(Ql);
rQr = sqrt(Qr);
uavg = (Ql(2)/rQl(1)+Qr(2)/rQr(1))/(rQl(1)+rQr(1));
cavg = sqrt(g*(Ql(1)+Qr(1))/2);
L = [uavg−cavg,0;0,uavg+cavg];
R = [1,1;L(1,1),L(2,2)];
Ri = 0.5/cavg*[L(2,2),−1;−L(1,1),1];
L(L<0) = 0;Ap = R*L*Ri;
F(:,i) = f(Qr,g) − Ap*(Qr−Ql);
end
case 'Roes−Method'
for i = 1:nX+1
Ql = Qt(:,i);
Qr = Qt(:,i+1);
rQl = sqrt(Ql);
rQr = sqrt(Qr);
uavg = (Ql(2)/rQl(1)+Qr(2)/rQr(1))/(rQl(1)+rQr(1));
cavg = sqrt(g*(Ql(1)+Qr(1))/2);
L = [uavg−cavg,0;0,uavg+cavg];
A = [1,1;L(1,1),L(2,2)] * abs(L) * 0.5/cavg*[L(2,2),−1;−L(1,1),1];
F(:,i) = 0.5*(f(Ql,g)+f(Qr,g)) − 0.5*A*(Qr−Ql);
end
end

function f = f(Q,g)
f = [Q(2,:);Q(2,:).^2./Q(1,:)+0.5*g*Q(1,:).^2];
end

function [ cfl ] = CFL(Q,nX,h,g)


uavg = (Q(2,1:nX+1)./sqrt(Q(1,1:nX+1))+Q(2,2:nX+2)./sqrt(Q(1,2:nX+2)))./(sqrt(Q(1,1:nX+1))+sqrt(Q(1,2:nX+2)));
cavg = sqrt(g*(Q(1,1:nX+1)+Q(1,2:nX+2))./2);
cfl = h/max(max(abs(uavg−cavg)),max(abs(uavg+cavg)));
end

8
function [ Qref,Xref ] = GetRef(types,data,g)

Name = ['Qref_',num2str(data),'.mat'];
if exist(Name, 'file') == 2
load(Name);
else
h = 0.0005;
wstring = 'Computing reference solution';
wh = waitbar(0,wstring);
[k,Xref,nX,T,nT] = Setup(h);
Qref = InitialData(data,Xref,nX,h/2);
F = zeros(2,nX+1);
for t = 1:nT
Qt = [Qref(:,nX),Qref,Qref(:,2)];
F = Flux(F,Qt,nX,g,h/k,types{2});
Qref(:,:) = Qt(:,2:nX+1)−k/h*(F(:,2:nX+1)−F(:,1:nX));
waitbar(t/nT);
end
close(wh);
save(Name,'Qref','Xref');
end

end

You might also like