function pde3 % just checking second order approximation % z(x,y) = x^3 + y^3 + 2x^2y + 3xy^2 + 4x + 5y + 6 % dz/dx = 3x^2 + 0 + 4xy + 3y^2 + 4 + 0 + 0 % d^2z/dx^2 = 6x + 0 + 4y + 0 + 0 + 0 + 0 % dz/dy = 0 + 3y^2 + 2x^2 + 6xy + 0 + 5 + 0 % d^2z/dy^2 = 0 + 6y + 0 + 6x + 0 + 0 + 0 % % solve d^2z/dx^2 + d^2z/dy^2 = 12x + 10y = c(x,y) % by second order method on square -1,-1 to 1,1 % second order numerical difference % d^2z/dx^2 + d^2z/dy^2 = % 1/h^2(z(x-h,y)-2z(x,y)+z(x+h,y))+ % 1/h^2(z(x,y-h)-2z(x,y)+z(x,y+h)) + O(h^2) % = c(x,y) % solve for new z(x,y) = % (z(x-h,y)+z(x+h,y)+z(x,y-h)+z(x,y+h)-c(x,y)*h^2)/4 format compact; % prevent blank lines fid = fopen('pde3_m.out', 'w'); fprintf(fid, 'pde3.m running \n'); sprintf('generating pde3_m.out \n') xmin = -1.0; xmax = 1.0; ymin = -1.0; ymax = 1.0; nx = 11; ny = 11; h = (xmax-xmin)/(nx-1); % also = (ymax-ymin)/(ny-1) zs = zeros(nx, ny); % initialize matrix zt = zeros(nx, ny); 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, h=%g \n', xmin, xmax, nx, h); fprintf(fid, 'ymin=%g, ymax=%g, ny=%d, h=%g \n', ymin, ymax, ny, h); printexact(); init_boundary(); fprintf(fid, '\n initial condition \n'); printzs(); while diff>0.0001 && iter<200 iterate(); check(); avgerror = error/((nx-2).*(ny-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 printzs(); printdiff(); end end fclose(fid); return; function val = z(x,y) % solution for boundary and checking val = x.*x.*x + y.*y.*y + + 2.0.*x.*x.*y + 3.0.*x.*y.*y + 4.0.*x + 5.0.*y + 6.0; end % z function term = c(x, y) % the term on the right hand side term = 12.0.*x + 10.0.*y; end % c function value = z00(i, j) % compute new iterated value of zs(i,j) % the equation is the solution of the difference solution value = zs(i-1,j) + zs(i+1,j) + zs(i,j-1) + zs(i,j+1); value = (value - c(xmin+(i-1)*h, ymin+(j-1)*h).*h.*h)/4.0; end % z00 function init_boundary() % initialize the boundary cells in zs(i,j) for i=1:nx zs(i,1) = z(xmin+(i-1)*h, ymin); zs(i,ny) = z(xmin+(i-1)*h, ymax); end for j=1:ny zs(1,j) = z(xmin, ymin+(j-1)*h); zs(nx,j) = z(xmax, ymin+(j-1)*h); 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 zt(i,j) = z00(i, j); diff = diff + abs(zt(i,j)-zs(i,j)); end end % copy temp to solution for i=2:nx-1 for j=2:ny-1 zs(i,j) = zt(i,j); 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 zexact = z(xmin+(i-1)*h, ymin+(j-1)*h); err = abs(zs(i,j)-zexact); error = error + err; if err>maxerror maxerror = err; end end end end % check function printzs() % print the solution thus far fprintf(fid, '\n computed solution \n'); for i=1:nx for j=1:ny fprintf(fid, '%7.3f', zs(i,j)); end fprintf(fid, '\n'); end fprintf(fid, '\n'); end % printzs function printexact() % print exact solution fprintf(fid, '\n exact solution \n'); for i=1:nx for j=1:ny fprintf(fid, '%7.3f', z(xmin+(i-1)*h, ymin+(j-1)*h)); end fprintf(fid, '\n'); end fprintf(fid, '\n'); end % printexact function printdiff() % print exact solution minus computed solution fprintf(fid, '\n difference exact-computed solution \n'); for i=2:nx-1 fprintf(fid, ' '); for j=2:ny-1 fprintf(fid, '%7.4f', z(xmin+(i-1)*h, ymin+(j-1)*h)-zs(i,j)); end fprintf(fid, '\n'); end fprintf(fid, '\n'); end % printdiff end % pde3.m