PROGRAM md PUBLIC x(36),y(36),vx(36),vy(36),ax(36),ay(36) PUBLIC N,Lx,Ly,dt,dt2 PUBLIC gcum(0:1000),nbin,dr PUBLIC xsave(100),ysave(100),R2cum(100) LIBRARY "csgraphics" CALL initial(t,ke,kecum,pecum,vcum,area) CALL set_up_windows(#1,#2) CALL accel(pe,virial) LET E = ke + pe ! total energy LET ncum = 0 ! number of times data accumulated LET flag$ = "" DO CALL show_positions(flag$,#2) CALL Verlet(t,ke,pe,virial) CALL show_output(t,ke,pe,virial,kecum,vcum,ncum,area,#1) LOOP until flag$ = "stop" CALL save_config END SUB initial(t,ke,kecum,pecum,vcum,area) DECLARE PUBLIC x(),y(),vx(),vy() DECLARE PUBLIC N,Lx,Ly,dt,dt2 DECLARE PUBLIC gcum(),nbin,dr DECLARE DEF pbc LET dt = 0.01 LET dt2 = dt*dt LET response$ = "" DO INPUT prompt "read data statements (d) or file (f)? ": start$ IF (start$ = "d") or (start$ = "D") then LET response$ = "ok" LET N = 16 LET Lx = 6 LET Ly = 6 DATA 1.09,0.98,-0.33,0.78,3.12,5.25,0.12,-1.19 DATA 0.08,2.38,-0.08,-0.10,0.54,4.08,-1.94,-0.56 DATA 2.52,4.39,0.75,0.34,3.03,2.94,1.70,-1.08 DATA 4.25,3.01,0.84,0.47,0.89,3.11,-1.04,0.06 DATA 2.76,0.31,1.64,1.36,3.14,1.91,0.38,-1.24 DATA 0.23,5.71,-1.58,0.55,1.91,2.46,-1.55,-0.16 DATA 4.77,0.96,-0.23,-0.83,5.10,4.63,-0.31,0.65 DATA 4.97,5.88,1.18,1.48,3.90,0.20,0.46,-0.51 FOR i = 1 to N READ x(i),y(i),vx(i),vy(i) NEXT i ELSE IF (start$ = "f") or (start$ = "F") then LET response$ = "ok" INPUT prompt "file name = ": file$ OPEN #1: name file$, access input INPUT #1: N INPUT #1: Lx INPUT #1: Ly INPUT #1: heading$ FOR i = 1 to N INPUT #1: x(i),y(i) NEXT i INPUT #1: heading$ FOR i = 1 to N INPUT #1: vx(i),vy(i) NEXT i CLOSE #1 ELSE PRINT PRINT "d or f are the only acceptable responses." END IF LOOP until response$ = "ok" CLEAR LET ke = 0 ! kinetic energy FOR i = 1 to N LET ke = ke + vx(i)*vx(i) + vy(i)*vy(i) NEXT i LET ke = 0.5*ke LET area = Lx*Ly LET t = 0 ! time ! initialize sums LET kecum = 0 LET pecum = 0 LET vcum = 0 END SUB SUB set_up_windows(#1,#2) DECLARE PUBLIC Lx,Ly OPEN #1: screen 0,1,0.90,1.0 ! numerical output OPEN #2: screen 0.02,1,0.02,0.90 ! particle trajectories CALL compute_aspect_ratio(Lx,xwin,ywin) SET WINDOW 0,xwin,0,ywin BOX LINES 0,Lx,0,Ly CALL headings(#1) END SUB SUB headings(#1) WINDOW #1 SET CURSOR 1,1 PRINT using "##########": "time steps"; PRINT, PRINT using "###.##": "time"; PRINT, PRINT using "---#.###": "energy"; PRINT, PRINT using "##.##": ""; PRINT, PRINT using "##.##": "

" END SUB SUB Verlet(t,ke,pe,virial) DECLARE PUBLIC x(),y(),vx(),vy(),ax(),ay() DECLARE PUBLIC N,Lx,Ly,dt,dt2 DECLARE DEF pbc FOR i = 1 to N LET xnew = x(i) + vx(i)*dt + 0.5*ax(i)*dt2 LET ynew = y(i) + vy(i)*dt + 0.5*ay(i)*dt2 ! partially update velocity using old acceleration LET vx(i) = vx(i) + 0.5*ax(i)*dt LET vy(i) = vy(i) + 0.5*ay(i)*dt LET x(i) = pbc(xnew,Lx) LET y(i) = pbc(ynew,Ly) NEXT i CALL accel(pe,virial) ! new acceleration LET ke = 0 FOR i = 1 to N ! complete the update of the velocity using new acceleration LET vx(i) = vx(i) + 0.5*ax(i)*dt LET vy(i) = vy(i) + 0.5*ay(i)*dt LET ke = ke + vx(i)*vx(i) + vy(i)*vy(i) NEXT i LET ke = 0.5*ke LET t = t + dt END SUB FUNCTION pbc(pos,L) IF pos < 0 then LET pbc = pos + L ELSE IF pos > L then LET pbc = pos - L ELSE LET pbc = pos END IF END DEF SUB accel(pe,virial) DECLARE PUBLIC x(),y(),ax(),ay() DECLARE PUBLIC N,Lx,Ly DECLARE DEF separation FOR i = 1 to N LET ax(i) = 0 LET ay(i) = 0 NEXT i LET pe = 0 LET virial = 0 FOR i = 1 to N - 1 ! compute total force on particle i FOR j = i + 1 to N ! due to particles j > i LET dx = separation(x(i) - x(j),Lx) LET dy = separation(y(i) - y(j),Ly) ! acceleration = force because mass = 1 in reduced units CALL force(dx,dy,fxij,fyij,pot) LET ax(i) = ax(i) + fxij LET ay(i) = ay(i) + fyij LET ax(j) = ax(j) - fxij ! Newton's third law LET ay(j) = ay(j) - fyij LET pe = pe + pot LET virial = virial + dx*fxij + dy*fyij NEXT j NEXT i END SUB SUB force(dx,dy,fx,fy,pot) LET r2 = dx*dx + dy*dy LET rm2 = 1/r2 LET rm6 = rm2*rm2*rm2 LET f_over_r = 24*rm6*(2*rm6 - 1)*rm2 LET fx = f_over_r*dx LET fy = f_over_r*dy LET pot = 4*(rm6*rm6 - rm6) END SUB FUNCTION separation(ds,L) IF ds > 0.5*L then LET separation = ds - L ELSE IF ds < -0.5*L then LET separation = ds + L ELSE LET separation = ds END IF END DEF SUB show_positions(flag$,#2) DECLARE PUBLIC x(),y(),N,Lx,Ly IF key input then GET KEY k IF k = ord("r") then WINDOW #2 CLEAR SET COLOR "black" BOX LINES 0,Lx,0,Ly LET flag$ = "" ELSEIF k = ord("s") then LET flag$ = "stop" ELSEIF k = ord("n") then LET flag$ = "no_show" END IF END IF IF flag$ <> "no_show" then WINDOW #2 SET COLOR "red" FOR i = 1 to N PLOT x(i),y(i) NEXT i END IF END SUB SUB show_output(t,ke,pe,virial,kecum,vcum,ncum,area,#1) WINDOW #1 DECLARE PUBLIC N,Lx,Ly SET CURSOR 2,1 SET COLOR "black/white" LET ncum = ncum + 1 PRINT using "######": ncum; PRINT, PRINT using "###.##": t; ! time PRINT, LET E = ke + pe ! total energy PRINT using "---#.###": E; PRINT, LET kecum = kecum + ke LET vcum = vcum + virial LET mean_ke = kecum/ncum ! still need to divide by N LET p = mean_ke + (0.5*vcum)/ncum ! mean pressure * area LET p = p/area PRINT using "##.##": mean_ke/N; ! mean kinetic temperature PRINT, PRINT using "##.##": p; END SUB SUB save_config DECLARE PUBLIC x(),y(),vx(),vy() DECLARE PUBLIC N,Lx,Ly INPUT prompt "file name of saved configuration = ": file$ OPEN #1: name file$,access output,create new PRINT #1: N PRINT #1: Lx PRINT #1: Ly PRINT #1: "x(i)","y(i)" ! comma added between outputs on the same line so that file ! can be read by True BASIC FOR i = 1 to N PRINT #1, using "----.####, ----.#####": x(i),y(i) NEXT i PRINT #1: "vx(i)","vy(i)" FOR i = 1 to N PRINT #1, using "----.####, ----.#####": vx(i),vy(i) NEXT i CLOSE #1 END SUB