4

I am going ahead with asking what might appear as a debugging question. But,I am looking for something conceptual that I might have missed, and this question is somewhat related to my previous question: NVE MD simulation of inert gas: Problem maintaining equilibrium, although a different issue now. If the moderators decide to close this, I understand.

I am doing a constant energy (NVE) simulation of 49 Argon particles in a 100x100 2D box with Lennard Jones potential at temperature 240 K I am using the following:

1) Unit system: Natural unit system such that mass $m=1$, LJ parameters, $\sigma=1$, $\epsilon=1$, Boltzmann constant $k=1$ such that temperatureof 120 K is 1.

2) Initial Conditions: Square lattice position, Maxwell-Boltzmann velocities

3) Integration: Velocity-verlet with periodic boundary conditions. Time step of 0.001 (2fs in actual time)

4) I am checking for occurrence of a non-zero mean velocity (flying ice cubes): It does not occur.

I am unable to keep energy conservation within 1% for more than 2000 time steps (total actual time of 4ps). Most studies, lecture notes, online tutorials,etc., seem to be using these same values for time step, parameters, etc. While these never say how long they are able to conserve energy (and within what accuracy) I find research papers do 10ns on an average. I am failing 3 orders below. Velocity verlet seems like a fairly-accepted algorithm at least for something so simple!

It doesn't seem like a basic coding (i.e.,non-conceptual) mistake since the code does well until it gets to around 4ps. Some runs I can go upto 6 or 7ps, just lucky initial conditions I guess. Any helpful suggestions on where I could be going wrong? Thanks.


Update: 1) The error doesn't seem to scale with time-step $\Delta t$. Most papers seem to use $\Delta t$ =0.001, I have tried the range from 1e-2 to 1e-5.

