/* Metropolis Monte Carlo simulation of a Lennard-Jones fluid in a periodic boundary, using the Widom test particle insertion method to compute mu_ex Cameron F. Abrams Written for the course CHE 800-002, Molecular Simulation Spring 0304 compile using "gcc -o mclj_widom mclj_widom.c -lm -lgsl" (assumes the GNU Scientific Library is installed) runs as "./mclj_widom -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 /* 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 (r2hL) 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; /* Get the new energy */ 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; nAcc++; } /* ... or reject the move; reassign the old positions */ else { rx[i]=rxold; ry[i]=ryold; rz[i]=rzold; } /* Sample: default frequency is once per trial move; We must include results of a move regardless of whether the move is accepted or rejected. */ if (c>nEq&&(!(c%fs))) { esum+=E_old; vir_sum+=vir_old; widom(rx,ry,rz,N,L,rc2,shift,ecut,r,&we); w_sum+=exp(-T*we); nSamp++; } } if (short_out) fprintf(stdout,"%.5lf %.5lf\n",rho, -log(w_sum/nSamp)/T + (tailcorr?(2*ecor):0)); else fprintf(stdout,"NVT Metropolis Monte Carlo Simulation" " of the Lennard-Jones fluid with the Widom Method.\n" "---------------------------------------------\n" "Number of particles: %i\n" "Number of cycles: %i\n" "Cutoff radius: %.5lf\n" "Maximum displacement: %.5lf\n" "Density: %.5lf\n" "Temperature: %.5lf\n" "Tail corrections applied? %s\n" "Shifted potential? %s\n" "Results:\n" "Potential energy tail correction: %.5lf\n" "Pressure tail correction: %.5lf\n" "Potential energy shift at cutoff: %.5lf\n" "Acceptance ratio: %.5lf\n" "Energy/particle: %.5lf\n" "Ideal gas pressure: %.5lf\n" "Virial: %.5lf\n" "Total pressure: %.5lf\n" "Excess chemical potential: %.5lf\n" "Program ends.\n", N,nCycles,sqrt(rc2),dr,rho,1.0/T, tailcorr?"Yes":"No",shift?"Yes":"No", ecor,pcor,ecut, ((double)nAcc)/nCycles, esum/nSamp/N, rho/T,vir_sum/3.0/nSamp/V, vir_sum/3.0/nSamp/V+rho/T+(tailcorr?pcor:0.0), -log(w_sum/nSamp)/T + (tailcorr?(2*ecor):0)); }