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);
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
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)
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
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
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