48 double * rx,
double * ry,
double * rz,
49 double * vx,
double * vy,
double * vz,
50 int * ix,
int * iy,
int * iz,
double L,
51 int N,
int z,
int put_vel,
int unfold) {
54 fprintf(fp,
"%i %i\n\n",N,put_vel);
56 fprintf(fp,
"%i %.8lf %.8lf %.8lf ",z,
57 rx[i]+(unfold?(ix[i]*L):0.0),
58 ry[i]+(unfold?(iy[i]*L):0.0),
59 rz[i]+(unfold?(iz[i]*L):0.0));
61 fprintf(fp,
"%.8lf %.8lf %.8lf",vx[i],vy[i],vz[i]);
66 int xyz_in (FILE * fp,
double * rx,
double * ry,
double * rz,
67 double * vx,
double * vy,
double * vz,
71 fscanf(fp,
"%i %i\n\n",N,&has_vel);
72 for (i=0;i<(*N);i++) {
73 fscanf(fp,
"%i %lf %lf %lf ",&dum,&rx[i],&ry[i],&rz[i]);
75 fscanf(fp,
"%lf %lf %lf",&vx[i],&vy[i],&vz[i]);
91 double *rx0,
double *ry0,
double *rz0) {
111 double *rx0,
double *ry0,
double *rz0) {
115 double dx2= (rx[i]-rx0[i])*(rx[i]-rx0[i]) \
116 +(ry[i]-ry0[i])*(ry[i]-ry0[i]) \
117 +(rz[i]-rz0[i])*(rz[i]-rz0[i]);
138 double *rx,
double *ry,
double *rz,
139 double *dx,
double *dy,
double *dz,
double L) {
151 else if (*dx<-hL) *dx+=L;
153 else if (*dy<-hL) *dy+=L;
155 else if (*dz<-hL) *dz+=L;
156 r2 = *dx* *dx + *dy* *dy + *dz* *dz;
175 void calc_lj (
int i,
int j,
double dx,
double dy,
double dz,
double r2,
176 double * fx,
double * fy,
double * fz,
177 double rc2,
double ecut,
double * vir,
double *e) {
181 r6i = 1.0/(r2*r2*r2);
182 *e += 4*(r6i*r6i - r6i) - ecut;
183 f = 48*(r6i*r6i-0.5*r6i);
216 void calc_dpd (
int i,
int j,
double dx,
double dy,
double dz,
double r2,
217 double * fx,
double * fy,
double * fz,
dpd_t* dpd) {
219 double v_dot_d, amplitude;
220 double tmp_x,tmp_y,tmp_z;
221 if (r2 < dpd->cutoff2) {
222 v_dot_d = ( dpd->
vx[i] - dpd->
vx[j] ) * dx ;
223 v_dot_d += ( dpd->
vy[i] - dpd->
vy[j] ) * dy ;
224 v_dot_d += ( dpd->
vz[i] - dpd->
vz[j] ) * dz ;
225 amplitude = dpd->
prefactor / sqrt(r2) * (drand48()-0.5) - dpd->
gamma * v_dot_d / r2;
226 tmp_x = amplitude * dx;
229 tmp_y = amplitude * dy;
232 tmp_z = amplitude * dz;
280 double total_e (
double * rx,
double * ry,
double * rz,
281 double * fx,
double * fy,
double * fz,
283 double rc2,
double ecor,
double ecut,
double * vir ) {
285 int cx,cy,cz,nbx,nby,nbz,c;
294 fx[i]=fy[i]=fz[i]=0.0;
299 for (i=0;i<(N-1);i++) {
300 for (j=i+1;j<N;j++) {
301 r2=
per_dist2(i,j,rx,ry,rz,&dx,&dy,&dz,L);
302 calc_lj(i,j,dx,dy,dz,r2,fx,fy,fz,rc2,ecut,vir,&e);
304 calc_dpd(i,j,dx,dy,dz,r2,fx,fy,fz,dpd);
318 cx=(int)floor(rx[i]/nblist->
lc->
lcell);
319 cy=(int)floor(ry[i]/nblist->
lc->
lcell);
320 cz=(int)floor(rz[i]/nblist->
lc->
lcell);
331 for(cx=0;cx<nblist->
lc->
ncells;cx++){
332 for(cy=0;cy<nblist->
lc->
ncells;cy++){
333 for(cz=0;cz<nblist->
lc->
ncells;cz++){
336 for (nbx=cx-nblist->
lc->
left;nbx<=cx+nblist->lc->right;nbx++){
337 for (nby=cy-nblist->
lc->
left;nby<=cy+nblist->lc->right;nby++){
338 for (nbz=cz-nblist->
lc->
left;nbz<=cz+nblist->lc->right;nbz++){
346 r2=
per_dist2(i,j,rx,ry,rz,&dx,&dy,&dz,L);
347 calc_lj(i,j,dx,dy,dz,r2,fx,fy,fz,rc2,ecut,vir,&e);
349 calc_dpd(i,j,dx,dy,dz,r2,fx,fy,fz,dpd);
368 for(cx=0;cx<nblist->
lc->
ncells;cx++){
369 for(cy=0;cy<nblist->
lc->
ncells;cy++){
370 for(cz=0;cz<nblist->
lc->
ncells;cz++){
377 for (nbx=cx-nblist->
lc->
left;nbx<=cx+nblist->lc->right;nbx++){
378 for (nby=cy-nblist->
lc->
left;nby<=cy+nblist->lc->right;nby++){
379 for (nbz=cz-nblist->
lc->
left;nbz<=cz+nblist->lc->right;nbz++){
386 r2=
per_dist2(i,j,rx,ry,rz,&dx,&dy,&dz,L);
387 if (r2 < nblist->vl->cutoff2) {
388 if(k == nblist->
vl->
size ) {
394 calc_lj(i,j,dx,dy,dz,r2,fx,fy,fz,rc2,ecut,vir,&e);
396 calc_dpd(i,j,dx,dy,dz,r2,fx,fy,fz,dpd);
417 for (i=0;i<(N-1);i++) {
419 for (j=i+1;j<N;j++) {
420 r2=
per_dist2(i,j,rx,ry,rz,&dx,&dy,&dz,L);
421 if (r2 < nblist->vl->cutoff2) {
422 if(k == nblist->
vl->
size ) {
428 calc_lj(i,j,dx,dy,dz,r2,fx,fy,fz,rc2,ecut,vir,&e);
430 calc_dpd(i,j,dx,dy,dz,r2,fx,fy,fz,dpd);
444 for (k=nblist->
vl->
head[l];k<nblist->vl->head[l+1];k++) {
446 r2=
per_dist2(i,j,rx,ry,rz,&dx,&dy,&dz,L);
447 calc_lj(i,j,dx,dy,dz,r2,fx,fy,fz,rc2,ecut,vir,&e);
449 calc_dpd(i,j,dx,dy,dz,r2,fx,fy,fz,dpd);
455 for (i=0;i<(N-1);i++) {
456 for (k=nblist->
vl->
head[i];k<nblist->vl->head[i+1];k++) {
458 r2=
per_dist2(i,j,rx,ry,rz,&dx,&dy,&dz,L);
459 calc_lj(i,j,dx,dy,dz,r2,fx,fy,fz,rc2,ecut,vir,&e);
461 calc_dpd(i,j,dx,dy,dz,r2,fx,fy,fz,dpd);
480 double r,theta,u1,u2,x1;
485 r=sqrt(-2*log(u1))*sigma;
487 x1 = r*cos(theta) + mean;
488 x2 = r*sin(theta) + mean ;
500 void init (
double * rx,
double * ry,
double * rz,
501 double * vx,
double * vy,
double * vz,
502 int * ix,
int * iy,
int * iz,
503 int * N,
double L,
double T0,
504 double * KE,
char * icf) {
506 double cmvx=0.0,cmvy=0.0,cmvz=0.0;
514 FILE * fp = fopen(icf,
"r");
516 vel_ok =
xyz_in(fp,rx,ry,rz,vx,vy,vz,N);
519 fprintf(stderr,
"# error: could not read %s\n",icf);
529 while ((n3*n3*n3)<*N) n3++;
534 rx[i] = ((double)iix+0.5)*L/n3;
535 ry[i] = ((double)iiy+0.5)*L/n3;
536 rz[i] = ((double)iiz+0.5)*L/n3;
567 (*KE)+=vx[i]*vx[i]+vy[i]*vy[i]+vz[i]*vz[i];
579 (*KE)+=vx[i]*vx[i]+vy[i]*vy[i]+vz[i]*vz[i];
591 int main (
int argc,
char * argv[] ) {
593 double * rx, * ry, * rz;
594 double * vx, * vy, * vz;
595 double * fx, * fy, * fz;
596 int * ix, * iy, * iz;
599 double rho=pow(1./1.05,3), rc2 = 1.12246, vir, vir_old, V;
600 double PE, KE, TE, ecor, ecut, T0=1.0, TE0, T=1.0;
601 double rr3,dt=0.001, dt2;
603 int nSteps = 10, fSamp=100;
606 double langevin_gamma=0;
611 char * wrt_code_str =
"w";
612 char * init_cfg_file = NULL;
616 unsigned long int Seed = 23410981;
620 for (i=1;i<argc;i++) {
621 if (!strcmp(argv[i],
"-N")) N=atoi(argv[++i]);
622 else if (!strcmp(argv[i],
"-rho")) rho=atof(argv[++i]);
623 else if (!strcmp(argv[i],
"-dt")) dt=atof(argv[++i]);
624 else if (!strcmp(argv[i],
"-rc")) rc2=atof(argv[++i]);
625 else if (!strcmp(argv[i],
"-ns")) nSteps = atoi(argv[++i]);
626 else if (!strcmp(argv[i],
"-T0")) T0=atof(argv[++i]);
627 else if (!strcmp(argv[i],
"-T")) T=atof(argv[++i]);
628 else if (!strcmp(argv[i],
"-sd")) langevin_gamma=atof(argv[++i]);
629 else if (!strcmp(argv[i],
"-dpd")) dpd_gamma=atof(argv[++i]);
630 else if (!strcmp(argv[i],
"-fs")) fSamp=atoi(argv[++i]);
631 else if (!strcmp(argv[i],
"-sf")) wrt_code_str = argv[++i];
632 else if (!strcmp(argv[i],
"-icf")) init_cfg_file = argv[++i];
633 else if (!strcmp(argv[i],
"-ecorr")) use_e_corr = 1;
634 else if (!strcmp(argv[i],
"-seed")) Seed = (
unsigned long)atoi(argv[++i]);
635 else if (!strcmp(argv[i],
"-rvl")) rvl = atof(argv[++i]);
636 else if (!strcmp(argv[i],
"-rlc")) rlc = atof(argv[++i]);
637 else if (!strcmp(argv[i],
"-uf")) unfold = 1;
638 else if ((!strcmp(argv[i],
"-h"))||(!strcmp(argv[i],
"--help"))) {
639 fprintf(stdout,
"mdlj usage:\n");
640 fprintf(stdout,
"mdlj [options]\n\n");
641 fprintf(stdout,
"Options:\n");
642 fprintf(stdout,
"\t -N [integer]\t\tNumber of particles (default %i)\n",N);
643 fprintf(stdout,
"\t -rho [real]\t\tNumber density (default %f)\n",rho);
644 fprintf(stdout,
"\t -dt [real]\t\tTime step (default %f)\n",dt);
645 fprintf(stdout,
"\t -rc [real]\t\tCutoff radius (default %f)\n",rc2);
646 fprintf(stdout,
"\t -ns [real]\t\tNumber of integration steps (default %i)\n",nSteps);
647 fprintf(stdout,
"\t -T0 [real]\t\tInitial temperature (default %f)\n",T0);
648 fprintf(stdout,
"\t -sd [real]\t\tUse Langevin thermostat with frition constant 0=off (default %f)\n",langevin_gamma);
649 fprintf(stdout,
"\t -dpd [real]\t\tUse DPD thermostat with frition constant 0=off (default %f)\n",dpd_gamma);
650 fprintf(stdout,
"\t -T [real]\t\tTemperature of the Langevin thermostat(default %f)\n",T);
651 fprintf(stdout,
"\t -fs [integer]\t\tSample frequency (default %i)\n",fSamp);
652 fprintf(stdout,
"\t -sf [a|w]\t\tAppend or write config output file (default %s)\n",wrt_code_str);
653 fprintf(stdout,
"\t -icf [string]\t\tInitial configuration file (default %s)\n",init_cfg_file);
654 fprintf(stdout,
"\t -seed [integer]\tRandom number generator seed (default %li)\n",Seed);
655 fprintf(stdout,
"\t -rvl [real]\t\tUse neighbor lists with this cutoff (default %f)\n",rvl);
656 fprintf(stdout,
"\t -rlc [read] \t\tUse linked cells with this size (default %f)\n",rlc);
657 fprintf(stdout,
"\t -uf \t\tPrint unfolded coordinates in output files (default %i)\n",unfold);
658 fprintf(stdout,
"\t -h \t\tPrint this info\n");
662 fprintf(stderr,
"Error: Command-line argument '%s' not recognized.\n",
669 L = pow((V=N/rho),0.3333333);
672 rr3 = 1.0/(rc2*rc2*rc2);
673 ecor = use_e_corr?8*M_PI*rho*(rr3*rr3*rr3/9.0-rr3/3.0):0.0;
674 ecut = 4*(rr3*rr3*rr3*rr3-rr3*rr3);
683 fprintf(stdout,
"# NVE MD Simulation of a Lennard-Jones fluid\n");
684 fprintf(stdout,
"# L = %.5lf; rho = %.5lf; N = %i; rc = %.5lf\n",
686 fprintf(stdout,
"# nSteps %i, seed %li, dt %.5lf\n", nSteps,Seed,dt);
690 if (( rvl > 0 ) || ( rlc > 0 )){
700 fprintf(stderr,
"-rvl must be bigger than -rc\n");
703 fprintf(stdout,
"# using Verlet lists with cutoff %.5f\n",nblist->
vl->
cutoff);
705 nblist->
vl->
skin2 = pow(rvl-sqrt(rc2),2);
708 nblist->
vl->
head = (
int *)malloc(N*
sizeof(
int));
712 nblist->
vl->
rx0 = (
double*)malloc(N*
sizeof(
double));
713 nblist->
vl->
ry0 = (
double*)malloc(N*
sizeof(
double));
714 nblist->
vl->
rz0 = (
double*)malloc(N*
sizeof(
double));
720 nblist->
lc->
ncells=(int)floor(L/rlc);
733 fprintf(stderr,
"-rlc must be bigger than -rc\n");
736 fprintf(stdout,
"# using Linked cell lists with grid %i x %i x %i (cufoff %f)\n",nblist->
lc->
ncells,nblist->
lc->
ncells,nblist->
lc->
ncells,nblist->
lc->
lcell);
737 nblist->
lc->
neighbors = (
int *)malloc(N*
sizeof(
int));
742 nblist->
lc->
rx0 = (
double*)malloc(N*
sizeof(
double));
743 nblist->
lc->
ry0 = (
double*)malloc(N*
sizeof(
double));
744 nblist->
lc->
rz0 = (
double*)malloc(N*
sizeof(
double));
746 nblist->
vl->
id_head = (
int *)malloc(N*
sizeof(
int));
748 nblist->
vl->
head = (
int *)realloc(nblist->
vl->
head,(N+1)*
sizeof(int));
753 fprintf(stdout,
"# no neighbor lists\n");
756 double langevin_const = 0;
757 if (langevin_gamma > 0) {
758 fprintf(stdout,
"# using Langevin thermostat for T=%f with gamma=%f\n",T,langevin_gamma);
759 langevin_const = sqrt(24.0*T*langevin_gamma/dt);
760 if (dpd_gamma > 0 ) {
761 fprintf(stderr,
"# error: dpd and langevin thermostat cannot be enable at the same time\n");
770 rx = (
double*)malloc(N*
sizeof(
double));
771 ry = (
double*)malloc(N*
sizeof(
double));
772 rz = (
double*)malloc(N*
sizeof(
double));
775 ix = (
int*)malloc(N*
sizeof(
int));
776 iy = (
int*)malloc(N*
sizeof(
int));
777 iz = (
int*)malloc(N*
sizeof(
int));
780 vx = (
double*)malloc(N*
sizeof(
double));
781 vy = (
double*)malloc(N*
sizeof(
double));
782 vz = (
double*)malloc(N*
sizeof(
double));
785 fx = (
double*)malloc(N*
sizeof(
double));
786 fy = (
double*)malloc(N*
sizeof(
double));
787 fz = (
double*)malloc(N*
sizeof(
double));
793 dpd->
gamma = dpd_gamma;
795 dpd->
prefactor = sqrt(24.0*T*dpd_gamma/dt);
803 init(rx,ry,rz,vx,vy,vz,ix,iy,iz,&N,L,T0,&KE,init_cfg_file);
804 sprintf(fn,
"%i.xyz",0);
806 xyz_out(out,rx,ry,rz,vx,vy,vz,ix,iy,iz,L,N,16,1,unfold);
821 dpd->
gamma = dpd_gamma * sqrt(3);
822 PE =
total_e(rx,ry,rz,fx,fy,fz,N,L,nblist,dpd,rc2,ecor,ecut,&vir_old);
823 dpd->
gamma = dpd_gamma;
825 PE =
total_e(rx,ry,rz,fx,fy,fz,N,L,nblist,dpd,rc2,ecor,ecut,&vir_old);
831 if (langevin_gamma > 0) {
833 fx[i]+= -langevin_gamma*vx[i] + langevin_const*sqrt(3)*(drand48()-0.5);
834 fy[i]+= -langevin_gamma*vy[i] + langevin_const*sqrt(3)*(drand48()-0.5);
835 fz[i]+= -langevin_gamma*vz[i] + langevin_const*sqrt(3)*(drand48()-0.5);
839 fprintf(stdout,
"# step time PotE KinE TotE Tdrift T P\n");
841 for (s=0;s<nSteps;s++) {
845 rx[i]+=vx[i]*dt+0.5*dt2*fx[i];
846 ry[i]+=vy[i]*dt+0.5*dt2*fy[i];
847 rz[i]+=vz[i]*dt+0.5*dt2*fz[i];
852 if (rx[i]<0.0) { rx[i]+=L; ix[i]--; }
853 if (rx[i]>L) { rx[i]-=L; ix[i]++; }
854 if (ry[i]<0.0) { ry[i]+=L; iy[i]--; }
855 if (ry[i]>L) { ry[i]-=L; iy[i]++; }
856 if (rz[i]<0.0) { rz[i]+=L; iz[i]--; }
857 if (rz[i]>L) { rz[i]-=L; iz[i]++; }
881 PE =
total_e(rx,ry,rz,fx,fy,fz,N,L,nblist,dpd,rc2,ecor,ecut,&vir);
884 if (langevin_gamma > 0) {
886 fx[i]+= -langevin_gamma*vx[i] + langevin_const*(drand48()-0.5);
887 fy[i]+= -langevin_gamma*vy[i] + langevin_const*(drand48()-0.5);
888 fz[i]+= -langevin_gamma*vz[i] + langevin_const*(drand48()-0.5);
898 KE+=vx[i]*vx[i]+vy[i]*vy[i]+vz[i]*vz[i];
902 fprintf(stdout,
"%i %.5lf %.5lf %.5lf %.5lf %.5le %.5lf %.5lf\n",
903 s,s*dt,PE,KE,TE,(TE-TE0)/TE0,KE*2/3./N,rho*KE*2./3./N+vir/3.0/V);
905 sprintf(fn,
"%i.xyz",!strcmp(wrt_code_str,
"a")?0:s);
906 out=fopen(fn,wrt_code_str);
907 xyz_out(out,rx,ry,rz,vx,vy,vz,ix,iy,iz,L,N,16,1,unfold);
915 free(nblist->
lc->
rx0);
916 free(nblist->
lc->
ry0);
917 free(nblist->
lc->
rz0);
926 free(nblist->
vl->
rx0);
927 free(nblist->
vl->
ry0);
928 free(nblist->
vl->
rz0);
void calc_dpd(int i, int j, double dx, double dy, double dz, double r2, double *fx, double *fy, double *fz, dpd_t *dpd)
calculates dpd force between two particles
int ncells
number of cell in each direction
int ncells2
square of number of cell in each direction
double cutoff
verlet list cutoff
double * rx0
array of x-coordinate of the old position of all particles
int update
if verlet list should be updated
int update
if verlet list should be updated
int right
if there is a neighbor on the right
int main(int argc, char *argv[])
double * vx
array of x-coordinate of the velocity of all particles
void init(double *rx, double *ry, double *rz, double *vx, double *vy, double *vz, int *ix, int *iy, int *iz, int *N, double L, double T0, double *KE, char *icf)
int ncells3
total of number of cells (ncells**3)
double per_dist2(int i, int j, double *rx, double *ry, double *rz, double *dx, double *dy, double *dz, double L)
calculates periodic distance between two particles
double drand_gaussian(double mean, double sigma)
generate gaussian random number generate a gaussian random number using the Box-Muller method ...
contains all information about the linked cell list
void xyz_out(FILE *fp, double *rx, double *ry, double *rz, double *vx, double *vy, double *vz, int *ix, int *iy, int *iz, double L, int N, int z, int put_vel, int unfold)
contains all information about the verlet list
int * head
point to first neighboring particles of the ith particle
int * neighbors
list of all neighboring paricles
double max_moved_distance2(double *rx, double *ry, double *rz, int N, double *rx0, double *ry0, double *rz0)
calculates the max distance a particle has moved
int * neighbors
list of all neighboring paricles
double lcell
length of a cell (effective cutoff)
int left
if there is a neighbor on the left
double * ry0
array of y-coordinate of the old position of all particles
double skin2
square of the verlet list skin (list cutoff - lj cutoff)
int * head
point to first neighboring particles of the ith cell
double * rx0
array of x-coordinate of the old position of all particles
int * id_head
particle id of particle in head needed in combination with linked cell
int xyz_in(FILE *fp, double *rx, double *ry, double *rz, double *vx, double *vy, double *vz, int *N)
lclist_t * lc
pointer to linked cell list struct
double * ry0
array of y-coordinate of the old position of all particles
double skin2
square of the linked cell list skin (list cutoff - lj cutoff)
vlist_t * vl
pointer to verlet list struct
double cutoff2
square of the verlet list cutoff
int size
size of neighbors array
void calc_lj(int i, int j, double dx, double dy, double dz, double r2, double *fx, double *fy, double *fz, double rc2, double ecut, double *vir, double *e)
calculates Lennard-Jones interaction between two particles
contains all information about the neighbor list
double * vz
array of z-coordinate of the velocity of all particles
contains all information about the dpd thermostat
double prefactor
dpd constant = sqrt(24.0*T*gamma/dt)
double total_e(double *rx, double *ry, double *rz, double *fx, double *fy, double *fz, int N, double L, nblist_t *nblist, dpd_t *dpd, double rc2, double ecor, double ecut, double *vir)
algorithm for computing forces and potential energy. algorithm for computing forces and potential ene...
double * rz0
array of z-coordinate of the old position of all particles
void save_positions(double *rx, double *ry, double *rz, int N, double *rx0, double *ry0, double *rz0)
save current positions
double * vy
array of y-coordinate of the velocity of all particles
double * rz0
array of z-coordinate of the old position of all particles
double cutoff
list cutoff, round up from user input
double cutoff2
square of the cutoff
double gamma
friction parameter