function pde3b % pde3b.m 3D non equal h boundary value PDE, iterative solution % u(x,y,z) = x^3 + y^3 +z^3 + 2x^2y + 3xy^2 + 4z^2x + 5y + 6 % du/dx = 3x^2 + 0 + 0 + 4xy + 3y^2 + 4z^2 + 0 + 0 % d^2u/dx^2 = 6x + 0 + 0 + 4y + 0 + 0 + 0 + 0 % du/dy = 0 + 3y^2 + 0 + 2x^2 + 6xy + 0 + 5 + 0 % d^2u/dy^2 = 0 + 6y + 0 + 0 + 6x + 0 + 0 + 0 % du/dz = 0 + 0 +3z^2 + 0 + 0 + 8zx + 0 + 0 % d^2u/dz^2 = 0 + 0 +6z + 0 + 0 + 8x + 0 + 0 % % solve d^2u/dx^2 + d^2u/dy^2 + d^2u/dz^2 = c(x,y,z) % by second order method on cube -1,-1,-1 to 1.2,1,1 % second order numerical difference % d^2u/dx^2 + d^2u/dy^2 + d^2u/dz^2 = % 1/hx^2(u(x-hx,y,z)+u(x+hx,y,z)-2u(x,y,z)) + % 1/hy^2(u(x,y-hy,z)+u(x,y+hy,z)-2u(x,y,z)) % 1/hz^2(u(x,y,z-hz)+u(x,y,z+hz)-2u(x,y,z)) + O(h^2) % = c(x,y,z) = 20x + 10y + 6z % solve for new u(x,y,z) = % ((u(x-hx,y,z)+u(x+hx,y,z))/hx^2 + % (u(x,y-hy,z)+u(x,y+hy,z))/hy^2 + % (u(x,y,z-hz)+u(x,y,z+hz))/hz^2 - c(x,y,z)) / % (2/hx^2 + 2/hy^2 + 2/hz^2) format compact; % prevent blank lines fid = fopen('pde3b_m.out', 'w'); fprintf(fid, 'pde3b.m running \n'); sprintf('generating pde3b_m.out \n') xmin = -1.0; ymin = -1.0; zmin = -1.0; xmax = 1.2; ymax = 1.0; zmax = 1.0; nx = 11; ny = 11; nz = 9; hx = (xmax-xmin)/(nx-1); hy = (ymax-ymin)/(ny-1); hz = (zmax-zmin)/(nz-1); us = zeros(nx, ny, nz); % initialize matrix ut = zeros(nx, ny, nz); diff = 1.0E100; % declare variables then we error = 0.0; % do not need 'global' % avgerror = 0.0; % only used locally, lint complains maxerror = 0.0; iter = 0; fprintf(fid, 'xmin=%g, xmax=%g, nx=%d, hx=%g \n', xmin, xmax, nx, hx); fprintf(fid, 'ymin=%g, ymax=%g, ny=%d, hy=%g \n', ymin, ymax, ny, hy); fprintf(fid, 'zmin=%g, zmax=%g, nz=%d, hz=%g \n', zmin, zmax, nz, hz); init_boundary(); fprintf(fid, '\n initial conditions set \n'); while diff>0.0001 && iter<149 iterate(); check(); avgerror = error/((nx-2).*(ny-2).*(nz-2)); fprintf(fid, 'iter=%4d, diff=%8.4f, error=%9.4f, avg=%8.4f, max=%8.4f\n',... iter, diff, error, avgerror, maxerror); iter = iter+1; if mod(iter,50)==0 printus(); printdiff(); end end printexact() printus() printdiff() fclose(fid); return; function value = u(x,y,z) % solution for boundary and checking value = x.*x.*x + y.*y.*y + z.*z.*z + 2.0.*x.*x.*y + 3.0.*x.*y.*y + ... 4.0.*z.*z.*x + 5.0.*y + 6.0; end % z function term = c(x, y, z) % the term on the right hand side term = 20.0.*x + 10.0.*y + 6.0.*z; end % c function value = u000(i, j, k) % compute new iterated value of us(i,j,k) % the equation is the solution of the difference solution value = ((us(i-1,j,k) + us(i+1,j,k))/(hx*hx) + ... (us(i,j-1,k) + us(i,j+1,k))/(hy*hy) + ... (us(i,j,k-1) + us(i,j,k+1))/(hz*hz) - ... c(xmin+(i-1)*hx,ymin+(j-1)*hy,zmin+(k-1)*hz)) / ... (2.0/(hx*hx) + 2.0/(hy*hy) + 2.0/(hz*hz)); end % u000 function init_boundary() % set boundary on six sides for i=1:nx for j=1:ny us(i,j,1) = u(xmin+(i-1)*hx, ymin+(j-1)*hy, zmin); us(i,j,nz) = u(xmin+(i-1)*hx, ymin+(j-1)*hy, zmax); end end for j=1:ny for k=1:nz us(1,j,k) = u(xmin, ymin+(j-1)*hy, zmin+(k-1)*hz); us(nx,j,k) = u(xmax, ymin+(j-1)*hy, zmin+(k-1)*hz); end end for i=1:nx for k=1:nz us(i,1,k) = u(xmin+(i-1)*hx, ymin, zmin+(k-1)*hz); us(i,ny,k) = u(xmin+(i-1)*hx, ymax, zmin+(k-1)*hz); end end end % init_boundary function iterate() % perform one iteration step including copy diff = 0.0; for i=2:nx-1 for j=2:ny-1 for k=2:nz-1 ut(i,j,k) = u000(i, j, k); diff = diff + abs(ut(i,j,k)-us(i,j,k)); end end end % copy temp to solution for i=2:nx-1 for j=2:ny-1 for k=2:nz-1 us(i,j,k) = ut(i,j,k); end end end end % iterate function check() % compute total error and maximum cell error error = 0.0; maxerror = 0.0; for i=2:nx-1 for j=2:ny-1 for k=2:nz-1 zexact = u(xmin+(i-1)*hx, ymin+(j-1)*hy, zmin+(k-1)*hz); err = abs(us(i,j,k)-zexact); error = error + err; if err>maxerror maxerror = err; end end end end end % check function printus() % print the solution thus far fprintf(fid, '\n computed solution \n'); for k = 2:nz-1 fprintf(fid, 'u(x,y,%d) plane \n', k); for i=2:nx-1 for j=2:ny-1 fprintf(fid, '%7.3f', us(i,j,k)); end fprintf(fid, '\n'); end fprintf(fid, '\n'); end end % printus function printexact() % print exact solution fprintf(fid, '\n exact solution \n'); for k = 1:nz fprintf(fid, 'u(x,y,%d) plane \n', k); for i=1:nx for j=1:ny fprintf(fid, '%7.3f', u(xmin+(i-1)*hx, ymin+(j-1)*hy, zmin+(k-1)*hz)); end fprintf(fid, '\n'); end fprintf(fid, '\n'); end end % printexact function printdiff() % print exact solution minus computed solution fprintf(fid, '\n difference exact-computed solution \n'); for k=2:nz-1 fprintf(fid, 'u(x,y,%d) plane \n', k); for i=2:nx-1 fprintf(fid, ' '); for j=2:ny-1 fprintf(fid, '%7.4f', u(xmin+(i-1)*hx, ymin+(j-1)*hy, ... zmin+(k-1)*hz)-us(i,j,k)); end fprintf(fid, '\n'); end fprintf(fid, '\n'); end end % printdiff end % pde3b.m