#include "layers.h"

int displace() {

  int    j,idx;

  double nx,ny,nz;
  double sqdr,rsqdr,rdr6;
  double dx,dy,dz;
  double E0,E1,V0,V1;
  double sqcutoff = cutoff*cutoff;
  double adLxh = 2.0 / Lx;
  double adLyh = 2.0 / Ly;
  double adLzh = 2.0 / Lz;
  double sig6 = pow(sigma,6.0);
  double sig12 = pow(sigma,12.0);
  double A = 4.0*epsilon*sig12;
  double B = 4.0*epsilon*sig6;
  double dA = 48.0*epsilon*sig12;
  double dB = 24.0*epsilon*sig6;
  double max1d = maxdisp/sqrt(3.0);
  double dE, dV;

  /* ... return if number of sites is zero ... */

  if(nsites<1) {
    dEdisp=0.0;
    dVdisp=0.0;
    return(0);
  }

  if(SHIFT) {
    dE = - EshiftpIA;
    dV = - VshiftpIA;
  } else {
    dE = 0.0;
    dV = 0.0;
  }

  E0 = 0.0;
  E1 = 0.0;
  V0 = 0.0;
  V1 = 0.0;

  ndisptried++;

  idx = (int)(nsites*((double)rand()/RAND_MAX));

  nx = x[idx];
  ny = y[idx];
  nz = z[idx];

  for(j=0;j<idx;j++) {

      dx = x[j]-nx;
      dy = y[j]-ny;
      dz = z[j]-nz;
      dx -= Lx * (int)(dx * adLxh);
      dy -= Ly * (int)(dy * adLyh);
      dz -= Lz * (int)(dz * adLzh);

      sqdr = dx*dx+dy*dy+dz*dz;

      if(sqdr<sqcutoff) {

        rsqdr = 1.0/sqdr;
        rdr6  = rsqdr*rsqdr*rsqdr;
        E0   += A * rdr6 * rdr6 - B * rdr6 + dE;
        V0   -= -dA * rdr6 * rdr6 + dB * rdr6 + dV;
      }
  }

  for(j=idx+1;j<nsites;j++) {

      dx = x[j]-nx;
      dy = y[j]-ny;
      dz = z[j]-nz;
      dx -= Lx * (int)(dx * adLxh);
      dy -= Ly * (int)(dy * adLyh);
      dz -= Lz * (int)(dz * adLzh);

      sqdr = dx*dx+dy*dy+dz*dz;

      if(sqdr<sqcutoff) {

        rsqdr = 1.0/sqdr;
        rdr6  = rsqdr*rsqdr*rsqdr;
        E0   += A * rdr6 * rdr6 - B * rdr6 + dE;
        V0   -= -dA * rdr6 * rdr6 + dB * rdr6 + dV;
      }
  }

  nx = x[idx] + max1d * 2.0*(0.5-((double)rand()/RAND_MAX));
  ny = y[idx] + max1d * 2.0*(0.5-((double)rand()/RAND_MAX));
  nz = z[idx] + max1d * 2.0*(0.5-((double)rand()/RAND_MAX));
  nx -= Lx * (int)(nx * adLxh);
  ny -= Ly * (int)(ny * adLyh);
  nz -= Lz * (int)(nz * adLzh);

  for(j=0;j<idx;j++) {

      dx = x[j]-nx;
      dy = y[j]-ny;
      dz = z[j]-nz;
      dx -= Lx * (int)(dx * adLxh);
      dy -= Ly * (int)(dy * adLyh);
      dz -= Lz * (int)(dz * adLzh);

      sqdr = dx*dx+dy*dy+dz*dz;

      if(sqdr<sqcutoff) {

        rsqdr = 1.0/sqdr;
        rdr6  = rsqdr*rsqdr*rsqdr;
        E1   += A * rdr6 * rdr6 - B * rdr6 + dE;
        V1   -= -dA * rdr6 * rdr6 + dB * rdr6 + dV;
      }
  }

  for(j=idx+1;j<nsites;j++) {

      dx = x[j]-nx;
      dy = y[j]-ny;
      dz = z[j]-nz;
      dx -= Lx * (int)(dx * adLxh);
      dy -= Ly * (int)(dy * adLyh);
      dz -= Lz * (int)(dz * adLzh);

      sqdr = dx*dx+dy*dy+dz*dz;

      if(sqdr<sqcutoff) {

        rsqdr = 1.0/sqdr;
        rdr6  = rsqdr*rsqdr*rsqdr;
        E1   += A * rdr6 * rdr6 - B * rdr6 + dE;
        V1   -= -dA * rdr6 * rdr6 + dB * rdr6 + dV;
      }
  }

  if(exp(-beta*(E1-E0)) > ((double)rand()/RAND_MAX)) {

    x[idx] = nx;
    y[idx] = ny;
    z[idx] = nz;

    ndispacpt++;

    dEdisp = E1-E0;
    dVdisp = V1-V0;

  } else {

    dEdisp = 0.0;
    dVdisp = 0.0;

  }

  return(1);
}
