program main(input, output); const EdgeTemp = 100.0; DiffNormal = 0.99; DiffImpure = 0.9; CoolGuess = 0.8; MaxSize = 50; var x,y: integer; (* size of sheet *) xx,yy: integer; (* query point *) tolerance: real; (* tolerance for steady state *) sheet,coeff: array[1..MaxSize,1..MaxSize] of real; (* sheet and diffusion coefficient *) (* Initializes specifications of sheet *) procedure readSheet ; var i,j,x1,y1: integer; begin readln(x, y); (* read size of metal sheet *) readln(xx, yy); (* point to measure temperature *) if (xx < 1) or (xx > x) or (yy < 1) or (yy > y) then begin writeln('Illegal location for query'); exit; end; readln(tolerance); (* tolerance for steady state *) (* initialize diffusion coefficient *) for i:=1 to x do begin for j:=1 to y do begin coeff[i,j] := DiffNormal end end; (* read location of impurities *) readln(x1, y1); while (x1 > 0) do begin if (x1 < 1) or (x1 > x) or (y1 < 1) or (y1 > y) then begin writeln('Illegal location for impurity'); exit end else begin coeff[x1,y1] := DiffImpure end; readln(x1, y1); end; end; (* Initializes temperature of sheet *) procedure initSheet ; var i,j,k: integer; t : real; begin (* simple initialization *) (* for i:=1 to x do begin for j:=1 to y do begin sheet[i,j] := EdgeTemp end end; *) (* heat edges *) for i:=1 to x do begin sheet[i,1] := EdgeTemp; sheet[i,y] := EdgeTemp end; for j:=1 to y do begin sheet[1,j] := EdgeTemp; sheet[x,j] := EdgeTemp end; (* initialize inner portion of sheet *) (* estimate sheet cools away from edges *) t := EdgeTemp * CoolGuess; for k:=1 to x div 2 do begin for i:=1+k to x-k do begin sheet[i,1+k] := t; sheet[i,y-k] := t; end; t := t * CoolGuess end; t := EdgeTemp * CoolGuess; for k:=1 to y div 2 do begin for j:=1+k to y-k do begin sheet[1+k,j] := t; sheet[x-k,j] := t; end; t := t * CoolGuess end; end; (* Simulate heat diffusion on sheet using Jacobi Iteration *) procedure simulateSheet; var i,j,iter: integer; change, maxChange: real; sbuf: array[1..MaxSize,1..MaxSize] of real; begin iter := 0; maxChange := 1.0; while (maxChange > tolerance) do begin iter := iter + 1; (* flow heat through sheet *) for i:=2 to x-1 do begin for j:=2 to y-1 do begin sbuf[i,j] := (coeff[i-1,j]*sheet[i-1,j] + coeff[i+1,j]*sheet[i+1,j] + coeff[i,j-1]*sheet[i,j-1] + coeff[i,j+1]*sheet[i,j+1]) *0.25 end end; (* update sheet *) maxChange := 0.0; for i:=2 to x-1 do begin for j:=2 to y-1 do begin change := abs(sheet[i,j]-sbuf[i,j]); sheet[i,j] := sbuf[i,j]; if (change > maxChange) then maxChange := change end end; end; (* end while *) writeln(sheet[xx,yy]:3:6); writeln(iter:0); end; (* Simulate heat diffusion on sheet using Gauss-Seidel *) procedure simulateSheet2; var i,j,iter: integer; ns, change, maxChange: real; begin iter := 0; maxChange := 1.0; while (maxChange > tolerance) do begin iter := iter + 1; (* flow heat through sheet *) maxChange := 0.0; for i:=2 to x-1 do begin for j:=2 to y-1 do begin ns := (coeff[i-1,j]*sheet[i-1,j] + coeff[i+1,j]*sheet[i+1,j] + coeff[i,j-1]*sheet[i,j-1] + coeff[i,j+1]*sheet[i,j+1]) *0.25; change := abs(ns - sheet[i,j]); sheet[i,j] := ns; if (change > maxChange) then maxChange := change end end; end; (* end while *) writeln(sheet[xx,yy]:3:6); writeln(iter:0); end; (* body of program *) begin readSheet; initSheet; simulateSheet2; end.