C 中 Lennard-Jones 势的 MD 模拟错误,导致缺乏能量守恒

计算科学 模拟 C 分子动力学
2021-12-04 14:30:44

我正在使用Lennard-Jones 势Velocity Verlet算法进行 MD 模拟。代码编译运行,但每个时间步的能量不守恒;它在运行时不断减小。势能的大小远大于动能的大小,但我一直无法检测到错误在哪里。

感谢您提供的任何帮助!

#include <stdio.H>    
#include <math.H>
#include <stdlib.H>
struct particle
{
    double x[3],v[3],a[3];
};

double sigma, epsilon, m, dt;
#define N 1000
struct particle particles[N];

double rfinder(int id_a, int id_b)
{
    int i;
    double rtot,dist,dist2;
    dist2 = 0;
    for(i=0;i<3;i++)
    {
        dist = particles[id_a].x[i] - particles[id_b].x[i];
        dist2 += dist * dist;
    }
    rtot = sqrt(dist2);
    return rtot;
}

double calcacceleration()
{
    int b,c,i;
    double dist,r,r7,r13,sigma6,sigma12, r12, sor6, sor12, pe;
    pe = 0;
    for(b=0;b<N;b++)
    {
        for(i=0;i<3;i++)
        {
            particles[b].a[i] = 0;
        }
    }

    for(b=0;b<N;b++)
    {
        for(c=0;c<N;c++)
        {
            if(b!=c)
            {
                double dist2;
                dist2 = 0;
                for(i=0;i<3;i++)
                {
                    dist = particles[b].x[i] - particles[c].x[i];
                    dist2 += dist * dist;
                }
                if (dist2<8*8)
                {
                    r = sqrt(dist2);
                    //printf("%d %d %f\n",b,c,r);
                    double rinv = 1.0/r;
                    double r2 = rinv*rinv;
                    double r4 = r2*r2;
                    double r6 = r4 * r2;
                    r7 = r4*r2*rinv;
                    r13 = r7*r4*r2;
                    r12 = r6 * r6;
                    sigma6 = sigma*sigma*sigma*sigma*sigma*sigma;
                    sigma12 = sigma6*sigma6;
                    sor6 = sigma6*r6;
                    sor12 = sigma12*r12;
                    for(i=0;i<3;i++)
                    {
                        dist = particles[b].x[i] - particles[c].x[i];
                        particles[b].a[i] += -(0.5 * (4 * epsilon *((-12 * sigma12 * r13) +(6 * sigma6 * r7))) * ((dist/r))/m);
                        particles[c].a[i] +=  (0.5 * (4 * epsilon *((-12 * sigma12 * r13) +(6 * sigma6 * r7))) * ((dist/r))/m);
                        pe += 0.5*(4*epsilon*(sor12 - sor6));
                    }
                }
            }
        }
    }
    return pe;
}

void position_mover()
{
    double x, x0, v;
    int p, i;
    for(p=0;p<N;p++)
    {
        for(i=0;i<3;i++)
        {
            particles[p].x[i] = particles[p].x[i] + (particles[p].v[i] * dt);
        }
    }
    return;
}

double velocity_mover()
{
    double ke;
    int p, i;
    ke = 0;
    for(p=0;p<N;p++)
    {
        for(i=0;i<3;i++)
        {
            particles[p].v[i] = particles[p].v[i] + (0.5 * particles[p].a[i] * dt);
            ke += 0.5 * m * particles[p].v[i] * particles[p].v[i];
        }
    }
    return ke;
}

void output_to_file()
{
int p;
FILE * fp;
fp = fopen("data.xyz", "a");
fprintf(fp,"%d \n\n",N);
for(p=0;p<N;p++)
{
    fprintf(fp,"H %f %f %f\n",particles[p].x[0],particles[p].x[1],particles[p].x[2]);
}
fclose(fp);
}

int main()
{
int p, i, j, k;
double ft,t,pe, ke,te;
sigma = 1;
epsilon = 1;
FILE * fp;
fp = fopen("data.xyz", "w");
fclose(fp);
printf("What timestep would you like?\n");
scanf("%lf", &dt);
printf("In seconds, what is the final time?\n");
scanf("%lf", &ft);
printf("What mass would you like?\n");
scanf("%lf", &m);
p = 0;
//sets initial positions of atoms to be evenly spaced in a 10 * 10 * 10 cube
for(i=0;i<10;i++)
{
    for(j=0;j<10;j++)
    {
        for(k=0;k<10;k++)
        {
            particles[p].x[0] = i*2;
            particles[p].x[1] = j*2;
            particles[p].x[2] = k*2;
            p++;
        }
    }
}

/*sets initial velocities and accelerations of atoms to 0 to get rid of any
garbage in memory */
for(i=0;i<3;i++)
{
    for(p=0;p<N;p++)
    {
        particles[p].v[i] = 0;
        particles[p].a[i] = 0;
    }
}


for(t=0;t<ft;t+=dt)
{
output_to_file();
calcacceleration();
velocity_mover();
position_mover();
pe = calcacceleration();
ke = velocity_mover();
te = ke + pe;
printf("Time: %f\n PE: %f\n KE: %f\n TE: %f\n",t,pe, ke, te);
}
printf("Done!\n");
return 0;
}
0个回答
没有发现任何回复~