2) My integrator code looks like this: { while(t

  //Energy Calculation
  Ven(t)=ven;
  KE(U,V,ken,N);
  Ken(t)=ken;
  if(t==0)
{
  Hen1=Ken(0)+Ven(0);
  cout<<"Total energy at t=0  is: "<<Hen1<<endl;
}

  //Error Checking
  ErrMeanVel=(U.sum())/N;
  ErrEConserve=(abs(Ken(t)+Ven(t)-Hen1)*100)/Hen1;
  if(ErrMeanVel>1e-6)
{
  cout<<"Flying ice cube at t="<<t*Deltat<<"ps. The mean velocity is"<<ErrMeanVel<<endl;
  break;
}
  if(ErrEConserve>ETol)
    {
      cout<<"Energy conservation violated at t="<<t*Deltat<<"ps. The energy at this time is "<<(Ken(t)+Ven(t))<<" and the percentage error is "<<((abs(Ken(t)+Ven(t)-Hen1)*100)/Hen1)<<endl;
      break;
    }

  //Velocity Verlet
  for (i=0;i<N;i++)
{
  X(0,i)=X(0,i)+(U(0,i)*Deltat)+0.5*Ax(i)*Deltat*(Deltat/mass);
  Y(0,i)=Y(0,i)+(V(0,i)*Deltat)+0.5*Ay(i)*Deltat*(Deltat/mass);
  U(0,i)=U(0,i)+(0.5*Ax(i)*Deltat/mass);
  V(0,i)=V(0,i)+(0.5*Ay(i)*Deltat/mass);
}
  LJ(X,Y,N,ven,Fx,Fy,ctr);
  Ax=Fx.rowwise().sum();
  Ay=Fy.rowwise().sum();
  for (i=0;i<N;i++)
    {
      U(0,i)=U(0,i)+(0.5*Ax(i)*Deltat/mass);
      V(0,i)=V(0,i)+(0.5*Ay(i)*Deltat/mass);
    }
  //Boundary Conditions      
  PeriodicBoundary(X,Y,L,N);
  t++;
}

\Force calculator is: (no cutoff)

 int i=0, j=0;
  double dx=0, dy=0,r2=0,F6=0,F12=0,F=0,Vcut=0;
  fx=MatrixXd::Zero(n,n);
  fy=MatrixXd::Zero(n,n);
  ven=0;
  MatrixXd ft(n,n);
  for (j=0;j<n;j++)
    {
      for(i=j+1;i<n;i++)
    {
      dx=(a(0,j)-a(0,i));
      dy=(b(0,j)-b(0,i));
      r2=dx*dx+dy*dy;
      if(r2<sigma)
        {
          ctr++;
        }
      F6=pow((sigma*sigma/r2),3);
      F12=pow((sigma*sigma/r2),6);
      F=(24*epsilon/r2)*(F6-2*F12);
      ven=ven+4*epsilon*(F12-F6);
      fx(i,j)=F*dx;
      fy(i,j)=F*dy;
    }
    }
  ft=fx.transpose();
  fx=fx-ft;
  ft=fy.transpose();
  fy=fy-ft;
}
Sankaran
  • 215
  • 1
  • 5
  • Can you post the code for your integrator? – Juan M. Bello-Rivas Feb 22 '13 at 03:31
  • Have you done an error analysis to estimate what energy drift you should expect given machine precision? What happens when you reduce $\Delta t$ to 0.0001? – Deathbreath Feb 22 '13 at 19:52
  • @Juan and Deathbreath: I have updated my question based on your comments. – Sankaran Feb 23 '13 at 19:01
  • Glad to see you're progressing with your simulations! Could you try plotting both the potential and kinetic energy for each time step? Both curves should appear smooth. If, however, they have jumps, they will at least tell you where and when your code is going wrong. – Pedro Feb 23 '13 at 19:28
  • Ok, forget my last comment, the bug is in F=(24*epsilon/r2)*(F6-2*F12). You should be dividing by $r$, not $r^2$. The mismatch between the energy function and its derivative is most probably what's causing you problems with the total energy. – Pedro Feb 23 '13 at 20:22
  • Furthermore, you don't seem to be enforcing boundary conditions when computing dx and dy... – Pedro Feb 23 '13 at 20:46
  • Hi Pedro. Thanks for looking at this again. r2 is the $r^2$ but I am multiplying by dx for taking force components (cos and sin for components which will bring the additional r). And the boundary conditions are enforced after every step. When evaluating $dx$ and $dy$ I am only calculating distances between particles, so I don't understand your second comment – Sankaran Feb 23 '13 at 20:51
  • Ok, sorry about the $r^2$ comment then, I missed that bit. You need to enforce the boundary conditions when computing dx and dy to account for particles that interact over the periodic boundary. Imagine two particles at opposite ends of the domain: In your current setup they won't interact, but as soon as one of them moves slightly and crosses the boundary, they will all of a sudden see each other. Or how are you enforcing the boundary conditions? – Pedro Feb 23 '13 at 21:21
  • Hmm. Yes you are right. Right now two particles at two ends are interacting weakly (I have no cut off in my potential) but when one crosses over there will be a jump. But if I account for that I guess I am calculating two forces for the same pair! Is that right ? I guess that's the whole point of periodic BC. But then that means if I want to do no cutoff I will have an infinite loop, because I can take as many periods. Technically I have to introduce some cutoff. – Sankaran Feb 23 '13 at 21:35
  • @Sankaran: Keep in mind that as of a certain distance the potential will be orders of magnitude smaller than the error introduced by the time integration. Most simulations just use what's referred to as the minimum image convention. – Pedro Feb 23 '13 at 21:40
  • That makes perfect sense! Let me do this and get back. Thanks – Sankaran Feb 23 '13 at 21:48
  • @Pedro Initial response: My code likes it. But I will try various starting conditions, no.of particles etc. and check. Could you write this as an answer so I can give you credit? Thanks! – Sankaran Feb 23 '13 at 22:55

2 Answers2

8

This is a re-formulation of my comments above as an answer.

You need to enforce the boundary conditions when computing dx and dy to account for particles that interact over the periodic boundary. Imagine two particles at opposite ends of the domain: In your current setup they won't interact, but as soon as one of them moves slightly and crosses the boundary, they will all of a sudden see each other.

Most simulations just use what's referred to as the minimum image convention.

Pedro
  • 9,573
  • 1
  • 36
  • 45
  • Interestingly I can conserve energy below 0.01% for say 49 molecules or 100 molecules, but can't for fewer molecules. I can conserve better energy for higher temperatures, i.e., error is less significant in comparison with kinetic energies. That seems about right. What do you think? – Sankaran Feb 25 '13 at 03:33
  • 2
    @Sankaran: I'd recommend you test your code with just two atoms interacting and/or moving across the periodic boundaries, keeping an eye on both the potential and kinetic energies. If you see a jump in either anywhere, you can then trace it back to what actually happened, e.g. a particle moving across a boundary, within or outside of a cutoff distance, etc... – Pedro Feb 25 '13 at 10:49
2

Two thoughts

A) A certain degree of energy dissipation in MD simulations is considered normal and can be counterbalanced with so called thermostat algorithms e.g. this. In your particular case I can not say wheter the ammount of dissipation you have is to be expected in your setup, or result of some bug.

B) The Lennard Jones potential is very steep when particles are near each other and diminishes fast when they are apart. That means that upon collision you would need to have very small timesteps to get reasonable results. Have you tried running your simulation with smaller timesteps just to eliminate the possiblilty that it's simply the temporal resolution?

MPIchael
  • 2,935
  • 10
  • 19