> restart: > Digits := 20: > # POISSON EQUATION FINITE-DIFFERENCE ALGORITHM 12.1 > # > # To approximate the solution to the Poisson equation > # DEL(u) = F(x,y), a <= x <= b, c <= y <= d, > # SUBJECT TO BOUNDARY CONDITIONS: > # u(x,y) = G(x,y), > # if x = a or x = b for c <= y <= d, > # if y = c or y = d for a <= x <= b > # > # INPUT: endpoints a, b, c, d: integers m, n: tolerance TOL: > # maximum number of iterations M > # > # OUTPUT: approximations W(I,J) to u(X(I),Y(J)) for each > # I = 1,..., n-1 and J=1,..., m-1 or a message that the > # maximum number of iterations was exceeded. > print(`This is the Finite-Difference Method for Elliptic Equations.`): > print(`Input the functions F(X,Y) and G(X,Y) in terms of x and y > separated by a space`): > print(`For example: x*exp(y) x*exp(y)`): > F := scanf(`%a`)[1]: > G := scanf(`%a`)[1]:print(`F(x,y) = `):print(F):print(`G(x,y) = `):print(G): > F := unapply(F,x,y): > G := unapply(G,x,y): > OK :=FALSE: > while OK = FALSE do > print(`Input endpoints of interval [A,B] on X-axis`): > print(`separated by a blank.`): > A := scanf(`%f`)[1]: > B := scanf(`%f`)[1]:print(`A = `):print(A):print(`B = `):print(B): > print(`Input endpoints of interval [C,D] on Y-axis`): > print(`separated by a blank.`): > C := scanf(`%f`)[1]: > D2 := scanf(`%f`)[1]:print(`C = `):print(C):print(`D = `):print(D2): > if A >= B or C >= D2 then > print(`Left endpoint must be less than right endpoint.\n`): > else > OK := TRUE: > fi: > od: > OK := FALSE: > while OK = FALSE do > print(`Input number of intervals n on the X-axis and m`): > print(`on the Y-axis separated by a blank`): > print(`Note that both n and m should be larger than 2.`): > N := scanf(`%d`)[1]:print(`Number on x-axis N = `):print(N): > M := scanf(`%d`)[1]:print(`Number on y-axis M = `):print(M): > if M <= 2 or N <= 2 > then print(`Numbers must exceed 2.`): > else > OK := TRUE: > fi: > od: > OK := FALSE: > while OK = FALSE do > print(`Input the Tolerance.`): > TOL := scanf(`%f`)[1]: print(`Tolerance = `):print(TOL): > if TOL <= 0 then > print(`Tolerance must be positive.`): > else > OK := TRUE: > fi: > od: > OK := FALSE: > while OK = FALSE do > print(`Input the maximum number of iterations.`): > NN := scanf(`%d`)[1]:print(`Maximum number of iterations = `):print(NN): > if NN <= 0 then > print (`Number must be a positive integer.`): > else > OK := TRUE: > fi: > od: > if OK = TRUE then > M1 := M-1: > M2 := M-2: > N1 := N-1: > N2 := N-2: > # Step 1 > H := (B-A)/N: > K := (D2-C)/M: > # Steps 2 and 3 construct mesh points > # Step 2 > for I2 from 0 to N do > X[I2] := A+I2*H: > od: > # Step 3 > for J from 0 to M do > Y[J] := C+J*K: > od: > # Step 4 > for I2 from 1 to N1 do > W[I2,0] := G(X[I2],Y[0]): > W[I2,M] := G(X[I2],Y[M]): > od: > for J from 0 to M do > W[0,J] := G(X[0],Y[J]): > W[N,J] := G(X[N],Y[J]): > od: > for I2 from 1 to N1 do > for J from 1 to M1 do > W[I2,J] := 0: > od: > od: > # Step 5 > # Use V in place of lambda, VV in place of mu > V := H*H/(K*K): > VV := 2*(1+V): > L := 1: > OK := FALSE: > # Z is a new value of W(I,J) to be used in computing the norm of the > # error E > # Step 6 > while L <= NN and OK = FALSE do > # Steps 7 - 20 perform Gauss-Seidel iterations > # Step 7 > Z := (-H*H*F(X[1],Y[M1])+G(A,Y[M1])+V*G(X[1],D2)+V*W[1,M2]+W[2,M1])/VV: > E := abs( W[1,M1]-Z): > W[1,M1] := Z: > # Step 8 > for I2 from 2 to N2 do > Z := (-H*H*F(X[I2],Y[M1])+V*G(X[I2],D2)+W[I2-1,M1]+W[I2+1,M1]+V*W[I2,M2])/VV: > if abs(W[I2,M1]-Z) > E then > E := abs( W[I2,M1] - Z ): > fi: > W[I2,M1] := Z: > od: > # Step 9 > Z := > (-H*H*F(X[N1],Y[M1])+G(B,Y[M1])+V*G(X[N1],D2)+W[N2,M1]+V*W[N1,M2])/VV: > if abs( W[N1,M1]-Z) > E then > E := abs( W[N1,M1]-Z): > fi: > W[N1,M1] := Z: > # Step 10 > for LL from 2 to M2 do > J := M2-LL+2: > # Step 11 > Z := (-H*H*F(X[1],Y[J])+G(A,Y[J])+V*W[1,J+1]+V*W[1,J-1]+W[2,J])/VV: > if abs(W[1,J]-Z) > E then > E := abs(W[1,J]-Z): > fi: > W[1,J] := Z: > # Step 12 > for I2 from 2 to N2 do > Z := (-H*H*F(X[I2],Y[J])+W[I2-1,J]+V*W[I2,J+1]+V*W[I2,J-1]+W[I2+1,J])/VV: > if abs(W[I2,J]-Z) > E then > E := abs(W[I2,J]-Z): > fi: > W[I2,J] := Z: > od: > # Step 13 > Z := (-H*H*F(X[N1],Y[J])+G(B,Y[J])+W[N2,J]+V*W[N1,J+1]+V*W[N1,J-1])/VV: > if abs(W[N1,J]-Z) > E then > E := abs(W[N1,J]-Z): > fi: > W[N1,J] := Z: > od: > # Step 14 > Z := (-H*H*F(X[1],Y[1])+V*G(X[1], C)+G(A,Y[1])+V*W[1,2]+W[2,1])/VV: > if abs(W[1,1]-Z) > E then > E := abs(W[1,1]-Z): > fi: > W[1,1] := Z: > # Step 15 > for I2 from 2 to N2 do > Z := (-H*H*F(X[I2],Y[1])+V*G(X[I2],C)+W[I2+1,1]+W[I2-1,1]+V*W[I2,2])/VV: > if abs(W[I2,1]-Z) > E then > E := abs(W[I2,1]-Z): > fi: > W[I2,1] := Z: > od: > # Step 16 > Z := (-H*H*F(X[N1],Y[1])+V*G(X[N1],C)+G(B,Y[1])+W[N2,1]+V*W[N1,2])/VV: > if abs(W[N1,1]-Z) > E then > E := abs(W[N1,1]-Z): > fi: > W[N1,1] := Z: > # Step 17 > if E <= TOL then > # Step 18 > print(`Choice of output method:\n`): > print(`1. Output to screen\n`): > print(`2. Output to text file\n`): > print(`Please enter 1 or 2.\n`): > FLAG := scanf(`%d`)[1]: print(`Input is `):print(FLAG): > if FLAG = 2 then > print(`Input the file name in the form - drive:\\name.ext`): > print(`for example: A:\\OUTPUT.DTA`): > NAME := scanf(`%s`)[1]: print(`Output file is `):print(NAME): > OUP := fopen(NAME,WRITE,TEXT): > else > OUP := default: > fi: > fprintf(OUP, `POISSON EQUATION FINITE-DIFFERENCE METHOD\n\n`): > fprintf(OUP, ` I J X(I) Y(J) W(I,J)\n\n`): > for I2 from 1 to N1 do > for J from 1 to M1 do > fprintf(OUP, `%3d %2d %11.8f %11.8f %13.8f\n`, I2, J, X[I2], Y[J], W[I2,J]): > od: > od: > fprintf(OUP, `Convergence occurred on iteration number: %d\n`, L): > # Step 19 > OK := TRUE: > else > # Step 20 > L := L+1: > fi: > od: > # Step 21 > if L > NN then > print(`Method fails after iteration number `):print(NN): > else > if OUP <> default then > fclose(OUP): > print(`Output file `,NAME,` created successfully`): > fi: > fi: > fi: