% sample code of 3D fast Poisson solver (c.f. POICALC)
% written by Weiguo Gao (wggao@fudan.edu.cn)
% number of grids on each direction
% nz is supposed to be the largest
nx=300; ny=300; nz=300;
% step length
hx=2.*pi/(nx+1); hy=2.*pi/(ny+1); hz=2.*pi/(nz+1);
% square of step length
hx2=hx*hx; hy2=hy*hy; hz2=hz*hz;
% example from Edouard Oudet, University of Savoie
x=zeros(nx,ny,nz);
for k=1:nz
% right hand side: f(x,y,z)=sin(2*x)*cos(z)
x(:,:,k)=sin(2.*(1:nx)'*hx)*cos(k*hz)*ones(1,ny);
end
% boundary condition: u(x,y,z)=sin(2*x)*cos(z)/5
for k=1:nz, for i=1:nx
x(i,1,k)=x(i,1,k)+sin(2.*i*hx)*cos(k*hz)/(5.*hy2);
x(i,ny,k)=x(i,ny,k)+sin(2.*i*hx)*cos(k*hz)/(5.*hy2);
end, end
x(:,:,1)=x(:,:,1)+sin(2.*(1:nx)'*hx)/(5.*hz2)*ones(1,ny);
x(:,:,nz)=x(:,:,nz)+sin(2.*(1:nx)'*hx)/(5.*hz2)*ones(1,ny);
dx=(4./hx2)*sin(pi/(2*nx+2.)*[1:nx]).^2;
dy=(4./hy2)*sin(pi/(2*ny+2.)*[1:ny]).^2;
i=[1:nz 2:nz 1:nz-1]'; j=[1:nz 1:nz-1 2:nz]';
trid=sparse(i,j,-ones(3*nz-2,1)/hz2);
fprintf('3D fast Poisson solver (Fourier) ... \t');
v=x;
t1=cputime();
for k=1:nz, v(:,:,k)=idst(v(:,:,k)); end
for k=1:nz, v(:,:,k)=idst(v(:,:,k)')'; end
for j=1:ny, for i=1:nx
trid(1:nz+1:nz*nz)=dx(i)+dy(j)+2./hz2;
v(i,j,:)=trid\reshape(v(i,j,:),nz,1);
end, end
for k=1:nz, v(:,:,k)=dst(v(:,:,k)')'; end
for k=1:nz, v(:,:,k)=dst(v(:,:,k)); end
fprintf('%f(s)\n',cputime()-t1);
clear i j k t1 dx dy trid