#include "layers.h"

int modn(void) {

  int i,j,idx,OL;

  double rd,rx,ry,rz,dvx,dvy,dvz,sqrtktom;
  double sqdr,rsqdr,rdr6;
  double dx,dy,dz;
  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 pdelete, pcreate;
  double dE,dV;
  static double E1,V1;

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

  E1 = 0.0;
  V1 = 0.0;

/******************************************************************/
/* decide whether to attempt deletion or insertion of a particle  */
/******************************************************************/

  rd = ((double)rand()/RAND_MAX);

  if(rd>=0.5) {

/******************************************************************/
/* choose a random position in the box and calculate energy of    */
/* inserted particle E1                                           */
/******************************************************************/

    ncreatried ++;

    rx = 0.5*Lx-Lx*((double)rand()/RAND_MAX);
    ry = 0.5*Ly-Ly*((double)rand()/RAND_MAX);
    rz = 0.5*Lz-Lz*((double)rand()/RAND_MAX);

    OL = 0;
    i = 0;

    do {

      dx = x[i]-rx;
      dy = y[i]-ry;
      dz = z[i]-rz;
      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) {
        if(sqdr<sigma*sigma*0.25) OL = 1;
        else {

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

      }

      i++;
 
    } while(i<nsites && !OL);

    if(LRC) { 
      E1 += Elrc * (double)(2*nsites+1);
      V1 += Vlrc * (double)(2*nsites+1);
    }

/******************************************************************/
    if(!OL) pcreate = exp(BA-beta*E1) / ((double)nsites+1.0);
    else    pcreate = -1,0;
/******************************************************************/

    if( pcreate >= ((double)rand()/RAND_MAX)) {

      x[nsites] = rx;
      y[nsites] = ry;
      z[nsites] = rz;

      if(GCMD && RELAX && E1 > 0.001*Rgas*Tsoll) 
        relax(&E1,&V1);

      if(ASSVEL) {

        sqrtktom = sqrt(0.001*Rgas*Tsoll/m);
        dvx = gauss_rand()*sqrtktom*deltat;
        dvy = gauss_rand()*sqrtktom*deltat;
        dvz = gauss_rand()*sqrtktom*deltat;

        xo[nsites] = x[nsites]+dvx;
        yo[nsites] = y[nsites]+dvy;
        zo[nsites] = z[nsites]+dvz;

      } else {

        xo[nsites] = x[nsites];
        yo[nsites] = y[nsites];
        zo[nsites] = z[nsites];

      }

      nsites++;
      Ndegfree += 3;
      ncreaacpt++;

      dEmodn = E1;
      dVmodn = V1;

    } else { 

      dEmodn = 0.0;
      dVmodn = 0.0;

    }

  } else {

    ndeletried ++;

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

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

      dx = x[j]-x[idx];
      dy = y[j]-y[idx];
      dz = z[j]-z[idx];
      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]-x[idx];
      dy = y[j]-y[idx];
      dz = z[j]-z[idx];
      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(LRC) { 
      E1 += Elrc * (double)(2*nsites-1);
      V1 += Vlrc * (double)(2*nsites-1);
    }

/******************************************************************/
    pdelete = ((double)nsites) * exp(beta*E1-BA);
/******************************************************************/

    if( pdelete > ((double)rand()/RAND_MAX) ) {

      if(idx==nsites-1) {
        nsites--;
// uuu !!!
        Ndegfree -= 3;
        ndeleacpt++;
// ...
      } else {
        x[idx]=x[nsites-1];
        y[idx]=y[nsites-1];
        z[idx]=z[nsites-1];
        xo[idx]=xo[nsites-1];
        yo[idx]=yo[nsites-1];
        zo[idx]=zo[nsites-1];
        nsites--;
        Ndegfree -= 3;
        ndeleacpt++;
      } 

      dEmodn = -E1;
      dVmodn = -V1;

    } else { 

      dEmodn = 0.0;
      dVmodn = 0.0;

    }

  }

  return(1);
}
