Solving the 3D wave equation

This scripts solves the 3D wave equation using the FFT. It also illustrates how to create nice 3D graphics.

Contents

close all;clear;

Create the grid

N=64;
z=linspace(-1,1,N+1);
z=z(1:end-1);
[xx,yy,zz]=meshgrid(z,z,z);

Parameters.

dt=0.001;
L=2;
dk=2*pi/L;

Wavenumbers

ksvec(1)=0;
ksvec(N/2+1)=0;
for ii=2:(N/2)
    ksvec(ii)=ii-1;
    ksvec(N/2+ii)=-N/2 + ii -1;
end
ksvec=ksvec*dk;
[k,l,m]=meshgrid(ksvec,ksvec,ksvec);
k2=k.*k; l2=l.*l; m2=m.*m;

Create the operators

lap=-(k2+l2+m2);
myop=dt*dt*lap;

Create the ICs

r=sqrt(xx.*xx+yy.*yy+4*zz.*zz);
u0 = exp(-((r-.4)/.1).^2);
u=u0;
um1=u0;

Time parameters

numsteps=100; numouts=10; t=0;

Plot ICs

figure(1)
clf
hold on
p=patch(isosurface(xx,yy,zz,u,0.05));
set(p,'FaceColor','blue','EdgeColor','none','facealpha',.3)
daspect([1 1 1])
view(3); camlight, lighting phong
sl = slice(xx,yy,zz,u,0,[],[]);
minc = max(min(u(:)),-1);
maxc = min(max(u(:)),1);
cbot = -abs(max(abs(minc),abs(maxc)));
ctop = -cbot;
caxis([cbot ctop]);
colormap hot;grid on %colorbar
set(sl,'edgecolor','none','facecolor','interp','ambientstrength',1,...
    'diffusestrength',0,'specularstrength',0,'facealpha',0.6);
mystr=['time = ' num2str(t)];
title(mystr);
axis([-1 1 -1 1 -1 1])
drawnow

Main Loop

for ii=1:numouts
    for jj=1:numsteps

Step time.

        t=t+dt;

FFT in y.

        uf=fft(u);

FFT in x.

        uf=fft(uf,[],2);

FFT in z.

        uf=fft(uf,[],3);

Make the laplacian piece.

        uf=myop.*uf;

iFFT in y.

        uf=ifft(uf);

iFFT in x.

        uf=ifft(uf,[],2);

iFFT in z.

        uf=ifft(uf,[],3);

Knock off the small imaginary parts.

        uf=real(uf);

Take a leapfrog step forward.

        up1=-um1+2*u+uf;
        um1=u;
        u=up1;
    end

Step plot

    figure(1)
    clf
    hold on
    p=patch(isosurface(xx,yy,zz,u,0.05));
    set(p,'FaceColor','blue','EdgeColor','none','facealpha',.3)
    daspect([1 1 1])
    view(3); camlight, lighting phong
    sl = slice(xx,yy,zz,u,0,[],[]);
    minc = max(min(u(:)),-1);
    maxc = min(max(u(:)),1);
    cbot = -abs(max(abs(minc),abs(maxc)));
    ctop = -cbot;
    caxis([cbot ctop]);
    colormap hot;grid on %colorbar
    set(sl,'edgecolor','none','facecolor','interp','ambientstrength',1,...
        'diffusestrength',0,'specularstrength',0,'facealpha',0.6);
    mystr=['time = ' num2str(t)];
    title(mystr);
    axis([-1 1 -1 1 -1 1])
    drawnow
end