% Usage: [u2,ts] = animwave(x, u, T, a, lambda, scheme) % % Animate solution of one-way wave equation u_t + a u_x = 0, with % periodic boundary conditions, given initial u(x), using various % finite-difference schemes. % % x = uniformly spaced x-axis values (row array, length N) % u = initial condition u(x) (row array, length N) % T = simulation time % a = velocity (number, *or* row array of length N for inhomogeneous case) % lambda = dt/dx % scheme = time-stepping scheme (optional). % % results: u2 = L2 norm |u| vs. time corresponding to array ts. function [u2,ts] = animwave(x, u, T, a, lambda, scheme) if (nargin < 6) scheme = 'Forward-Time Backward-Space'; end h = plot(x, u); axis([min(x) max(x) -2*max(abs(u)) 2*max(abs(u))]); set(h,'EraseMode', 'xor'); dx = (max(x) - min(x)) / (length(u) - 1); dt = dx * lambda; t = 0; ts = [t]; u2 = [sqrt(u * u' * dx)]; if (strcmp(scheme, 'Crank-Nicolson')) if (length(a) == 1) a = a * ones(size(x)); end % matrix for Crank-Nicolson: A = diag(ones(size(x))) + 0.25 * lambda * (diag(a(1:end-1),1) - diag(a(2:end),-1)); A(1,length(x)) = -0.25 * lambda * a(1); A(length(x),1) = 0.25 * lambda * a(end); end v = u + 0.5 * lambda * a .* ([u(2:end),u(1)] - [u(end),u(1:end-1)]);; % for leap-frog while (t < T) t = t + dt; if (strcmp(scheme, 'Lax-Friedrichs')) u = 0.5 * ((1 - a*lambda) .* [u(2:end),u(1)] + (1 + a*lambda) .* [u(end),u(1:end-1)]); elseif (strcmp(scheme, 'Lax-Wendroff')) u = (1 - (a*lambda).^2) .* u - 0.5 * a*lambda .* ((1 - a*lambda) .* [u(2:end),u(1)] - (1 + a*lambda) .* [u(end),u(1:end-1)]); elseif (strcmp(scheme, 'Leap-Frog')) w = v - lambda * a .* ([u(2:end),u(1)] - [u(end),u(1:end-1)]); v = u; u = w; elseif (strcmp(scheme, 'Crank-Nicolson')) u = (A \ (u - 0.25 * lambda * a .* ([u(2:end),u(1)] - [u(end),u(1:end-1)])).').'; else u = u - a .* lambda .* (u - [u(end),u(1:end-1)]); end set(h, 'XData', x, 'YData', u); drawnow; ts = [ts, t]; u2 = [u2, sqrt(u * u' * dx)]; end uf = u;