/* Metropolis Monte Carlo simulation of a Lennard-Jones fluid in a periodic boundary: NPT implementation Cameron F. Abrams Written for the course CHE 800-002, Molecular Simulation Spring 0304 compile using "gcc -o mclj_npt mclj_npt.c -lm -lgsl" (assumes the GNU Scientific Library is installed) runs as "./mclj_npt -N -rho \ -nc -dr \ -s -ne <#equil.cycles(100)>" You must have the GNU Scientific Library installed; see the coursenotes to learn how to do this. Drexel University, Department of Chemical Engineering Philadelphia (c) 2004 */ #include #include #include #include #include /* An N^2 algorithm for computing the total energy. The virial is also computed and returned in *vir. */ double total_e ( double * rx, double * ry, double * rz, int N, double L, double rc2, int tailcorr, double ecor, int shift, double ecut, double * vir ) { int i,j; double dx, dy, dz, r2, r6i; double e = 0.0, hL=L/2.0; *vir=0.0; for (i=0;i<(N-1);i++) { for (j=i+1;jhL) dx-=L; else if (dx<-hL) dx+=L; if (dy>hL) dy-=L; else if (dy<-hL) dy+=L; if (dz>hL) dz-=L; else if (dz<-hL) dz+=L; r2 = dx*dx + dy*dy + dz*dz; if (r2L) rx[i]-=L; if (ry[i]<0.0) ry[i]+=L; if (ry[i]>L) ry[i]-=L; if (rz[i]<0.0) rz[i]+=L; if (rz[i]>L) rz[i]-=L; E_new = total_e(rx,ry,rz,N,L,rc2,tailcorr,ecor,shift,ecut,&vir); /* Conditionally accept... */ if (gsl_rng_uniform(r) < exp(-T*(E_new-(*E_old)))) { *E_old=E_new; *vir_old=vir; return 1; } /* ... or reject the move; reassign the old positions */ else { rx[i]=rxold; ry[i]=ryold; rz[i]=rzold; return 0; } } int mcvol ( double * rx, double * ry, double * rz, int N, double * L, int tailcorr, double * ecor, double * pcor, int shift, double * ecut, double * rc2, double dlnV, double T, double P, double * E_old, double * vir_old, gsl_rng * r ) { int i; double V0 = (*L)*(*L)*(*L); double f, lnV, lnV0, V, L1, E_new, vir, rho, rr3, arg, rc; lnV0 = log(V0); lnV = lnV0 + dlnV*(gsl_rng_uniform(r)-0.5); V=exp(lnV); L1 = pow(V,0.333333333); f = L1/(*L); for (i=0;inEq) { esum+=E; p_sum+=vir/3.0/(L*L*L)+pcor; rho_sum+=N/(L*L*L); nSamp++; } } if (short_out) fprintf(stdout,"%.3lf %.3lf | %.6lf %.6lf : %.5lf %.5lf [%.5lf] %.5lf\n", T,P,dr,dlnV,((double)nAcc)/(N*nCycles), esum/nSamp/N,p_sum/nSamp+rho_sum/nSamp*T,rho_sum/nSamp); else fprintf(stdout,"NPT Metropolis Monte Carlo Simulation" " of the Lennard-Jones fluid.\n" "---------------------------------------------\n" "Number of particles: %i\n" "Number of cycles: %i\n" "Maximum particle displacement: %.5lf\n" "Maximum log-volume displacement: %.5lf\n" "Temperature: %.5lf\n" "Pressure: %.5lf\n" "Tail corrections used? %s\n" "Shifted potentials used? %s\n" "Results:\n" "Displacement attempts: %i\n" "Volume change attempts: %i\n" "Acceptance ratio, ptcl displ. %.5lf\n" "Acceptance ratio, vol moves %.5lf\n" "Overall acceptance ratio: %.5lf\n" "Energy/particle: %.5lf\n" "Density: %.5lf\n" "Computed Pressure: %.5lf\n" "Program ends.\n", N,nCycles,dr,dlnV,T,P, tailcorr?"Yes":"No",shift?"Yes":"No", nTransAtt,nVolAtt, ((double)nTransAcc)/(nTransAtt?nTransAtt:1), ((double)nVolAcc)/(nVolAtt?nVolAtt:1), ((double)nAcc)/nCycles, esum/nSamp/N,rho_sum/nSamp, p_sum/nSamp+rho_sum/nSamp*T); return 0; }