code 33170; procedure RICHARDSON(U,LJ,UJ,LL,UL,INAP,RESIDUAL,A,B,N,DISCR,K, RATECONV,DOMEIGVAL,OUT); value LJ,UJ,LL,UL,A,B; integer N,K,LJ,UJ,LL,UL; real A,B,RATECONV,DOMEIGVAL; boolean INAP; array U,DISCR; procedure RESIDUAL,OUT; begin integer J,L; real X,Y,Z,Y0,C,D,ALFA,OMEGA,OMEGA0, EIGMAX,EIGEUCL,EUCLRES,MAXRES,RCMAX,RCEUCL,MAXRES0,EUCLRES0; array V,RES[LJ:UJ,LL:UL]; procedure CALPAR; comment CALPAR CALCULATES THE PARAMETERS ALFA AND OMEGA FOR EACH ITERATION; begin ALFA:= Z/(Z - ALFA); OMEGA:= 1/(X - OMEGA * Y) end CALPAR; procedure ITERATION; comment FIRST THE ITERATION FORMULA IS CONSTRUCTED; begin real AUXV,AUXU,AUXRES,EUCLUV,MAXUV; EUCLUV:= EUCLRES:= MAXUV:= MAXRES:= 0; for J:= LJ step 1 until UJ do for L:= LL step 1 until UL do RES[J,L]:= V[J,L]; RESIDUAL(RES); for J:= LJ step 1 until UJ do for L:= LL step 1 until UL do begin AUXV:= U[J,L]; AUXU:= V[J,L]; AUXRES:= RES[J,L]; AUXV:= ALFA * AUXU - OMEGA * AUXRES + (1 - ALFA) * AUXV; V[J,L]:= AUXV; U[J,L]:= AUXU; comment THE NORMS OF THE K-TH RESIDUAL AND THE DIFFERENCE BETWEEN THE (K+1)-TH AND K-TH ITERAND ARE CALCULATED; AUXU:= ABS(AUXU - AUXV); AUXRES:= ABS(AUXRES); MAXUV:= if MAXUV < AUXU then AUXU else MAXUV; MAXRES:= if MAXRES < AUXRES then AUXRES else MAXRES; EUCLUV:= EUCLUV + AUXU * AUXU; EUCLRES:= EUCLRES + AUXRES * AUXRES; end; EUCLUV:= SQRT(EUCLUV); EUCLRES:= SQRT(EUCLRES); DISCR[1]:= EUCLRES; DISCR[2]:= MAXRES; comment DOMEIGVAL IS EVALUATED; MAXUV:= MAXRES/MAXUV; EUCLUV:= EUCLRES/EUCLUV; EIGMAX:= MAXUV * (C - MAXUV)/(.25 * D - MAXUV); EIGEUCL:= EUCLUV * (C - EUCLUV)/(.25 * D - EUCLUV); DOMEIGVAL:= .5 * (EIGMAX + EIGEUCL); comment FINALLY THE RATE OF CONVERGENCE IS CALCULATED; RCEUCL:= -LN(EUCLRES/EUCLRES0)/K; RCMAX:= -LN(MAXRES/MAXRES0)/K; RATECONV:= .5 * (RCEUCL + RCMAX) comment THE CONSTANTS FOR STARTING CALPAR ARE CALCULATED; ALFA:= 2; OMEGA:= 4/(B + A); Y0:= (B + A)/(B - A); X:= .5 * (B + A); Y:= (B - A) * (B - A)/16; Z:= 4 * Y0 * Y0; comment THE CONSTANTS NEEDED FOR DOMEIGVAL ARE CALCULATED; C:= A * B; C:= SQRT(C); D:= SQRT(A) + SQRT(B); D:= D * D; comment THE INITIAL APPROXIMATION IS PUT INTO ARRAY U; if ^INAP then begin for J:= LJ step 1 until UJ do for L:= LL step 1 until UL do U[J,L]:= 1 end; comment THE ZEROTH ITERATION IS NOW PERFORMED; K:= 0; for J:= LJ step 1 until UJ do for L:= LL step 1 until UL do RES[J,L]:= U[J,L]; RESIDUAL(RES); OMEGA0:= 2/(B+A); begin real AUXRES0; MAXRES0:= EUCLRES0:= 0; for J:= LJ step 1 until UJ do for L:= LL step 1 until UL do begin AUXRES0:= RES[J,L]; V[J,L]:= U[J,L] - OMEGA0 * AUXRES0; AUXRES0:= ABS(AUXRES0); MAXRES0:= if MAXRES0 < AUXRES0 then AUXRES0 else MAXRES0; EUCLRES0:= EUCLRES0 + AUXRES0 * AUXRES0 end; EUCLRES0:= SQRT(EUCLRES0) end; DISCR[1]:= EUCLRES0; DISCR[2]:= MAXRES0; OUT(K); if K >= N then goto FINALLY; NEXT STEP: K:= K + 1; CALPAR; ITERATION; OUT(K); if K < N then goto NEXT STEP; FINALLY: end RICHARDSON eop