- for(i=0;i<count;i++) {
- /* reset force */
- v3_zero(&(atom[i].f));
-
- /* determine cell + neighbours */
- ni=(atom[i].r.x+(moldyn->dim.x/2))/lc->x;
- nj=(atom[i].r.y+(moldyn->dim.y/2))/lc->y;
- nk=(atom[i].r.z+(moldyn->dim.z/2))/lc->z;
- c=link_cell_neighbour_index(moldyn,ni,nj,nk,neighbour);
-
- /*
- * processing cell of atom i
- * => no need to check for empty list (1 element at minimum)
- */
- this=&(neighbour[0]);
- list_reset(this);
- do {
- btom=this->current->data;
- if(btom==&(atom[i]))
- continue;
- v3_sub(&distance,&(atom[i].r),&(btom->r));
- d=v3_norm(&distance);
- if(d<=moldyn->cutoff) {
- u+=(0.5*sc*(d-equi_dist)*(d-equi_dist));
- v3_scale(&force,&distance,
- -sc*(1.0-(equi_dist/d)));
- v3_add(&(atom[i].f),&(atom[i].f),&force);
- }
- } while(list_next(this)!=L_NO_NEXT_ELEMENT);
-
- /*
- * direct neighbour cells
- * => no boundary condition check necessary
- */
- for(j=1;j<c;j++) {
- this=&(neighbour[j]);
- list_reset(this); /* there might not be a single atom */
- if(this->start!=NULL) {
-
- do {
- btom=this->current->data;
- v3_sub(&distance,&(atom[i].r),&(btom->r));
- d=v3_norm(&distance);
- if(d<=moldyn->cutoff) {
- u+=(0.5*sc*(d-equi_dist)*(d-equi_dist));
- v3_scale(&force,&distance,
- -sc*(1.0-(equi_dist/d)));
- v3_add(&(atom[i].f),&(atom[i].f),
- &force);
- }
- } while(list_next(this)!=L_NO_NEXT_ELEMENT);
-
- }
- }
-
- /*
- * indirect neighbour cells
- * => check boundary conditions
- */
- for(j=c;j<27;j++) {
- this=&(neighbour[j]);
- list_reset(this); /* check boundary conditions */
- if(this->start!=NULL) {
-
- do {
- btom=this->current->data;
- v3_sub(&distance,&(atom[i].r),&(btom->r));
- v3_per_bound(&distance,&(moldyn->dim));
- d=v3_norm(&distance);
- if(d<=moldyn->cutoff) {
- u+=(0.5*sc*(d-equi_dist)*(d-equi_dist));
- v3_scale(&force,&distance,
- -sc*(1.0-(equi_dist/d)));
- v3_add(&(atom[i].f),&(atom[i].f),
- &force);
- }
- } while(list_next(this)!=L_NO_NEXT_ELEMENT);
-
- }
- }
+ v3_sub(&distance,&(ai->r),&(aj->r);
+
+ v3_per_bound(&distance,&(moldyn->dim));
+ if(bc) check_per_bound(moldyn,&distance);
+ d=v3_norm(&distance);
+ if(d<=moldyn->cutoff) {
+ /* energy is 1/2 (d-d0)^2, but we will add this twice ... */
+ moldyn->energy+=(0.25*sc*(d-equi_dist)*(d-equi_dist));
+ v3_scale(&force,&distance,-sc*(1.0-(equi_dist/d)));
+ v3_add(&(ai->f),&(ai->f),&force);