Computer simulation of formation of Liesegang bands (written in Pascal)program Liesegang_With_Menu; {by Albert Harris, 1994} uses memtypes, quickdraw; {in Pascal programs, you start by } const MN = 200; SPACE=2; {naming all the variables you will use} type ary = array [0..MN] of real; {and whether they will be integers, etc.} var SATURATION, SUPERSATURATION, DiffConst_A, DiffConst_B, ACONC, BCONC : real; Skip : integer; a, b, na, nb : ary; n, cycle : integer; c :array [0..MN] of boolean; {arrays are sort of like rows of mailboxes} t :array [0..MN] of integer; {in which you can store a value in each "box"} procedure set_MENU_choices; {this procedure (=subroutine) asks the user to assign values} begin writeln('What should the saturation concentration be? (50)'); writeln('(The numbers in parentheses are the values used in the original program.'); readln(SATURATION); writeln('What should the supersaturation concentration be? (100)'); readln(SUPERSATURATION); writeln('What diffusion constant should A have? (0.5)'); readln( DiffConst_A); writeln('What diffusion constant should B have? (0.5)'); readln(DiffConst_B); writeln('The initial concentration of A should be what? (200)'); readln(ACONC); writeln('The initial concentration of A should be what? (20)'); readln(BCONC); writeln('A new graph should be drawn every how many recalculation cycles? (5)'); skip:=5; readln(skip); end; procedure set_start; {this procedure assigns initial values to appropriate "mailboxes"} begin for n:=1 to MN do begin; a[n]:= 0.0; b[n]:=BCONC; c[n]:=false; cycle:= -1; end; a[1]:=ACONC ;b[1]:=0; end; {of the set_start procedure} procedure diffuse; {this procedure recalculates values as if they were diffusing} begin; for n:=2 to MN-1 do begin; na[n]:=a[n]+ DiffConst_A * (a[n-1]+a[n+1]-2*a[n])/2; nb[n]:=b[n]+ DiffConst_B * (b[n-1]+b[n+1]-2*b[n])/2; end; end; {of the diffuse procedure} procedure plot_sisyphisAxB; {this procedure draws one of the graphs of concentrations} begin; moveto(250+ SPACE,250-round(a[1]*b[1]/5)); for n:=2 to MN do begin; lineto(250+ n*SPACE,250-round(a[n]*b[n]/5)); end; end; {you don't really have to write which procedure it's the end of} procedure react; {this procedure causes crystalization where concentrations are high enough} begin; cycle:= cycle+1; for n:=2 to MN-1 do begin; if a[n]*b[n]>SUPERSATURATION then c[n]:=true ; if c[n]=true then begin; if a[n]*b[n]>SATURATION then begin t[n]:=cycle; {plot_sisyphisAxB;} repeat a[n]:=a[n]-1; b[n]:=b[n]-1; until a[n]*b[n]< SATURATION {or b[n]<0.0}; end; end; end; end; {of the react procedure, although the program would run just as well without this} procedure new_old; {this procedure resets values, before another round of recalculation} begin; for n:=2 to MN-1 do begin; a[n]:= na[n]; b[n]:= nb[n]; end; end; { can you figure out which procedure this is the end of? } procedure plot_A; {another graph plotting procedure} begin; moveto(10+ SPACE,150- round(a[1])); for n:=2 to MN do begin; lineto(10+ n*SPACE,150- round( a[n])); end; end; {of procedure plot_A} procedure plot_B; {yet another graph plotting procedure} begin; moveto(10+ SPACE,150-round( b[1])); for n:=2 to MN do begin; lineto(10+ n*SPACE,150-round( b[n])); end; end; {of procedure plot_B} procedure plot_C; {this procedure marks location where crystal precipitation occurred} begin; for n:=2 to MN do begin; if c[n]=true then begin; moveto(10+ n*SPACE,155); lineto(10+ n*SPACE,170); end; end; end; {of procedure plot_C} procedure plot_AxB; {yet another graph plotting procedure} begin; moveto(10+SPACE, 250-round(SUPERSATURATION/5)); lineto(10+SPACE*MN,250-round(SUPERSATURATION/5)); moveto(10+SPACE, 250-round(SATURATION/5)); lineto(10+SPACE*MN,250-round(SATURATION/5)); moveto(10+ SPACE,250-round(a[1]*b[1]/5)); for n:=2 to MN do begin; lineto(10+ n*SPACE,250-round(a[n]*b[n]/5)); end; end; {of procedure plot_AxB} begin {main program}; {now the program uses all the subroutines defined above} set_MENU_choices; set_start; while not keypressed do begin; {the following is a loop that keeps repeating forever, until you type} react; diffuse; new_old; if cycle mod skip=0 then begin clearscreen; writeln(' cycle number ',cycle); writeln(' Diffusion constant of A ',DiffConst_A:2:2); writeln(' Diffusion constant of B ',DiffConst_B:2:2); writeln(' A concentration at margin ',ACONC:2:2); writeln(' concentration of B in gel ',BCONC:2:2); writeln(' SATURATION = ',SATURATION:2:2); writeln(' SUPERSATURATION = ',SUPERSATURATION:2:2); plot_A; plot_B; plot_C; plot_AxB; end;end; readln; writeln('The following are the positions and times at which rings formed.'); for n:= 1 to MN do begin if c[n]=true then writeln(' n= ',n,' time = ',t[n]); end; readln; end. {There, now! You understood it all, didn't you?} |