Lecture 3.5. Things to do in class.

We are testing the error accuracy of the 2D 2nd-order 2nd derivative differentiation matrices. Basically, we are redoing the last page of Lecture 3 with the 2D 2nd derivative differentiation matrices.

Contents

Number 1

clear all; close all; % clear all to start fresh
a = -1; b = 1;
n = 10; h = (b-a)/(n-1);
one = ones(n,1); % create a column vector of size n by 1 of ones
D2 = spdiags([one -2*one one],[-1 0 1],n,n);
D2(1,1:4) = [2 -5 4 -1]; D2(end,end-3:end) = [-1 4 -5 2]; % Modify first and last row (one-sided weights)
D2 = (1/h^2)*D2; % Don't forget the 1/(h^2) factor
spy(D2) % Plot the structure of the sparse matrix
x = linspace(a,b,n).'; % Create n equally-spaced points in [a,b]
y = x; % set y = x
[X,Y] = meshgrid(x,y);
figure
mesh(X,Y,0*X); view(2); % plot the grid
I = speye(n); % Create sparse identity matrix
Dxx = kron(D2,I);
Dyy = kron(I,D2);
figure;
subplot(1,2,1); spy(Dxx);
subplot(1,2,2); spy(Dyy);

Number 2

format long e % format number in long format
u = @(x,y) exp(-(x.^2+0.5*y.^2)); % Define the function
uxx = @(x,y) 2*exp(-(x.^2+0.5*y.^2)).*(2*x.^2 - 1); % Define the exact u_xx of the function
uyy = @(x,y) exp(-(x.^2+0.5*y.^2)).*(y.^2-1); % Define the exact u_yy of the function
U = u(X,Y); % Function values at nodes
Uxx = U*D2.'; % U_x = U*transpose(D)
Uyy = D2*U; % U_y = D*U
norm(Uxx(:)-uxx(X(:),Y(:)),Inf)
norm(Uyy(:)-uyy(X(:),Y(:)),Inf)
figure
subplot(1,2,1); surf(X,Y,Uxx); xlabel('x'); ylabel('y'); zlabel('U_{xx}');
subplot(1,2,2); surf(X,Y,Uyy); xlabel('x'); ylabel('y'); zlabel('U_{yy}');
ans =

     2.378780537064675e-01


ans =

     1.172505202572083e-02

Uxx = Dxx*U(:);
Uyy = Dyy*U(:);
norm(Uxx-uxx(X(:),Y(:)),Inf)
norm(Uyy-uyy(X(:),Y(:)),Inf)
ans =

     2.378780537064675e-01


ans =

     1.172505202572083e-02

Number 3

For 2nd order convergence, the error convergence trend slope must be 2.

n = 30:30:1140; % Create n = 10,110,210,310,...
h = (b-a)./(n-1);
err = zeros(length(n),2); % Pre-allocate memory to store errors
for i=1:length(n)
    one = ones(n(i),1);
    D2 = spdiags([one -2*one one],[-1 0 1],n(i),n(i));
    D2(1,1:4) = [2 -5 4 -1]; D2(end,end-3:end) = [-1 4 -5 2]; % Modify first and last row (one-sided weights)
    D2 = (1/h(i)^2)*D2; % Don't forget the 1/(h^2) factor
    x = linspace(a,b,n(i)).';
    y = x; % set y = x
    [X,Y] = meshgrid(x,y);
    U = u(X,Y); % Function values at nodes
    Uxx = U*D2.'; % U_xx = U*transpose(D2)
    Uyy = D2*U; % U_yy = D2*U
    err(i,1) = norm(Uxx(:)-uxx(X(:),Y(:)),Inf); % Store err of ux in 1st col
    err(i,2) = norm(Uyy(:)-uyy(X(:),Y(:)),Inf); % Store err of uy in 2nd col
end
figure
loglog(h,err(:,1),'-o',h,err(:,2),'-*r') % Plot the errors in logscale
xlabel('h'); ylabel('Error')

Additional Problem

Can you redo problem (1)-(3) for the case of mixed derivatives Uxy and/or Uyx ?