% KEYEDENTRY ON PROGRAM RESEARCH(INPUT,OUTPUT); PROCEDURE ESSPJL; CONST NST=150; MNC=10; LOGTEN=2.3025951; TYPE COMP=ARRAY[1..MNC] OF REAL; STREAMDATA=RECORD FLAG:INTEGER; PRESS:REAL; TEMP:REAL; FLOW:ARRAY[0..13] OF REAL; DESCRIPTION:ARRAY[1..15] OF CHAR END; VAR STR:ARRAY[0..NST] OF STREAMDATA; COMPNAME:ARRAY[1..MNC,1..10] OF CHAR; HOLD:ARRAY[0..1,1..100] OF REAL; NC,DIAGS,TANDP:INTEGER; VITN:INTEGER; ITE,MAXITE,UNCONVERGED:INTEGER; PROCEDURE INITIALIZE; VAR I,J:INTEGER; BEGIN FOR I:=0 TO NST DO BEGIN STR[I].FLAG :=0; STR[I].PRESS:=0; STR[I].TEMP :=0; FOR J:=1 TO MNC DO STR[I].FLOW[J]:=0; FOR J:=1 TO 10 DO STR[I].DESCRIPTION[J]:=' '; END; FOR I:=1 TO MNC DO BEGIN FOR J:=1 TO 10 DO COMPNAME[I,J]:=' '; END; NC:=1; TANDP:=0; ITE:=1; MAXITE:=20; UNCONVERGED:=0; END; PROCEDURE ERROR(N,PROCESS,IN1,IN2,OUT1,OUT2:INTEGER); BEGIN WRITELN; IF PROCESS>0 THEN BEGIN WRITE('FAULTY INTSTRUCTION: '); IF PROCESS=10 THEN WRITELN('SETSTREAM(',IN1:1,'...)'); IF PROCESS=11 THEN WRITELN('SETTP(',N:1,'...)'); IF PROCESS=12 THEN WRITELN('NAMESTREAM(',IN1:1,')'); IF PROCESS=13 THEN WRITELN('NAMECOMPONENT(',IN1:1,')'); IF PROCESS=14 THEN WRITELN('READSTREAM(',IN1:1,')'); IF PROCESS=15 THEN WRITELN('PRINTSTREAM(',IN1:1,')'); IF PROCESS=16 THEN WRITELN('COPYSTREAM(',IN1:1,',',OUT1:1,')'); IF PROCESS=2 THEN WRITELN('MIX(',IN1:1,',',IN2:1,',',OUT1:1,')'); IF PROCESS=3 THEN WRITELN('HEATMIX(',IN1:1,',',IN2:1,',',OUT1:1,'....)'); IF PROCESS=4 THEN WRITELN('SPLIT(',IN1:1,',',OUT1:1,',',OUT2:1,'....)'); IF PROCESS=51 THEN WRITELN('PHASESPLITTER(',IN1:1,OUT1:1,OUT2:1,'....)'); IF PROCESS=52 THEN WRITELN('PHASESPLITTER(....',IN1:1,'....)'); IF PROCESS=6 THEN WRITELN('CASCADE(',IN1:1,',',IN2:1,',',OUT1:1,',',OUT2:1,'....)'); IF PROCESS=71 THEN WRITELN('SEPARATOR(',IN1:1,IN2:1,OUT1:1,OUT2:1,'....)'); IF PROCESS=72 THEN WRITELN('SEPARATOR(....',IN1:1); IF PROCESS=81 THEN WRITELN('REACTOR(',IN1:1,OUT1:1,'....)'); IF PROCESS=82 THEN WRITELN('REACTOR(....',IN1:1,'....)'); IF PROCESS=9 THEN WRITELN('EXCHANGER(',IN1:1,',',IN2:1,',',OUT1:1,',',OUT2:1,'....)'); END; IF N>100 THEN BEGIN WRITELN; WRITELN('----ERROR----',N:3); WRITELN; HALT('TRY AGAIN'); END; END; PROCEDURE ALLOWED(VAR N:INTEGER;X,IN1,IN2,OUT1,OUT2:INTEGER); BEGIN IF (N<1) OR (N>NST) THEN BEGIN ERROR(100,X,IN1,IN2,OUT1,OUT2); REPEAT WRITELN; WRITELN('STREAM NUMBERS SHOULD BE BETWEEN'); WRITELN('1 AND 150 INCLUSIVE NOT...',N); WRITELN('TYPE IN THE APPROPRIATE STREAM NUMBER'); READ(N); UNTIL (N>1) AND (N<=NST); WRITELN; END; END; PROCEDURE SUDS(IN1,IN2,OUT1,OUT2,X:INTEGER); PROCEDURE TEST(N,X,Y,IN1,IN2,OUT1,OUT2:INTEGER); BEGIN IF N<>0 THEN BEGIN IF (N<1) OR (N>NST) THEN BEGIN WRITELN('STREAM NUMBERS SHOULD BE BETWEEN'); WRITELN('1 AND 150 INCLUSIVE NOT...',N); ERROR(101,X,IN1,IN2,OUT1,OUT2); END; IF (STR[N].FLAG=0) AND (Y=1) THEN BEGIN WRITELN('STREAM ',N:1,' IS UNASSIGNED'); ERROR(101,X,IN1,IN2,OUT1,OUT2); END; END; END; BEGIN TEST(IN1 ,X,1,IN1,IN2,OUT1,OUT2); TEST(IN2 ,X,1,IN1,IN2,OUT1,OUT2); TEST(OUT1,X,2,IN1,IN2,OUT1,OUT2); TEST(OUT2,X,2,IN1,IN2,OUT1,OUT2); STR[OUT1].FLAG:=1; STR[OUT2].FLAG:=1; END; FUNCTION TOTALFLOW(N:INTEGER):REAL; VAR X:REAL; I:INTEGER; BEGIN X:=0; FOR I:=1 TO NC DO X:=X+STR[N].FLOW[I]; TOTALFLOW:=X; END; PROCEDURE SETSTREAM(N:INTEGER;A,B,C,D,E,F,G,H,I,J:REAL); VAR CH:CHAR; BEGIN ALLOWED(N,10,N,0,0,0); WRITELN('IS STREAM ',N:1,' A PROCESS(P) OR AN INFORMATION(I) STREAM?'); READ(CH); IF EOLN THEN READ(CH); IF CH='P' THEN STR[N].FLAG:=1 ELSE STR[N].FLAG:=2; STR[N].FLOW[1 ]:=A; STR[N].FLOW[2 ]:=B; STR[N].FLOW[3 ]:=C; STR[N].FLOW[4 ]:=D; STR[N].FLOW[5 ]:=E; STR[N].FLOW[6 ]:=F; STR[N].FLOW[7 ]:=G; STR[N].FLOW[8 ]:=H; STR[N].FLOW[9 ]:=I; STR[N].FLOW[10]:=J; WRITELN; END; PROCEDURE SETTP(N:INTEGER;TEM,PRES:REAL); BEGIN ALLOWED(N,11,N,0,0,0); IF STR[N].FLAG=2 THEN WRITELN('SETTP(',N:1,'...) ',N:1,' WAS AN INFORMATION STREAM'); STR[N].FLAG :=1; STR[N].TEMP :=TEM; STR[N].PRESS:=PRES; END; PROCEDURE NAMESTREAM(N:INTEGER); VAR I:INTEGER; CH:CHAR; BEGIN ALLOWED(N,12,N,0,0,0); WRITELN('ENTER NAME FOR STREAM ',N); I:=1; REPEAT READ(CH); IF (NOT EOLN) AND (I<=10) THEN STR[N].DESCRIPTION[I]:=CH; I:=I+1; UNTIL EOLN; WRITELN; END; PROCEDURE NAMECOMPONENT(N:INTEGER); VAR I:INTEGER; CH:CHAR; BEGIN IF (N<1) OR (N>NC) THEN BEGIN ERROR(100,13,N,0,0,0); REPEAT WRITELN; WRITELN('TYPE IN THE APPROPRIATE COMPONENT NUMBER'); READ(N); UNTIL (N>0) AND (N<=NC); END; WRITELN('ENTER NAME FOR COMPONENT',N); I:=1; REPEAT READ(CH); IF (NOT EOLN) AND (I<10) THEN COMPNAME[N,I]:=CH; I:=I+1; UNTIL EOLN; WRITELN; END; PROCEDURE READSTREAM(N:INTEGER); VAR I:INTEGER; CH:CHAR; BEGIN ALLOWED(N,14,N,0,0,0); WRITELN; WRITELN('ENTER DATA FOR STREAM',N); WRITELN; WRITELN('IS THIS A PROCESS(P) OR INFORMATION(I) STREAM?'); READ(CH); IF (CH<'A') OR (CH>'Z') THEN READ(CH); IF CH='P' THEN BEGIN STR[N].FLAG:=1; IF TANDP=1 THEN BEGIN WRITELN('TEMP(K) '); READ (STR[N].TEMP); WRITELN('PRESS(BARA)'); READ (STR[N].PRESS); END; WRITELN('PROCESS FLOWS'); FOR I:=1 TO NC DO READ(STR[N].FLOW[I]); END ELSE BEGIN STR[N].FLAG:=2; WRITELN('INFORMATION DATA'); FOR I:=1 TO NC DO READ(STR[N].FLOW[I]); END; NAMESTREAM(N); WRITELN; END; PROCEDURE PRINTSTREAM(N:INTEGER); VAR I,J:INTEGER; BEGIN ALLOWED(N,15,N,0,0,0); IF STR[N].FLAG=0 THEN WRITELN('STREAM ',N:3,' IS UNASSIGNED') ELSE BEGIN WRITE('STREAM',N:3,' '); FOR I:=1 TO 10 DO WRITE(STR[N].DESCRIPTION[I]); WRITELN; WRITELN(' ------------'); IF STR[N].FLAG=1 THEN BEGIN WRITE('TEMP(K) ',STR[N].TEMP:8:2,' PRESS(BARA) ',STR[N].PRESS:8:2); WRITELN(' TOTAL FLOW',TOTALFLOW(N):12:3); WRITELN; END; FOR I:=1 TO NC DO BEGIN IF STR[N].FLAG=1 THEN FOR J:=1 TO 10 DO WRITE(COMPNAME[I,J]); WRITE(STR[N].FLOW[I]:9:3); IF (I=3) OR (I=6) OR (I=9) THEN WRITELN ELSE WRITE(' ! '); END; WRITELN; WRITELN('---------------------------------------------------------------------'); END; END; PROCEDURE PRINTTP(X,Y:INTEGER); VAR I:INTEGER; BEGIN WRITELN; WRITELN('TEMPERATURE/PRESSURE REPORT'); WRITELN(' STREAM TEMPERATURE(K) PRESSURE(BARA)'); FOR I:=X TO Y DO IF STR[I].FLAG=1 THEN WRITELN(I:8,STR[I].TEMP:8:2,STR[I].PRESS:8:2); WRITELN(2); END; PROCEDURE REPORTSTREAMS; PROCEDURE STREAMREPORT(N:INTEGER); VAR I,TOT:INTEGER; BEGIN WRITELN(2); IF N=1 THEN WRITE('PROCESS ') ELSE WRITE('INFORMATION '); WRITELN('STREAM REPORT'); WRITELN('---------------------'); TOT:=0; FOR I:=1 TO NST DO BEGIN IF STR[I].FLAG=N THEN BEGIN PRINTSTREAM(I); TOT:=TOT+1; END; END; WRITE(TOT); IF N=1 THEN WRITE(' PROCESS ') ELSE WRITE(' INFORMATION '); WRITELN('STREAMS DEFINED'); WRITELN(2); END; BEGIN STREAMREPORT(1); STREAMREPORT(2); END; PROCEDURE EXAMINESTREAMS; VAR N:INTEGER; BEGIN WRITELN; WRITELN('WHICH STREAM DO YOU WISH TO BE PRINTED'); WRITELN('IF NONE REQUIRED TYPE IN ''0'' (ZERO)'); REPEAT READ(N); IF (N>0) AND (N<=NST) THEN PRINTSTREAM(N); IF N<>0 THEN WRITELN('ANY-OTHERS,IF NOT TYPE IN ''0'' (ZERO)'); UNTIL (N<1) OR (N>NST); WRITELN(2) END; PROCEDURE GETSTREAMS; VAR N:INTEGER; BEGIN WRITELN; WRITELN('WHICH STREAM DO YOU WISH TO BE READ IN'); WRITELN('IF NONE REQUIRED TYPE ''0'' (ZERO)'); REPEAT READ(N); IF (N>0) AND (N<=NST) THEN READSTREAM(N); IF N<>0 THEN WRITELN('ANY-OTHERS,IF NOT TYPE IN ''0'' (ZERO)'); UNTIL (N<1) OR (N>NST); WRITELN(2) END; PROCEDURE COPYSTREAM(IN1,OUT1:INTEGER); VAR I:INTEGER; BEGIN SUDS(IN1,0,OUT1,0,16); FOR I:=1 TO NC DO STR[OUT1].FLOW[I]:=STR[IN1].FLOW[I]; IF TANDP=1 THEN BEGIN STR[OUT1].TEMP :=STR[IN1].TEMP; STR[OUT1].PRESS:=STR[IN1].PRESS; END; END; PROCEDURE NORMALISE(IN1:INTEGER;VAR FLO:REAL;VAR X:COMP); VAR I:INTEGER; BEGIN FLO:=TOTALFLOW(IN1); IF FLO=0 THEN FOR I:=1 TO NC DO X[I]:=0; IF FLO<>0 THEN FOR I:=1 TO NC DO X[I]:=STR[IN1].FLOW[I]/FLO; END; FUNCTION TEMPERATURE(N:INTEGER;H:REAL;VAR CPA,CPB:COMP):REAL; VAR I:INTEGER; SA,SB:REAL; T1,T2:REAL; D:REAL; BEGIN SA:=0; SB:=0; FOR I:=1 TO NC DO BEGIN SA:=SA+STR[N].FLOW[I]*CPA[I]; SB:=SB+STR[N].FLOW[I]*CPB[I]; END; SB:=SB/2; D:=SQR(SA)+4*SB*H; IF D<0 THEN ERROR(101,0,0,0,0,0); IF (SB=0) OR (D<0) THEN TEMPERATURE:=H/SA ELSE BEGIN D :=SQRT(D); T1:=(D-SA)/(2*SB); T2:=(-D-SA)/(2*SB); IF T1>0 THEN TEMPERATURE:=T1; IF (T1>0) AND (T2>0) THEN BEGIN ERROR(101,0,0,0,0,0); TEMPERATURE:=H/SA; END; IF T1=T2 THEN TEMPERATURE:=T1; IF (T1<0) AND (T1<>T2) THEN TEMPERATURE:=T2; END; END; PROCEDURE MIX(IN1,IN2,OUT1:INTEGER); VAR I:INTEGER; F1:REAL; F2:REAL; BEGIN SUDS(IN1,IN2,OUT1,0,2); FOR I:=1 TO NC DO BEGIN STR[OUT1].FLOW[I]:=STR[IN1].FLOW[I]+STR[IN2].FLOW[I]; END; IF TANDP=1 THEN BEGIN F1:=TOTALFLOW(IN1); F2:=TOTALFLOW(IN2); STR[OUT1].PRESS:=STR[IN1].PRESS; IF STR[IN2].PRESS0 THEN BEGIN STR[OUT1].TEMP:=STR[IN1].TEMP*F1+STR[IN2].TEMP*F2; STR[OUT1].TEMP:=STR[OUT1].TEMP/(F1+F2); END; END; END; PROCEDURE HEATMIX(IN1,IN2,OUT1:INTEGER;VAR CPA,CPB:COMP); VAR I:INTEGER; ENTH1,ENTH2:REAL; QIN:REAL; BEGIN SUDS(IN1,IN2,OUT1,0,3); ENTH1:=0; ENTH2:=0; FOR I:=1 TO NC DO BEGIN ENTH1:=ENTH1+STR[IN1].FLOW[I]*STR[IN1].TEMP*(CPA[I]+0.5*CPB[I]*STR[IN1].TEMP); ENTH2:=ENTH2+STR[IN2].FLOW[I]*STR[IN2].TEMP*(CPA[I]+0.5*CPB[I]*STR[IN2].TEMP); END; QIN:=ENTH1+ENTH2; MIX(IN1,IN2,OUT1); STR[OUT1].TEMP:=TEMPERATURE(OUT1,QIN,CPA,CPB); END; PROCEDURE SPLIT(IN1,OUT1,OUT2:INTEGER;F1:REAL); VAR I:INTEGER; BEGIN SUDS(IN1,0,OUT1,OUT2,4); IF (F1<0) OR (F1>1) THEN BEGIN WRITE('SPLIT FRACTION<0 OR SPLIT FRACTION>1'); ERROR(102,4,IN1,0,OUT1,OUT2); END; FOR I:=1 TO NC DO BEGIN STR[OUT1].FLOW[I]:=STR[IN1].FLOW[I]*F1; STR[OUT2].FLOW[I]:=STR[IN1].FLOW[I]-STR[OUT1].FLOW[I]; END; IF TANDP=1 THEN BEGIN STR[OUT1].TEMP :=STR[IN1].TEMP; STR[OUT2].TEMP :=STR[IN1].TEMP; STR[OUT1].PRESS:=STR[IN1].PRESS; STR[OUT2].PRESS:=STR[IN1].PRESS; END; END; FUNCTION FV(V:REAL;IN1:INTEGER;VAR K:COMP):REAL; VAR I:INTEGER; TOTAL:REAL; BEGIN TOTAL:=0; FOR I:=1 TO NC DO BEGIN TOTAL:=TOTAL+STR[IN1].FLOW[I]*(K[I]-1)/(V*(K[I]-1)+1); END; FV:=TOTAL; END; FUNCTION DFDV(V:REAL;IN1:INTEGER;VAR K:COMP):REAL; VAR I:INTEGER; TOTAL:REAL; BEGIN TOTAL:=0; FOR I:=1 TO NC DO BEGIN TOTAL:=TOTAL-STR[IN1].FLOW[I]*SQR((K[I]-1)/(V*(K[I]-1)+1)); END; DFDV:=TOTAL; END; PROCEDURE PHASESPLIT(IN1,OUTL,OUTV:INTEGER;VAR KVALUE:COMP); CONST TOL=0.0001; ITMAX=50; VAR I,CONV:INTEGER; VOLD,VNEW,VFRACT:REAL; FUNC,DERIV:REAL; TOTALOUTL,TOTALOUTV,TOTALIN1,ZI:REAL; BEGIN SUDS(IN1,0,OUTL,OUTV,51); TOTALOUTL:=0; TOTALOUTV:=0; TOTALIN1 :=0; FOR I:=I TO NC DO BEGIN ZI:=STR[IN1].FLOW[I]; IF ZI<>0 THEN BEGIN TOTALOUTL:=TOTALOUTL+ZI/KVALUE[I]; TOTALOUTV:=TOTALOUTV+KVALUE[I]*ZI; TOTALIN1 :=TOTALIN1+ZI; END; STR[OUTL].FLOW[I]:=0; STR[OUTV].FLOW[I]:=0; END; STR[IN1].FLOW[0]:=TOTALIN1; IF (TOTALOUTL<=1-TOL) OR (TOTALOUTV<=1-TOL) THEN BEGIN IF TOTALOUTL<=1-TOL THEN BEGIN VFRACT:=1; STR[OUTL].FLOW[0]:=0; STR[OUTV].FLOW[0]:=TOTALIN1; FOR I:=1 TO NC DO STR[OUTV].FLOW[I]:=STR[IN1].FLOW[I]; END; IF TOTALOUTV<=1-TOL THEN BEGIN VFRACT:=0; STR[OUTL].FLOW[0]:=TOTALIN1; STR[OUTV].FLOW[0]:=0; FOR I:=1 TO NC DO STR[OUTL].FLOW[I]:=STR[IN1].FLOW[I]; END; END ELSE BEGIN CONV:=1; VNEW:=0.5; FOR I:=1 TO ITMAX DO BEGIN VOLD:=VNEW; FUNC:=FV(VOLD,IN1,KVALUE); IF FUNC=0 THEN CONV:=0 ELSE BEGIN DERIV:=DFDV(VOLD,IN1,KVALUE); IF DERIV<>0 THEN BEGIN VNEW:=VOLD-FUNC/DERIV; IF ABS(VOLD-VNEW)/(ABS(VNEW)+TOL)<=TOL THEN CONV:=0; END; END; END; IF CONV=1 THEN WRITE('VFRACT FAILED TO CONVERGE'); VITN:=VITN+1; VFRACT:=VNEW; TOTALOUTL:=0; TOTALOUTV:=0; FOR I:=I TO NC DO BEGIN STR[OUTL].FLOW[I]:=STR[IN1].FLOW[I]/(VFRACT*KVALUE[I]+1-VFRACT); TOTALOUTL:=TOTALOUTL+STR[OUTL].FLOW[I]; STR[OUTV].FLOW[I]:=KVALUE[I]*STR[OUTL].FLOW[I]; TOTALOUTV:=TOTALOUTV+STR[OUTV].FLOW[I]; END; STR[OUTL].FLOW[I]:=TOTALOUTL; STR[OUTV].FLOW[I]:=TOTALOUTV; END; END; PROCEDURE PHASESPLITTER(IN1,OUTL,OUTV,SPLT:INTEGER); VAR I:INTEGER; SP:COMP; BEGIN SUDS(SPLT,0,0,0,52); FOR I:=1 TO NC DO SP[I]:=STR[SPLT].FLOW[I]; PHASESPLIT(IN1,OUTL,OUTV,SP); END; PROCEDURE CASCADE(INV,INL,OUTV,OUTL,KVALUE:INTEGER;N:REAL); VAR L,V,FI,Q,E,EN,FEED:REAL; LI,ETOP,EBASE:REAL; I:INTEGER; KBASE:ARRAY[1..MNC] OF REAL; KTOP :ARRAY[1..MNC] OF REAL; XTOP :ARRAY[1..MNC] OF REAL; YBASE:ARRAY[1..MNC] OF REAL; BEGIN SUDS(INV,INL,OUTV,OUTL,6); NORMALISE(INV,V,YBASE); NORMALISE(INL,L,XTOP); COPYSTREAM(INV,OUTV); COPYSTREAM(INL,OUTL); IF (V<>0) AND (L<>0) THEN BEGIN FOR I:=1 TO NC DO BEGIN FEED:=L*XTOP[I]+V*YBASE[I]; IF FEED=0 THEN LI:=0 ELSE BEGIN EBASE:=KBASE[I]*V/L; ETOP :=KTOP[I]*V/L; E:=SQRT(ETOP*(EBASE+1)+0.25)-0.5; IF E<0.000001 THEN E:=0.000001; EN:=N*LN(E); IF EN>100 THEN EN:=100; EN:=EXP(EN); Q :=L*XTOP[I]/FEED; FI:=((1-EN)+Q*(EN-E))/(1-EN*E); LI:=FI*FEED; END; IF LI<0 THEN LI:=0; IF LI>FEED THEN LI:=FEED; STR[OUTL].FLOW[I]:=LI; STR[OUTV].FLOW[I]:=FEED-LI; END; END; END; PROCEDURE SEPARATE(IN1,IN2,OUT1,OUT2:INTEGER;VAR SP:COMP); VAR AMT:ARRAY[1..MNC] OF REAL; PS:REAL; I:INTEGER; BEGIN SUDS(IN1,IN2,OUT1,OUT2,71); FOR I:=1 TO NC DO BEGIN AMT[I]:=0; IF IN1<>0 THEN AMT[I]:=STR[IN1].FLOW[I]; IF IN2<>0 THEN AMT[I]:=AMT[I]+STR[IN2].FLOW[I]; END; FOR I:=1 TO NC DO BEGIN IF (SP[I]<0) OR (SP[I]>1) THEN BEGIN WRITE('SPLIT FRACTION<0 OR SPLIT FRACTION>1'); ERROR(102,71,IN1,IN2,OUT1,OUT2); END; STR[OUT1].FLOW[I]:=AMT[I]*SP[I]; STR[OUT2].FLOW[I]:=AMT[I]-STR[OUT1].FLOW[I]; END; IF TANDP=1 THEN BEGIN IF (IN1=0) OR (IN2=0) THEN BEGIN IF IN1=0 THEN IN1:=IN2 ELSE IN2:=IN1; END; STR[OUT1].TEMP:=STR[IN1].TEMP; STR[OUT2].TEMP:=STR[IN2].TEMP; IF STR[IN1].PRESS=0 THEN BEGIN WRITE('KEY COMPONENT IS NOT A REACTANT'); ERROR(103,81,IN1,OUT1,0,0); END; AMT:=CONV*STR[IN1].FLOW[KEY]; FOR I:=1 TO NC DO BEGIN STR[OUT1].FLOW[I]:=STR[IN1].FLOW[I]+STO[I]*AMT/ABS(STO[KEY]); IF STR[OUT1].FLOW[I]<0 THEN BEGIN ERROR(125,0,0,0,0,0); REACTION(IN1,OUT1,I,1.0,STO); I:=NC; END; END; END; PROCEDURE REACTOR(IN1,OUT1,COEFFS,KEY:INTEGER;CON:REAL); VAR I:INTEGER; STOCH:COMP; BEGIN SUDS(COEFFS,0,0,0,82); FOR I:=1 TO NC DO STOCH[I]:=STR[COEFFS].FLOW[I]; REACTION(IN1,OUT1,KEY,CON,STOCH); END; PROCEDURE EXCHANGER(IN1,IN2,OUT1,OUT2:INTEGER;UA,CP1,CP2:REAL); VAR FC,FH,F,R:REAL; BEGIN SUDS(IN1,IN2,OUT1,OUT2,9); FC:=TOTALFLOW(IN1)*CP1; FH:=TOTALFLOW(IN2)*CP2; COPYSTREAM(IN1,OUT1); COPYSTREAM(IN2,OUT2); IF (FC=0) OR (FH=0) THEN BEGIN STR[OUT1].TEMP:=STR[IN1].TEMP; STR[OUT2].TEMP:=STR[IN2].TEMP; END ELSE BEGIN R:=FH/FC; IF R=1 THEN F:=1/(1+UA/FH) ELSE F:=(1-R)/(1-R*EXP(-UA*(1-R)/FH)); STR[OUT1].TEMP:=STR[IN2].TEMP+(STR[IN1].TEMP-STR[IN2].TEMP)*F; STR[OUT2].TEMP:=STR[IN2].TEMP+(STR[IN1].TEMP-STR[IN2].TEMP)*(1-F/R); END; END; FUNCTION TEST(NEW,OLD,TOT:REAL):INTEGER; BEGIN IF ABS(NEW-OLD)/(ABS(NEW)+TOT)<=TOT THEN TEST:=0 ELSE TEST:=1; END; PROCEDURE AITKEN(VAR X2,X1,X0:REAL); VAR DENOM,XNEW:REAL; BEGIN DENOM:=2*X1-X2-X0; IF ABS(DENOM)<0.00001 THEN BEGIN IF DIAGS>0 THEN BEGIN WRITELN('AITKEN SUPPRESSED X=',X2); WRITELN; END; END ELSE BEGIN XNEW:=X2+SQR(X2-X1)/DENOM; IF X2*XNEW>0 THEN X2:=XNEW; END; END; FUNCTION CONVSTREAM(ST,LOOPNOS,ITE,METHOD:INTEGER):INTEGER; VAR POINT,I,N,KK:INTEGER; BEGIN N:=NC; POINT:=(LOOPNOS-1)*(NC+3); IF POINT-(NC+3)>100 THEN BEGIN WRITELN('****TOO MANY ITERATE VARIABLES****'); ERROR(115,0,0,0,0,0); END; STR[ST].FLOW[NC+2]:=STR[ST].TEMP; STR[ST].FLOW[NC+3]:=STR[ST].PRESS; IF ITE>1 THEN BEGIN N:=0; FOR I:=1 TO NC+3 DO BEGIN N:=N+TEST(STR[ST].FLOW[I],HOLD[1,POINT+I],0.0001); END; END; FOR I:=1 TO NC+3 DO BEGIN KK:=POINT+I; IF (METHOD=1) AND (((ITE/3.0)-TRUNC(ITE/3.0))<0.01) THEN BEGIN AITKEN(STR[ST].FLOW[I],HOLD[1,KK],HOLD[0,KK]); END; IF (METHOD=2) AND (((ITE/5.0)-TRUNC(ITE/5.0))<0.001) THEN BEGIN AITKEN(STR[ST].FLOW[I],HOLD[1,KK],HOLD[0,KK]); END; HOLD[0,KK]:=HOLD[1,KK]; HOLD[1,KK]:=STR[ST].FLOW[I]; END; CONVSTREAM:=N; END; PROCEDURE TESTSTREAM(STREAM,LOOPNOS,METHOD:INTEGER); BEGIN UNCONVERGED:=CONVSTREAM(STREAM,LOOPNOS,ITE,METHOD)+UNCONVERGED; END; FUNCTION CONVERGED:BOOLEAN; BEGIN IF (UNCONVERGED=0) OR (ITE>=MAXITE) THEN BEGIN WRITELN; WRITE('THERE WERE ',ITE:2); IF ITE>=MAXITE THEN WRITE(' ,THE SET MAXIMUM NUMBER OF'); WRITELN(' ITERATIONS'); ITE:=1; CONVERGED:=TRUE; END ELSE BEGIN ITE:=ITE+1; CONVERGED:=FALSE; END; UNCONVERGED:=0; END; BEGIN END.