+/*
+ * numerical tricks
+ */
+
+/* verlet list */
+
+int verlet_list_init(t_moldyn *moldyn) {
+
+ int i,fd;
+
+ fd=open("/dev/null",O_WRONLY);
+
+ for(i=0;i<moldyn->count;i++)
+ list_init(&(moldyn->atom[i].verlet),fd);
+
+ moldyn->r_verlet=1.1*moldyn->cutoff;
+ /* +moldyn->tau*\
+ sqrt(3.0*K_BOLTZMANN*moldyn->t/moldyn->atom[0].mass); */
+
+ printf("debug: r verlet = %.15f\n",moldyn->r_verlet);
+ printf(" r cutoff = %.15f\n",moldyn->cutoff);
+ printf(" dim = %.15f\n",moldyn->dim.x);
+
+ /* make sure to update the list in the beginning */
+ moldyn->dr_max1=moldyn->r_verlet;
+ moldyn->dr_max2=moldyn->r_verlet;
+
+ return 0;
+}
+
+int link_cell_init(t_moldyn *moldyn) {
+
+ t_linkcell *lc;
+
+ lc=&(moldyn->lc);
+
+ /* partitioning the md cell */
+ lc->nx=moldyn->dim.x/moldyn->cutoff;
+ lc->x=moldyn->dim.x/lc->nx;
+ lc->ny=moldyn->dim.y/moldyn->cutoff;
+ lc->y=moldyn->dim.y/lc->ny;
+ lc->nz=moldyn->dim.z/moldyn->cutoff;
+ lc->z=moldyn->dim.z/lc->nz;
+
+ lc->subcell=malloc(lc->nx*lc->ny*lc->nz*sizeof(t_list));
+
+ link_cell_update(moldyn);
+
+ return 0;
+}
+
+int verlet_list_update(t_moldyn *moldyn) {
+
+ int i,j;
+ t_3dvec d;
+ t_atom *atom;
+
+ atom=moldyn->atom;
+
+ puts("debug: list update start");
+
+ for(i=0;i<moldyn->count;i++) {
+ list_destroy(&(atom[i].verlet));
+ for(j=0;j<moldyn->count;j++) {
+ if(i!=j) {
+ v3_sub(&d,&(atom[i].r),&(atom[j].r));
+ v3_per_bound(&d,&(moldyn->dim));
+ if(v3_norm(&d)<=moldyn->r_verlet)
+ list_add_immediate_ptr(&(atom[i].verlet),&(atom[j]));
+ }
+ }
+ }
+
+ moldyn->dr_max1=0.0;
+ moldyn->dr_max2=0.0;
+
+ puts("debug: list update end");
+
+ return 0;
+}
+
+int link_cell_update(t_moldyn *moldyn) {
+
+ int count,i,j,k;
+ int nx,ny,nz;
+ t_atom *atom;
+
+ atom=moldyn->atom;
+ nx=moldyn->lc.nx; ny=moldyn->lc.ny; nz=moldyn->lc.nz;
+
+ for(i=0;i<nx*ny*nz;i++)
+ list_destroy(&(moldyn->lc.subcell[i]));
+
+ for(count=0;count<moldyn->count;count++) {
+ for(i=0;i<nx;i++) {
+ if((atom[count].r.x>=i*moldyn->dim.x) && \
+ (atom[count].r.x<(i+1)*moldyn->dim.x))
+ break;
+ }
+ for(j=0;j<ny;j++) {
+ if((atom[count].r.y>=j*moldyn->dim.y) && \
+ (atom[count].r.y<(j+1)*moldyn->dim.y))
+ break;
+ }
+ for(k=0;k<nz;k++) {
+ if((atom[count].r.z>=k*moldyn->dim.z) && \
+ (atom[count].r.z<(k+1)*moldyn->dim.z))
+ break;
+ }
+ list_add_immediate_ptr(&(moldyn->lc.subcell[i+j*nx+k*nx*ny]),
+ &(atom[count]));
+ }
+
+ return 0;
+}
+
+int verlet_list_shutdown(t_moldyn *moldyn) {
+
+ int i;
+
+ for(i=0;i<moldyn->count;i++)
+ list_shutdown(&(moldyn->atom[i].verlet));
+
+ return 0;
+}
+
+int link_cell_shutdown(t_moldyn *moldyn) {
+
+ int i;
+ t_linkcell *lc;
+
+ lc=&(moldyn->lc);
+
+ for(i=0;i<lc->nx*lc->ny*lc->nz;i++)
+ list_shutdown(&(moldyn->lc.subcell[i]));
+
+ return 0;
+}