git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@1193 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2007-11-30 21:54:30 +00:00
parent d9df67ded2
commit 8fb52958ce
124 changed files with 4220 additions and 3618 deletions

View File

@ -74,15 +74,16 @@ PairGayBerne::~PairGayBerne()
void PairGayBerne::compute(int eflag, int vflag) void PairGayBerne::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,m,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double one_eng,rsq,r2inv,r6inv,forcelj; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fx,fy,fz;
double one_eng,rsq,r2inv,r6inv,forcelj,factor_lj;
double fforce[3],ttor[3],rtor[3],r12[3]; double fforce[3],ttor[3],rtor[3],r12[3];
double a1[3][3],b1[3][3],g1[3][3],a2[3][3],b2[3][3],g2[3][3],temp[3][3]; double a1[3][3],b1[3][3],g1[3][3],a2[3][3],b2[3][3],g2[3][3],temp[3][3];
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
double factor_lj;
eng_vdwl = 0.0; evdwl = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -90,7 +91,7 @@ void PairGayBerne::compute(int eflag, int vflag)
double **tor = atom->torque; double **tor = atom->torque;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -188,25 +189,16 @@ void PairGayBerne::compute(int eflag, int vflag)
tor[j][2] += rtor[2]; tor[j][2] += rtor[2];
} }
if (eflag) { if (eflag) evdwl = factor_lj*one_eng;
if (newton_pair || j < nlocal) eng_vdwl += factor_lj*one_eng;
else eng_vdwl += 0.5*factor_lj*one_eng;
}
if (vflag == 1) { if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) evdwl,0.0,fforce[0],fforce[1],fforce[2],
for (m = 0; m < 6; m++) fforce[m] *= 0.5; -r12[0],-r12[1],-r12[2]);
virial[0] -= r12[0]*fforce[0];
virial[1] -= r12[1]*fforce[1];
virial[2] -= r12[2]*fforce[2];
virial[3] -= r12[0]*fforce[1];
virial[4] -= r12[0]*fforce[2];
virial[5] -= r12[1]*fforce[2];
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -80,23 +80,23 @@ PairRESquared::~PairRESquared()
void PairRESquared::compute(int eflag, int vflag) void PairRESquared::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,m,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double one_eng,rsq,r2inv,r6inv,forcelj; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fx,fy,fz;
double one_eng,rsq,r2inv,r6inv,forcelj,factor_lj;
double fforce[3],ttor[3],rtor[3],r12[3]; double fforce[3],ttor[3],rtor[3],r12[3];
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
double factor_lj;
RE2Vars wi,wj; RE2Vars wi,wj;
eng_vdwl = 0.0; evdwl = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double **quat = atom->quat;
double **tor = atom->torque; double **tor = atom->torque;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -155,7 +155,7 @@ void PairRESquared::compute(int eflag, int vflag)
case SPHERE_ELLIPSE: case SPHERE_ELLIPSE:
precompute_i(j,wj); precompute_i(j,wj);
if (newton_pair || j<nlocal) { if (newton_pair || j < nlocal) {
one_eng = resquared_lj(j,i,wj,r12,rsq,fforce,rtor,true); one_eng = resquared_lj(j,i,wj,r12,rsq,fforce,rtor,true);
tor[j][0] += rtor[0]*factor_lj; tor[j][0] += rtor[0]*factor_lj;
tor[j][1] += rtor[1]*factor_lj; tor[j][1] += rtor[1]*factor_lj;
@ -177,7 +177,7 @@ void PairRESquared::compute(int eflag, int vflag)
tor[i][0] += ttor[0]*factor_lj; tor[i][0] += ttor[0]*factor_lj;
tor[i][1] += ttor[1]*factor_lj; tor[i][1] += ttor[1]*factor_lj;
tor[i][2] += ttor[2]*factor_lj; tor[i][2] += ttor[2]*factor_lj;
if (newton_pair || j<nlocal) { if (newton_pair || j < nlocal) {
tor[j][0] += rtor[0]*factor_lj; tor[j][0] += rtor[0]*factor_lj;
tor[j][1] += rtor[1]*factor_lj; tor[j][1] += rtor[1]*factor_lj;
tor[j][2] += rtor[2]*factor_lj; tor[j][2] += rtor[2]*factor_lj;
@ -198,25 +198,16 @@ void PairRESquared::compute(int eflag, int vflag)
f[j][2] -= fforce[2]; f[j][2] -= fforce[2];
} }
if (eflag) { if (eflag) evdwl = factor_lj*one_eng;
if (newton_pair || j < nlocal) eng_vdwl += factor_lj*one_eng;
else eng_vdwl += 0.5*factor_lj*one_eng;
}
if (vflag == 1) { if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) evdwl,0.0,fforce[0],fforce[1],fforce[2],
for (m = 0; m < 6; m++) fforce[m] *= 0.5; -r12[0],-r12[1],-r12[2]);
virial[0] -= r12[0]*fforce[0];
virial[1] -= r12[1]*fforce[1];
virial[2] -= r12[2]*fforce[2];
virial[3] -= r12[0]*fforce[1];
virial[4] -= r12[0]*fforce[2];
virial[5] -= r12[1]*fforce[2];
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -64,15 +64,17 @@ AngleClass2::~AngleClass2()
void AngleClass2::compute(int eflag, int vflag) void AngleClass2::compute(int eflag, int vflag)
{ {
int i1,i2,i3,n,type,factor; int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2,rfactor; double delx1,dely1,delz1,delx2,dely2,delz2;
double eangle,f1[3],f3[3];
double dtheta,dtheta2,dtheta3,dtheta4,de_angle; double dtheta,dtheta2,dtheta3,dtheta4,de_angle;
double dr1,dr2,tk1,tk2,aa1,aa2,aa11,aa12,aa21,aa22; double dr1,dr2,tk1,tk2,aa1,aa2,aa11,aa12,aa21,aa22;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22,b1,b2,vx1,vx2,vy1,vy2,vz1,vz2; double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22,b1,b2;
double vx11,vx12,vy11,vy12,vz11,vz12,vx21,vx22,vy21,vy22,vz21,vz22; double vx11,vx12,vy11,vy12,vz11,vz12,vx21,vx22,vy21,vy22,vz21,vz22;
energy = 0.0; eangle = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -82,21 +84,11 @@ void AngleClass2::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) { for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0]; i1 = anglelist[n][0];
i2 = anglelist[n][1]; i2 = anglelist[n][1];
i3 = anglelist[n][2]; i3 = anglelist[n][2];
type = anglelist[n][3]; type = anglelist[n][3];
if (newton_bond) factor = 3;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
}
rfactor = factor/3.0;
// 1st bond // 1st bond
delx1 = x[i1][0] - x[i2][0]; delx1 = x[i1][0] - x[i2][0];
@ -139,22 +131,20 @@ void AngleClass2::compute(int eflag, int vflag)
de_angle = 2.0*k2[type]*dtheta + 3.0*k3[type]*dtheta2 + de_angle = 2.0*k2[type]*dtheta + 3.0*k3[type]*dtheta2 +
4.0*k4[type]*dtheta3; 4.0*k4[type]*dtheta3;
a = de_angle*s; a = -de_angle*s;
a11 = a*c / rsq1; a11 = a*c / rsq1;
a12 = -a / (r1*r2); a12 = -a / (r1*r2);
a22 = a*c / rsq2; a22 = a*c / rsq2;
vx1 = a11*delx1 + a12*delx2; f1[0] = a11*delx1 + a12*delx2;
vy1 = a11*dely1 + a12*dely2; f1[1] = a11*dely1 + a12*dely2;
vz1 = a11*delz1 + a12*delz2; f1[2] = a11*delz1 + a12*delz2;
vx2 = a22*delx2 + a12*delx1; f3[0] = a22*delx2 + a12*delx1;
vy2 = a22*dely2 + a12*dely1; f3[1] = a22*dely2 + a12*dely1;
vz2 = a22*delz2 + a12*delz1; f3[2] = a22*delz2 + a12*delz1;
if (eflag) energy += rfactor * if (eflag) eangle = k2[type]*dtheta2 + k3[type]*dtheta3 + k4[type]*dtheta4;
(k2[type]*dtheta2 + k3[type]*dtheta3 + k4[type]*dtheta4);
// force & energy for bond-bond term // force & energy for bond-bond term
@ -163,15 +153,15 @@ void AngleClass2::compute(int eflag, int vflag)
tk1 = bb_k[type] * dr1; tk1 = bb_k[type] * dr1;
tk2 = bb_k[type] * dr2; tk2 = bb_k[type] * dr2;
vx1 += delx1*tk2/r1; f1[0] -= delx1*tk2/r1;
vy1 += dely1*tk2/r1; f1[2] -= dely1*tk2/r1;
vz1 += delz1*tk2/r1; f1[2] -= delz1*tk2/r1;
vx2 += delx2*tk1/r2; f3[0] -= delx2*tk1/r2;
vy2 += dely2*tk1/r2; f3[1] -= dely2*tk1/r2;
vz2 += delz2*tk1/r2; f3[2] -= delz2*tk1/r2;
if (eflag) energy += rfactor * bb_k[type]*dr1*dr2; if (eflag) eangle += bb_k[type]*dr1*dr2;
// force & energy for bond-angle term // force & energy for bond-angle term
@ -203,47 +193,38 @@ void AngleClass2::compute(int eflag, int vflag)
b1 = ba_k1[type] * dtheta / r1; b1 = ba_k1[type] * dtheta / r1;
b2 = ba_k2[type] * dtheta / r2; b2 = ba_k2[type] * dtheta / r2;
vx1 += vx11 + b1*delx1 + vx12; f1[0] -= vx11 + b1*delx1 + vx12;
vy1 += vy11 + b1*dely1 + vy12; f1[2] -= vy11 + b1*dely1 + vy12;
vz1 += vz11 + b1*delz1 + vz12; f1[2] -= vz11 + b1*delz1 + vz12;
vx2 += vx21 + b2*delx2 + vx22; f3[0] -= vx21 + b2*delx2 + vx22;
vy2 += vy21 + b2*dely2 + vy22; f3[1] -= vy21 + b2*dely2 + vy22;
vz2 += vz21 + b2*delz2 + vz22; f3[2] -= vz21 + b2*delz2 + vz22;
if (eflag) energy += rfactor * if (eflag) eangle += ba_k1[type]*dr1*dtheta + ba_k2[type]*dr2*dtheta;
((ba_k1[type]*dr1*dtheta) + (ba_k2[type]*dr2*dtheta));
// apply force to each of 3 atoms // apply force to each of 3 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= vx1; f[i1][0] += f1[0];
f[i1][1] -= vy1; f[i1][1] += f1[1];
f[i1][2] -= vz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += vx1 + vx2; f[i2][0] -= f1[0] + f3[0];
f[i2][1] += vy1 + vy2; f[i2][1] -= f1[1] + f3[1];
f[i2][2] += vz1 + vz2; f[i2][2] -= f1[2] + f3[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] -= vx2; f[i3][0] += f3[0];
f[i3][1] -= vy2; f[i3][1] += f3[1];
f[i3][2] -= vz2; f[i3][2] += f3[2];
} }
// virial contribution if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
if (vflag) {
virial[0] -= rfactor * (delx1*vx1 + delx2*vx2);
virial[1] -= rfactor * (dely1*vy1 + dely2*vy2);
virial[2] -= rfactor * (delz1*vz1 + delz2*vz2);
virial[3] -= rfactor * (delx1*vy1 + delx2*vy2);
virial[4] -= rfactor * (delx1*vz1 + delx2*vz2);
virial[5] -= rfactor * (dely1*vz1 + dely2*vz2);
}
} }
} }

View File

@ -49,11 +49,13 @@ BondClass2::~BondClass2()
void BondClass2::compute(int eflag, int vflag) void BondClass2::compute(int eflag, int vflag)
{ {
int i1,i2,n,type,factor; int i1,i2,n,type;
double delx,dely,delz,rsq,r,dr,dr2,dr3,dr4,de_bond,fforce,rfactor; double delx,dely,delz,ebond,fbond;
double rsq,r,dr,dr2,dr3,dr4,de_bond;
energy = 0.0; ebond = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -63,19 +65,10 @@ void BondClass2::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nbondlist; n++) { for (n = 0; n < nbondlist; n++) {
i1 = bondlist[n][0]; i1 = bondlist[n][0];
i2 = bondlist[n][1]; i2 = bondlist[n][1];
type = bondlist[n][2]; type = bondlist[n][2];
if (newton_bond) factor = 2;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
}
rfactor = 0.5 * factor;
delx = x[i1][0] - x[i2][0]; delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1]; dely = x[i1][1] - x[i2][1];
delz = x[i1][2] - x[i2][2]; delz = x[i1][2] - x[i2][2];
@ -91,36 +84,26 @@ void BondClass2::compute(int eflag, int vflag)
// force & energy // force & energy
de_bond = 2.0*k2[type]*dr + 3.0*k3[type]*dr2 + 4.0*k4[type]*dr3; de_bond = 2.0*k2[type]*dr + 3.0*k3[type]*dr2 + 4.0*k4[type]*dr3;
if (r > 0.0) fforce = -de_bond/r; if (r > 0.0) fbond = -de_bond/r;
else fforce = 0.0; else fbond = 0.0;
if (eflag) if (eflag) ebond = k2[type]*dr2 + k3[type]*dr3 + k4[type]*dr4;
energy += rfactor * (k2[type]*dr2 + k3[type]*dr3 + k4[type]*dr4);
// apply force to each of 2 atoms // apply force to each of 2 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] += delx*fforce; f[i1][0] += delx*fbond;
f[i1][1] += dely*fforce; f[i1][1] += dely*fbond;
f[i1][2] += delz*fforce; f[i1][2] += delz*fbond;
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx*fforce; f[i2][0] -= delx*fbond;
f[i2][1] -= dely*fforce; f[i2][1] -= dely*fbond;
f[i2][2] -= delz*fforce; f[i2][2] -= delz*fbond;
} }
// virial contribution if (evflag) ev_tally(i1,i2,nlocal,newton_bond,ebond,fbond,delx,dely,delz);
if (vflag) {
virial[0] += rfactor*delx*delx*fforce;
virial[1] += rfactor*dely*dely*fforce;
virial[2] += rfactor*delz*delz*fforce;
virial[3] += rfactor*delx*dely*fforce;
virial[4] += rfactor*delx*delz*fforce;
virial[5] += rfactor*dely*delz*fforce;
}
} }
} }
@ -215,19 +198,12 @@ void BondClass2::read_restart(FILE *fp)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void BondClass2::single(int type, double rsq, int i, int j, void BondClass2::single(int type, double rsq, int i, int j, double &eng)
int eflag, double &fforce, double &eng)
{ {
double r = sqrt(rsq); double r = sqrt(rsq);
double dr = r - r0[type]; double dr = r - r0[type];
double dr2 = dr*dr; double dr2 = dr*dr;
double dr3 = dr2*dr; double dr3 = dr2*dr;
double dr4 = dr3*dr; double dr4 = dr3*dr;
eng = k2[type]*dr2 + k3[type]*dr3 + k4[type]*dr4;
// force & energy
double de_bond = 2.0*k2[type]*dr + 3.0*k3[type]*dr2 + 4.0*k4[type]*dr3;
if (r > 0.0) fforce = -de_bond/r;
else fforce = 0.0;
if (eflag) eng = k2[type]*dr2 + k3[type]*dr3 + k4[type]*dr4;
} }

View File

@ -28,7 +28,7 @@ class BondClass2 : public Bond {
double equilibrium_distance(int); double equilibrium_distance(int);
void write_restart(FILE *); void write_restart(FILE *);
void read_restart(FILE *); void read_restart(FILE *);
void single(int, double, int, int, int, double &, double &); void single(int, double, int, int, double &);
private: private:
double *r0,*k2,*k3,*k4; double *r0,*k2,*k3,*k4;

View File

@ -101,23 +101,23 @@ DihedralClass2::~DihedralClass2()
void DihedralClass2::compute(int eflag, int vflag) void DihedralClass2::compute(int eflag, int vflag)
{ {
int i1,i2,i3,i4,i,j,k,n,type,factor; int i1,i2,i3,i4,i,j,k,n,type;
double rfactor; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double delx1,dely1,delz1,dely2,delz2,delx2m,dely2m,delz2m; double edihedral;
double delx2,dely3,delz3,r1mag2,r1,r2mag2,r2,r3mag2,r3; double r1mag2,r1,r2mag2,r2,r3mag2,r3;
double sb1,rb1,sb2,rb2,sb3,rb3,c0,r12c1; double sb1,rb1,sb2,rb2,sb3,rb3,c0,r12c1;
double r12c2,costh12,costh13,costh23,sc1,sc2,s1,s2,c; double r12c2,costh12,costh13,costh23,sc1,sc2,s1,s2,c;
double cosphi,phi,sinphi,a11,a22,a33,a12,a13,a23,sx1,sx2; double cosphi,phi,sinphi,a11,a22,a33,a12,a13,a23,sx1,sx2;
double sx12,sy1,sy2,sy12,sz1,sz2,sz12,dphi1,dphi2,dphi3; double sx12,sy1,sy2,sy12,sz1,sz2,sz12,dphi1,dphi2,dphi3;
double de_dihedral,t1,t2,t3,t4,cos2phi,cos3phi,bt1,bt2; double de_dihedral,t1,t2,t3,t4,cos2phi,cos3phi,bt1,bt2;
double bt3,sumbte,db,sumbtf,at1,at2,at3,da,da1,da2,r1_0; double bt3,sumbte,db,sumbtf,at1,at2,at3,da,da1,da2,r1_0;
double r3_0,dr1,dr2,tk1,tk2,vx1,vx2,vx3,vy1,vy2,vy3,vz1; double r3_0,dr1,dr2,tk1,tk2,s12,sin2;
double vz2,vz3,delx3,s12,sin2;
double dcosphidr[4][3],dphidr[4][3],dbonddr[3][4][3],dthetadr[2][4][3]; double dcosphidr[4][3],dphidr[4][3],dbonddr[3][4][3],dthetadr[2][4][3];
double fabcd[4][3]; double fabcd[4][3];
energy = 0.0; edihedral = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -127,76 +127,63 @@ void DihedralClass2::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < ndihedrallist; n++) { for (n = 0; n < ndihedrallist; n++) {
i1 = dihedrallist[n][0]; i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1]; i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2]; i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3]; i4 = dihedrallist[n][3];
type = dihedrallist[n][4]; type = dihedrallist[n][4];
if (newton_bond) factor = 4;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
if (i4 < nlocal) factor++;
}
rfactor = 0.25 * factor;
// 1st bond // 1st bond
delx1 = x[i1][0] - x[i2][0]; vb1x = x[i1][0] - x[i2][0];
dely1 = x[i1][1] - x[i2][1]; vb1y = x[i1][1] - x[i2][1];
delz1 = x[i1][2] - x[i2][2]; vb1z = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1); domain->minimum_image(vb1x,vb1y,vb1z);
// 2nd bond // 2nd bond
delx2 = x[i3][0] - x[i2][0]; vb2x = x[i3][0] - x[i2][0];
dely2 = x[i3][1] - x[i2][1]; vb2y = x[i3][1] - x[i2][1];
delz2 = x[i3][2] - x[i2][2]; vb2z = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2); domain->minimum_image(vb2x,vb2y,vb2z);
delx2m = -delx2; vb2xm = -vb2x;
dely2m = -dely2; vb2ym = -vb2y;
delz2m = -delz2; vb2zm = -vb2z;
domain->minimum_image(delx2m,dely2m,delz2m); domain->minimum_image(vb2xm,vb2ym,vb2zm);
// 3rd bond // 3rd bond
delx3 = x[i4][0] - x[i3][0]; vb3x = x[i4][0] - x[i3][0];
dely3 = x[i4][1] - x[i3][1]; vb3y = x[i4][1] - x[i3][1];
delz3 = x[i4][2] - x[i3][2]; vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(delx3,dely3,delz3); domain->minimum_image(vb3x,vb3y,vb3z);
// distances // distances
r1mag2 = delx1*delx1 + dely1*dely1 + delz1*delz1; r1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
r1 = sqrt(r1mag2); r1 = sqrt(r1mag2);
r2mag2 = delx2*delx2 + dely2*dely2 + delz2*delz2; r2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
r2 = sqrt(r2mag2); r2 = sqrt(r2mag2);
r3mag2 = delx3*delx3 + dely3*dely3 + delz3*delz3; r3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
r3 = sqrt(r3mag2); r3 = sqrt(r3mag2);
sb1 = 1.0/r1mag2; sb1 = 1.0/r1mag2;
rb1 = 1.0/r1; rb1 = 1.0/r1;
sb2 = 1.0/r2mag2; sb2 = 1.0/r2mag2;
rb2 = 1.0/r2; rb2 = 1.0/r2;
sb3 = 1.0/r3mag2; sb3 = 1.0/r3mag2;
rb3 = 1.0/r3; rb3 = 1.0/r3;
c0 = (delx1*delx3 + dely1*dely3 + delz1*delz3) * rb1*rb3; c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
// angles // angles
r12c1 = rb1*rb2; r12c1 = rb1*rb2;
r12c2 = rb2*rb3; r12c2 = rb2*rb3;
costh12 = (delx1*delx2 + dely1*dely2 + delz1*delz2) * r12c1; costh12 = (vb1x*vb2x + vb1y*vb2y + vb1z*vb2z) * r12c1;
costh13 = c0; costh13 = c0;
costh23 = (delx2m*delx3 + dely2m*dely3 + delz2m*delz3) * r12c2; costh23 = (vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z) * r12c2;
// cos and sin of 2 angles and final c // cos and sin of 2 angles and final c
@ -250,15 +237,15 @@ void DihedralClass2::compute(int eflag, int vflag)
a13 = rb1*rb3*s12; a13 = rb1*rb3*s12;
a23 = r12c2 * (-costh23*c*s2 - costh12*s12); a23 = r12c2 * (-costh23*c*s2 - costh12*s12);
sx1 = a11*delx1 + a12*delx2 + a13*delx3; sx1 = a11*vb1x + a12*vb2x + a13*vb3x;
sx2 = a12*delx1 + a22*delx2 + a23*delx3; sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sx12 = a13*delx1 + a23*delx2 + a33*delx3; sx12 = a13*vb1x + a23*vb2x + a33*vb3x;
sy1 = a11*dely1 + a12*dely2 + a13*dely3; sy1 = a11*vb1y + a12*vb2y + a13*vb3y;
sy2 = a12*dely1 + a22*dely2 + a23*dely3; sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sy12 = a13*dely1 + a23*dely2 + a33*dely3; sy12 = a13*vb1y + a23*vb2y + a33*vb3y;
sz1 = a11*delz1 + a12*delz2 + a13*delz3; sz1 = a11*vb1z + a12*vb2z + a13*vb3z;
sz2 = a12*delz1 + a22*delz2 + a23*delz3; sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
sz12 = a13*delz1 + a23*delz2 + a33*delz3; sz12 = a13*vb1z + a23*vb2z + a33*vb3z;
// set up d(cos(phi))/d(r) and dphi/dr arrays // set up d(cos(phi))/d(r) and dphi/dr arrays
@ -285,10 +272,10 @@ void DihedralClass2::compute(int eflag, int vflag)
dphi2 = 2.0*phi - phi2[type]; dphi2 = 2.0*phi - phi2[type];
dphi3 = 3.0*phi - phi3[type]; dphi3 = 3.0*phi - phi3[type];
if (eflag) energy += rfactor * (k1[type]*(1.0 - cos(dphi1)) + if (eflag) edihedral = k1[type]*(1.0 - cos(dphi1)) +
k2[type]*(1.0 - cos(dphi2)) + k2[type]*(1.0 - cos(dphi2)) +
k3[type]*(1.0 - cos(dphi3))); k3[type]*(1.0 - cos(dphi3));
de_dihedral = k1[type]*sin(dphi1) + 2.0*k2[type]*sin(dphi2) + de_dihedral = k1[type]*sin(dphi1) + 2.0*k2[type]*sin(dphi2) +
3.0*k3[type]*sin(dphi3); 3.0*k3[type]*sin(dphi3);
@ -308,30 +295,30 @@ void DihedralClass2::compute(int eflag, int vflag)
// bond1 // bond1
dbonddr[0][0][0] = delx1 / r1; dbonddr[0][0][0] = vb1x / r1;
dbonddr[0][0][1] = dely1 / r1; dbonddr[0][0][1] = vb1y / r1;
dbonddr[0][0][2] = delz1 / r1; dbonddr[0][0][2] = vb1z / r1;
dbonddr[0][1][0] = -delx1 / r1; dbonddr[0][1][0] = -vb1x / r1;
dbonddr[0][1][1] = -dely1 / r1; dbonddr[0][1][1] = -vb1y / r1;
dbonddr[0][1][2] = -delz1 / r1; dbonddr[0][1][2] = -vb1z / r1;
// bond2 // bond2
dbonddr[1][1][0] = delx2 / r2; dbonddr[1][1][0] = vb2x / r2;
dbonddr[1][1][1] = dely2 / r2; dbonddr[1][1][1] = vb2y / r2;
dbonddr[1][1][2] = delz2 / r2; dbonddr[1][1][2] = vb2z / r2;
dbonddr[1][2][0] = -delx2 / r2; dbonddr[1][2][0] = -vb2x / r2;
dbonddr[1][2][1] = -dely2 / r2; dbonddr[1][2][1] = -vb2y / r2;
dbonddr[1][2][2] = -delz2 / r2; dbonddr[1][2][2] = -vb2z / r2;
// bond3 // bond3
dbonddr[2][2][0] = delx3 / r3; dbonddr[2][2][0] = vb3x / r3;
dbonddr[2][2][1] = dely3 / r3; dbonddr[2][2][1] = vb3y / r3;
dbonddr[2][2][2] = delz3 / r3; dbonddr[2][2][2] = vb3z / r3;
dbonddr[2][3][0] = -delx3 / r3; dbonddr[2][3][0] = -vb3x / r3;
dbonddr[2][3][1] = -dely3 / r3; dbonddr[2][3][1] = -vb3y / r3;
dbonddr[2][3][2] = -delz3 / r3; dbonddr[2][3][2] = -vb3z / r3;
// set up d(theta)/d(r) array // set up d(theta)/d(r) array
// dthetadr(i,j,k) = angle i, atom j, coordinate k // dthetadr(i,j,k) = angle i, atom j, coordinate k
@ -348,37 +335,37 @@ void DihedralClass2::compute(int eflag, int vflag)
// angle12 // angle12
dthetadr[0][0][0] = sc1 * ((t1 * delx1) - (delx2 * r12c1)); dthetadr[0][0][0] = sc1 * ((t1 * vb1x) - (vb2x * r12c1));
dthetadr[0][0][1] = sc1 * ((t1 * dely1) - (dely2 * r12c1)); dthetadr[0][0][1] = sc1 * ((t1 * vb1y) - (vb2y * r12c1));
dthetadr[0][0][2] = sc1 * ((t1 * delz1) - (delz2 * r12c1)); dthetadr[0][0][2] = sc1 * ((t1 * vb1z) - (vb2z * r12c1));
dthetadr[0][1][0] = sc1 * ((-t1 * delx1) + (delx2 * r12c1) + dthetadr[0][1][0] = sc1 * ((-t1 * vb1x) + (vb2x * r12c1) +
(-t3 * delx2) + (delx1 * r12c1)); (-t3 * vb2x) + (vb1x * r12c1));
dthetadr[0][1][1] = sc1 * ((-t1 * dely1) + (dely2 * r12c1) + dthetadr[0][1][1] = sc1 * ((-t1 * vb1y) + (vb2y * r12c1) +
(-t3 * dely2) + (dely1 * r12c1)); (-t3 * vb2y) + (vb1y * r12c1));
dthetadr[0][1][2] = sc1 * ((-t1 * delz1) + (delz2 * r12c1) + dthetadr[0][1][2] = sc1 * ((-t1 * vb1z) + (vb2z * r12c1) +
(-t3 * delz2) + (delz1 * r12c1)); (-t3 * vb2z) + (vb1z * r12c1));
dthetadr[0][2][0] = sc1 * ((t3 * delx2) - (delx1 * r12c1)); dthetadr[0][2][0] = sc1 * ((t3 * vb2x) - (vb1x * r12c1));
dthetadr[0][2][1] = sc1 * ((t3 * dely2) - (dely1 * r12c1)); dthetadr[0][2][1] = sc1 * ((t3 * vb2y) - (vb1y * r12c1));
dthetadr[0][2][2] = sc1 * ((t3 * delz2) - (delz1 * r12c1)); dthetadr[0][2][2] = sc1 * ((t3 * vb2z) - (vb1z * r12c1));
// angle23 // angle23
dthetadr[1][1][0] = sc2 * ((t2 * delx2) + (delx3 * r12c2)); dthetadr[1][1][0] = sc2 * ((t2 * vb2x) + (vb3x * r12c2));
dthetadr[1][1][1] = sc2 * ((t2 * dely2) + (dely3 * r12c2)); dthetadr[1][1][1] = sc2 * ((t2 * vb2y) + (vb3y * r12c2));
dthetadr[1][1][2] = sc2 * ((t2 * delz2) + (delz3 * r12c2)); dthetadr[1][1][2] = sc2 * ((t2 * vb2z) + (vb3z * r12c2));
dthetadr[1][2][0] = sc2 * ((-t2 * delx2) - (delx3 * r12c2) + dthetadr[1][2][0] = sc2 * ((-t2 * vb2x) - (vb3x * r12c2) +
(t4 * delx3) + (delx2 * r12c2)); (t4 * vb3x) + (vb2x * r12c2));
dthetadr[1][2][1] = sc2 * ((-t2 * dely2) - (dely3 * r12c2) + dthetadr[1][2][1] = sc2 * ((-t2 * vb2y) - (vb3y * r12c2) +
(t4 * dely3) + (dely2 * r12c2)); (t4 * vb3y) + (vb2y * r12c2));
dthetadr[1][2][2] = sc2 * ((-t2 * delz2) - (delz3 * r12c2) + dthetadr[1][2][2] = sc2 * ((-t2 * vb2z) - (vb3z * r12c2) +
(t4 * delz3) + (delz2 * r12c2)); (t4 * vb3z) + (vb2z * r12c2));
dthetadr[1][3][0] = -sc2 * ((t4 * delx3) + (delx2 * r12c2)); dthetadr[1][3][0] = -sc2 * ((t4 * vb3x) + (vb2x * r12c2));
dthetadr[1][3][1] = -sc2 * ((t4 * dely3) + (dely2 * r12c2)); dthetadr[1][3][1] = -sc2 * ((t4 * vb3y) + (vb2y * r12c2));
dthetadr[1][3][2] = -sc2 * ((t4 * delz3) + (delz2 * r12c2)); dthetadr[1][3][2] = -sc2 * ((t4 * vb3z) + (vb2z * r12c2));
// mid-bond/torsion coupling // mid-bond/torsion coupling
// energy on bond2 (middle bond) // energy on bond2 (middle bond)
@ -391,7 +378,7 @@ void DihedralClass2::compute(int eflag, int vflag)
bt3 = mbt_f3[type] * cos3phi; bt3 = mbt_f3[type] * cos3phi;
sumbte = bt1 + bt2 + bt3; sumbte = bt1 + bt2 + bt3;
db = r2 - mbt_r0[type]; db = r2 - mbt_r0[type];
if (eflag) energy += rfactor * db * sumbte; if (eflag) edihedral += db * sumbte;
// force on bond2 // force on bond2
@ -413,7 +400,7 @@ void DihedralClass2::compute(int eflag, int vflag)
sumbte = bt1 + bt2 + bt3; sumbte = bt1 + bt2 + bt3;
db = r1 - ebt_r0_1[type]; db = r1 - ebt_r0_1[type];
if (eflag) energy += rfactor * db * (bt1+bt2+bt3); if (eflag) edihedral += db * (bt1+bt2+bt3);
// force on bond1 // force on bond1
@ -435,7 +422,7 @@ void DihedralClass2::compute(int eflag, int vflag)
sumbte = bt1 + bt2 + bt3; sumbte = bt1 + bt2 + bt3;
db = r3 - ebt_r0_2[type]; db = r3 - ebt_r0_2[type];
if (eflag) energy += rfactor * db * (bt1+bt2+bt3); if (eflag) edihedral += db * (bt1+bt2+bt3);
// force on bond3 // force on bond3
@ -457,7 +444,7 @@ void DihedralClass2::compute(int eflag, int vflag)
sumbte = at1 + at2 + at3; sumbte = at1 + at2 + at3;
da = acos(costh12) - at_theta0_1[type]; da = acos(costh12) - at_theta0_1[type];
if (eflag) energy += rfactor * da * (at1+at2+at3); if (eflag) edihedral += da * (at1+at2+at3);
// force on angle1 // force on angle1
@ -478,7 +465,7 @@ void DihedralClass2::compute(int eflag, int vflag)
sumbte = at1 + at2 + at3; sumbte = at1 + at2 + at3;
da = acos(costh23) - at_theta0_2[type]; da = acos(costh23) - at_theta0_2[type];
if (eflag) energy += rfactor *da * (at1+at2+at3); if (eflag) edihedral += da * (at1+at2+at3);
// force on angle2 // force on angle2
@ -496,11 +483,7 @@ void DihedralClass2::compute(int eflag, int vflag)
da1 = acos(costh12) - aat_theta0_1[type]; da1 = acos(costh12) - aat_theta0_1[type];
da2 = acos(costh23) - aat_theta0_2[type]; da2 = acos(costh23) - aat_theta0_2[type];
// energy if (eflag) edihedral += aat_k[type]*da1*da2*cosphi;
if (eflag) energy += rfactor * aat_k[type]*da1*da2*cosphi;
// force
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
@ -519,23 +502,23 @@ void DihedralClass2::compute(int eflag, int vflag)
tk1 = -bb13t_k[type] * dr1 / r3; tk1 = -bb13t_k[type] * dr1 / r3;
tk2 = -bb13t_k[type] * dr2 / r1; tk2 = -bb13t_k[type] * dr2 / r1;
if (eflag) energy += rfactor * bb13t_k[type]*dr1*dr2; if (eflag) edihedral += bb13t_k[type]*dr1*dr2;
fabcd[0][0] += tk2 * delx1; fabcd[0][0] += tk2 * vb1x;
fabcd[0][1] += tk2 * dely1; fabcd[0][1] += tk2 * vb1y;
fabcd[0][2] += tk2 * delz1; fabcd[0][2] += tk2 * vb1z;
fabcd[1][0] -= tk2 * delx1; fabcd[1][0] -= tk2 * vb1x;
fabcd[1][1] -= tk2 * dely1; fabcd[1][1] -= tk2 * vb1y;
fabcd[1][2] -= tk2 * delz1; fabcd[1][2] -= tk2 * vb1z;
fabcd[2][0] -= tk1 * delx3; fabcd[2][0] -= tk1 * vb3x;
fabcd[2][1] -= tk1 * dely3; fabcd[2][1] -= tk1 * vb3y;
fabcd[2][2] -= tk1 * delz3; fabcd[2][2] -= tk1 * vb3z;
fabcd[3][0] += tk1 * delx3; fabcd[3][0] += tk1 * vb3x;
fabcd[3][1] += tk1 * dely3; fabcd[3][1] += tk1 * vb3y;
fabcd[3][2] += tk1 * delz3; fabcd[3][2] += tk1 * vb3z;
} }
// apply force to each of 4 atoms // apply force to each of 4 atoms
@ -564,28 +547,10 @@ void DihedralClass2::compute(int eflag, int vflag)
f[i4][2] += fabcd[3][2]; f[i4][2] += fabcd[3][2];
} }
// virial contribution if (evflag)
ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,
if (vflag) { fabcd[i1],fabcd[i3],fabcd[i4],
vx1 = fabcd[0][0]; vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
vx2 = fabcd[2][0] + fabcd[3][0];
vx3 = fabcd[3][0];
vy1 = fabcd[0][1];
vy2 = fabcd[2][1] + fabcd[3][1];
vy3 = fabcd[3][1];
vz1 = fabcd[0][2];
vz2 = fabcd[2][2] + fabcd[3][2];
vz3 = fabcd[3][2];
virial[0] += rfactor * (delx1*vx1 + delx2*vx2 + delx3*vx3);
virial[1] += rfactor * (dely1*vy1 + dely2*vy2 + dely3*vy3);
virial[2] += rfactor * (delz1*vz1 + delz2*vz2 + delz3*vz3);
virial[3] += rfactor * (delx1*vy1 + delx2*vy2 + delx3*vy3);
virial[4] += rfactor * (delx1*vz1 + delx2*vz2 + delx3*vz3);
virial[5] += rfactor * (dely1*vz1 + dely2*vz2 + dely3*vz3);
}
} }
} }

View File

@ -63,8 +63,9 @@ ImproperClass2::~ImproperClass2()
void ImproperClass2::compute(int eflag, int vflag) void ImproperClass2::compute(int eflag, int vflag)
{ {
int i1,i2,i3,i4,i,j,k,n,type,factor; int i1,i2,i3,i4,i,j,k,n,type;
double rfactor; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z;
double eimproper,f1[3],f2[3],f3[3],f4[3];
double delr[3][3],rmag[3],rinvmag[3],rmag2[3]; double delr[3][3],rmag[3],rinvmag[3],rmag2[3];
double theta[3],costheta[3],sintheta[3]; double theta[3],costheta[3],sintheta[3];
double cossqtheta[3],sinsqtheta[3],invstheta[3]; double cossqtheta[3],sinsqtheta[3],invstheta[3];
@ -75,7 +76,7 @@ void ImproperClass2::compute(int eflag, int vflag)
double drCBxrDB[3],rCBxdrDB[3],drDBxrAB[3],rDBxdrAB[3]; double drCBxrDB[3],rCBxdrDB[3],drDBxrAB[3],rDBxdrAB[3];
double drABxrCB[3],rABxdrCB[3]; double drABxrCB[3],rABxdrCB[3];
double dot1,dot2,dd[3]; double dot1,dot2,dd[3];
double fdot[3][4][3],f2[3][4][3],invs3r[3],inv3r; double fdot[3][4][3],ftmp,invs3r[3],inv3r;
double t,tt1,tt3,sc1; double t,tt1,tt3,sc1;
double dotCBDBAB,dotDBABCB,dotABCBDB; double dotCBDBAB,dotDBABCB,dotABCBDB;
double chi,deltachi,d2chi,cossin2; double chi,deltachi,d2chi,cossin2;
@ -84,8 +85,9 @@ void ImproperClass2::compute(int eflag, int vflag)
double schiABCD,chiABCD,schiCBDA,chiCBDA,schiDBAC,chiDBAC; double schiABCD,chiABCD,schiCBDA,chiCBDA,schiDBAC,chiDBAC;
double fabcd[4][3]; double fabcd[4][3];
energy = 0.0; eimproper = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
@ -104,7 +106,6 @@ void ImproperClass2::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nimproperlist; n++) { for (n = 0; n < nimproperlist; n++) {
i1 = improperlist[n][0]; i1 = improperlist[n][0];
i2 = improperlist[n][1]; i2 = improperlist[n][1];
i3 = improperlist[n][2]; i3 = improperlist[n][2];
@ -113,16 +114,6 @@ void ImproperClass2::compute(int eflag, int vflag)
if (k0[type] == 0.0) continue; if (k0[type] == 0.0) continue;
if (newton_bond) factor = 4;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
if (i4 < nlocal) factor++;
}
rfactor = 0.25 * factor;
// difference vectors // difference vectors
delr[0][0] = x[i1][0] - x[i2][0]; delr[0][0] = x[i1][0] - x[i2][0];
@ -222,7 +213,7 @@ void ImproperClass2::compute(int eflag, int vflag)
// energy // energy
if (eflag) energy += rfactor * k0[type] * d2chi; if (eflag) eimproper = k0[type]*d2chi;
// forces // forces
// define d(delr) // define d(delr)
@ -443,15 +434,15 @@ void ImproperClass2::compute(int eflag, int vflag)
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
f2[0][i][j] = (fdot[0][i][j] * invs3r[0]) + ftmp = (fdot[0][i][j] * invs3r[0]) +
(dinvs3r[0][i][j] * dotCBDBAB); (dinvs3r[0][i][j] * dotCBDBAB);
dchi[0][i][j] = f2[0][i][j] / cos(chiABCD); dchi[0][i][j] = ftmp / cos(chiABCD);
f2[1][i][j] = (fdot[1][i][j] * invs3r[1]) + ftmp = (fdot[1][i][j] * invs3r[1]) +
(dinvs3r[1][i][j] * dotDBABCB); (dinvs3r[1][i][j] * dotDBABCB);
dchi[1][i][j] = f2[1][i][j] / cos(chiCBDA); dchi[1][i][j] = ftmp / cos(chiCBDA);
f2[2][i][j] = (fdot[2][i][j] * invs3r[2]) + ftmp = (fdot[2][i][j] * invs3r[2]) +
(dinvs3r[2][i][j] * dotABCBDB); (dinvs3r[2][i][j] * dotABCBDB);
dchi[2][i][j] = f2[2][i][j] / cos(chiDBAC); dchi[2][i][j] = ftmp / cos(chiDBAC);
dtotalchi[i][j] = (dchi[0][i][j]+dchi[1][i][j]+dchi[2][i][j]) / 3.0; dtotalchi[i][j] = (dchi[0][i][j]+dchi[1][i][j]+dchi[2][i][j]) / 3.0;
} }
@ -485,22 +476,13 @@ void ImproperClass2::compute(int eflag, int vflag)
f[i4][2] += fabcd[3][2]; f[i4][2] += fabcd[3][2];
} }
// virial contribution if (evflag)
ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,
if (vflag) { fabcd[i1],fabcd[i3],fabcd[i4],
virial[0] += rfactor * (delr[0][0]*fabcd[0][0] + delr[0][0],delr[0][1],delr[0][2],
delr[1][0]*fabcd[2][0] + delr[2][0]*fabcd[3][0]); delr[1][0],delr[1][1],delr[1][2],
virial[1] += rfactor * (delr[0][1]*fabcd[0][1] + delr[2][0]-delr[1][0],delr[2][1]-delr[1][1],
delr[1][1]*fabcd[2][1] + delr[2][1]*fabcd[3][1]); delr[2][2]-delr[1][2]);
virial[2] += rfactor * (delr[0][2]*fabcd[0][2] +
delr[1][2]*fabcd[2][2] + delr[2][2]*fabcd[3][2]);
virial[3] += rfactor * (delr[0][0]*fabcd[0][1] +
delr[1][0]*fabcd[2][1] + delr[2][0]*fabcd[3][1]);
virial[4] += rfactor * (delr[0][0]*fabcd[0][2] +
delr[1][0]*fabcd[2][2] + delr[2][0]*fabcd[3][2]);
virial[5] += rfactor * (delr[0][1]*fabcd[0][2] +
delr[1][1]*fabcd[2][2] + delr[2][1]*fabcd[3][2]);
}
} }
// compute angle-angle interactions // compute angle-angle interactions
@ -655,8 +637,8 @@ void ImproperClass2::read_restart(FILE *fp)
void ImproperClass2::angleangle(int eflag, int vflag) void ImproperClass2::angleangle(int eflag, int vflag)
{ {
int i1,i2,i3,i4,i,j,k,n,type,factor; int i1,i2,i3,i4,i,j,k,n,type;
double rfactor; double eimproper;
double delxAB,delyAB,delzAB,rABmag2,rAB; double delxAB,delyAB,delzAB,rABmag2,rAB;
double delxBC,delyBC,delzBC,rBCmag2,rBC; double delxBC,delyBC,delzBC,rBCmag2,rBC;
double delxBD,delyBD,delzBD,rBDmag2,rBD; double delxBD,delyBD,delzBD,rBDmag2,rBD;
@ -673,23 +655,12 @@ void ImproperClass2::angleangle(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nimproperlist; n++) { for (n = 0; n < nimproperlist; n++) {
i1 = improperlist[n][0]; i1 = improperlist[n][0];
i2 = improperlist[n][1]; i2 = improperlist[n][1];
i3 = improperlist[n][2]; i3 = improperlist[n][2];
i4 = improperlist[n][3]; i4 = improperlist[n][3];
type = improperlist[n][4]; type = improperlist[n][4];
if (newton_bond) factor = 4;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
if (i4 < nlocal) factor++;
}
rfactor = 0.25 * factor;
// difference vectors // difference vectors
delxAB = x[i1][0] - x[i2][0]; delxAB = x[i1][0] - x[i2][0];
@ -739,9 +710,9 @@ void ImproperClass2::angleangle(int eflag, int vflag)
// energy // energy
if (eflag) energy += rfactor * ((aa_k2[type] * dthABC * dthABD) + if (eflag) eimproper = aa_k2[type] * dthABC * dthABD +
(aa_k1[type] * dthABC * dthCBD) + aa_k1[type] * dthABC * dthCBD +
(aa_k3[type] * dthABD * dthCBD)); aa_k3[type] * dthABD * dthCBD;
// d(theta)/d(r) array // d(theta)/d(r) array
// angle i, atom j, coordinate k // angle i, atom j, coordinate k
@ -849,22 +820,10 @@ void ImproperClass2::angleangle(int eflag, int vflag)
f[i4][2] += fabcd[3][2]; f[i4][2] += fabcd[3][2];
} }
// virial contribution if (evflag)
ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,
if (vflag) { fabcd[i1],fabcd[i3],fabcd[i4],
virial[0] += rfactor * (delxAB*fabcd[0][0] + delxAB,delyAB,delzAB,delxBC,delyBC,delzBC,delxBD,delyBD,delzBD);
delxBC*fabcd[2][0] + delxBD*fabcd[3][0]);
virial[1] += rfactor * (delyAB*fabcd[0][1] +
delyBC*fabcd[2][1] + delyBD*fabcd[3][1]);
virial[2] += rfactor * (delzAB*fabcd[0][2] +
delzBC*fabcd[2][2] + delzBD*fabcd[3][2]);
virial[3] += rfactor * (delxAB*fabcd[0][1] +
delxBC*fabcd[2][1] + delxBD*fabcd[3][1]);
virial[4] += rfactor * (delxAB*fabcd[0][2] +
delxBC*fabcd[2][2] + delxBD*fabcd[3][2]);
virial[5] += rfactor * (delyAB*fabcd[0][2] +
delyBC*fabcd[2][2] + delyBD*fabcd[3][2]);
}
} }
} }

View File

@ -55,18 +55,19 @@ PairLJClass2::~PairLJClass2()
void PairLJClass2::compute(int eflag, int vflag) void PairLJClass2::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,rinv,r2inv,r3inv,r6inv,forcelj,fforce,factor_lj,philj; double rsq,rinv,r2inv,r3inv,r6inv,forcelj,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = 0.0; evdwl = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -107,37 +108,30 @@ void PairLJClass2::compute(int eflag, int vflag)
r3inv = r2inv*rinv; r3inv = r2inv*rinv;
r6inv = r3inv*r3inv; r6inv = r3inv*r3inv;
forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]); forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
fforce = factor_lj*forcelj*r2inv; fpair = factor_lj*forcelj*r2inv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
philj = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) - evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) -
offset[itype][jtype]; offset[itype][jtype];
if (newton_pair || j < nlocal) eng_vdwl += factor_lj*philj; evdwl *= factor_lj;
else eng_vdwl += 0.5*factor_lj*philj;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,0.0,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -59,20 +59,21 @@ PairLJClass2CoulCut::~PairLJClass2CoulCut()
void PairLJClass2CoulCut::compute(int eflag, int vflag) void PairLJClass2CoulCut::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj,fforce; double rsq,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj;
double factor_coul,factor_lj,factor,phicoul,philj; double factor_coul,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = eng_coul = 0.0; evdwl = ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -125,44 +126,35 @@ void PairLJClass2CoulCut::compute(int eflag, int vflag)
forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]); forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
} else forcelj = 0.0; } else forcelj = 0.0;
fforce = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv; fpair = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0; if (rsq < cut_coulsq[itype][jtype])
else factor = 0.5; ecoul = factor_coul * qqrd2e * qtmp*q[j]*sqrt(r2inv);
if (rsq < cut_coulsq[itype][jtype]) { else ecoul = 0.0;
phicoul = qqrd2e * qtmp*q[j]*sqrt(r2inv);
eng_coul += factor*factor_coul*phicoul;
}
if (rsq < cut_ljsq[itype][jtype]) { if (rsq < cut_ljsq[itype][jtype]) {
philj = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) - evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) -
offset[itype][jtype]; offset[itype][jtype];
eng_vdwl += factor*factor_lj*philj; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,ecoul,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -67,21 +67,22 @@ PairLJClass2CoulLong::~PairLJClass2CoulLong()
void PairLJClass2CoulLong::compute(int eflag, int vflag) void PairLJClass2CoulLong::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj,fforce; double rsq,r,rinv,r2inv,r3inv,r6inv,forcecoul,forcelj;
double grij,expm2,prefactor,t,erfc; double grij,expm2,prefactor,t,erfc;
double factor_coul,factor_lj,factor,phicoul,philj; double factor_coul,factor_lj;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = eng_coul = 0.0; evdwl = ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -141,45 +142,36 @@ void PairLJClass2CoulLong::compute(int eflag, int vflag)
forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]); forcelj = r6inv * (lj1[itype][jtype]*r3inv - lj2[itype][jtype]);
} else forcelj = 0.0; } else forcelj = 0.0;
fforce = (forcecoul + factor_lj*forcelj) * r2inv; fpair = (forcecoul + factor_lj*forcelj) * r2inv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq) { if (rsq < cut_coulsq) {
phicoul = prefactor*erfc; ecoul = prefactor*erfc;
if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
eng_coul += factor*phicoul; } else ecoul = 0.0;
}
if (rsq < cut_ljsq[itype][jtype]) { if (rsq < cut_ljsq[itype][jtype]) {
philj = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) - evdwl = r6inv*(lj3[itype][jtype]*r3inv-lj4[itype][jtype]) -
offset[itype][jtype]; offset[itype][jtype];
eng_vdwl += factor*factor_lj*philj; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,ecoul,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -69,20 +69,21 @@ PairColloid::~PairColloid()
void PairColloid::compute(int eflag, int vflag) void PairColloid::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r,fforce,forcelj,factor_lj,phi; double rsq,r,forcelj,factor_lj;
double r2inv,r6inv,c1,c2,fR,dUR,dUA; double r2inv,r6inv,c1,c2,fR,dUR,dUA;
double K[9],h[4],g[4]; double K[9],h[4],g[4];
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = 0.0; evdwl = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -124,8 +125,8 @@ void PairColloid::compute(int eflag, int vflag)
r2inv = 1.0/rsq; r2inv = 1.0/rsq;
r6inv = r2inv*r2inv*r2inv; r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fforce = factor_lj*forcelj*r2inv; fpair = factor_lj*forcelj*r2inv;
if (eflag) phi = r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) - if (eflag) evdwl = r6inv*(r6inv*lj3[itype][jtype]-lj4[itype][jtype]) -
offset[itype][jtype]; offset[itype][jtype];
break; break;
@ -139,11 +140,11 @@ void PairColloid::compute(int eflag, int vflag)
K[3] *= K[3]*K[3]; K[3] *= K[3]*K[3];
K[6] = K[3]*K[3]; K[6] = K[3]*K[3];
fR = sigma3[itype][jtype]*a12[itype][jtype]*c2*K[1]/K[3]; fR = sigma3[itype][jtype]*a12[itype][jtype]*c2*K[1]/K[3];
fforce = 4.0/15.0*sqrt(rsq)*fR*factor_lj * fpair = 4.0/15.0*sqrt(rsq)*fR*factor_lj *
(2.0*(K[1]+K[2]) * (K[1]*(5.0*K[1]+22.0*K[2])+5.0*K[4]) * (2.0*(K[1]+K[2]) * (K[1]*(5.0*K[1]+22.0*K[2])+5.0*K[4]) *
sigma6[itype][jtype]/K[6]-5.0) / K[0]; sigma6[itype][jtype]/K[6]-5.0) / K[0];
if (eflag) if (eflag)
phi = 2.0/9.0*fR * evdwl = 2.0/9.0*fR *
(1.0-(K[1]*(K[1]*(K[1]/3.0+3.0*K[2])+4.2*K[4])+K[2]*K[4]) * (1.0-(K[1]*(K[1]*(K[1]/3.0+3.0*K[2])+4.2*K[4])+K[2]*K[4]) *
sigma6[itype][jtype]/K[6]) - offset[itype][jtype]; sigma6[itype][jtype]/K[6]) - offset[itype][jtype];
break; break;
@ -175,43 +176,34 @@ void PairColloid::compute(int eflag, int vflag)
g[3] *= -42.0*K[0]/K[6]+6.0*K[2]+K[6]; g[3] *= -42.0*K[0]/K[6]+6.0*K[2]+K[6];
fR = a12[itype][jtype]*sigma6[itype][jtype]/r/37800.0; fR = a12[itype][jtype]*sigma6[itype][jtype]/r/37800.0;
phi = fR * (h[0]-h[1]-h[2]+h[3]); evdwl = fR * (h[0]-h[1]-h[2]+h[3]);
dUR = phi/r + 5.0*fR*(g[0]+g[1]-g[2]-g[3]); dUR = evdwl/r + 5.0*fR*(g[0]+g[1]-g[2]-g[3]);
dUA = -a12[itype][jtype]/3.0*r*((2.0*K[0]*K[7]+1.0)*K[7] + dUA = -a12[itype][jtype]/3.0*r*((2.0*K[0]*K[7]+1.0)*K[7] +
(2.0*K[0]*K[8]-1.0)*K[8]); (2.0*K[0]*K[8]-1.0)*K[8]);
fforce = factor_lj * (dUR+dUA)/r; fpair = factor_lj * (dUR+dUA)/r;
if (eflag) if (eflag)
phi += a12[itype][jtype]/6.0*(2.0*K[0]*(K[7]+K[8])-log(K[8]/K[7])) - evdwl += a12[itype][jtype]/6.0 *
offset[itype][jtype]; (2.0*K[0]*(K[7]+K[8])-log(K[8]/K[7])) - offset[itype][jtype];
break; break;
} }
if (eflag) { if (eflag) evdwl *= factor_lj;
if (newton_pair || j < nlocal) eng_vdwl += factor_lj*phi;
else eng_vdwl += 0.5*factor_lj*phi;
}
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,0.0,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -61,8 +61,8 @@ PairLubricate::~PairLubricate()
void PairLubricate::compute(int eflag, int vflag) void PairLubricate::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz; double xtmp,ytmp,ztmp,delx,dely,delz,fpair,fx,fy,fz;
double rsq,r,h_sep,radi,fforce,f1,f2,f3; double rsq,r,h_sep,radi;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3;
double vt1,vt2,vt3,w1,w2,w3,v_shear1,v_shear2,v_shear3; double vt1,vt2,vt3,w1,w2,w3,v_shear1,v_shear2,v_shear3;
double omega_t_1,omega_t_2,omega_t_3; double omega_t_1,omega_t_2,omega_t_3;
@ -71,11 +71,10 @@ void PairLubricate::compute(int eflag, int vflag)
double P_dot_wrel_1,P_dot_wrel_2,P_dot_wrel_3; double P_dot_wrel_1,P_dot_wrel_2,P_dot_wrel_3;
double a_squeeze,a_shear,a_pump,a_twist; double a_squeeze,a_shear,a_pump,a_twist;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
double PI = 4.0*atan(1.0); double PI = 4.0*atan(1.0);
eng_vdwl = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **v = atom->v; double **v = atom->v;
@ -212,11 +211,11 @@ void PairLubricate::compute(int eflag, int vflag)
(h_sep/2.0/radi) * log(2.0/(2.0*h_sep)); (h_sep/2.0/radi) * log(2.0/(2.0*h_sep));
if (h_sep >= cut_inner[itype][jtype]) { if (h_sep >= cut_inner[itype][jtype]) {
f1 = -a_squeeze*vn1 - a_shear*(2.0/r)*(2.0/r)*vt1 + fx = -a_squeeze*vn1 - a_shear*(2.0/r)*(2.0/r)*vt1 +
(2.0/r)*a_shear*n_cross_omega_t_1; (2.0/r)*a_shear*n_cross_omega_t_1;
f2 = -a_squeeze*vn2 - a_shear*(2.0/r)*(2.0/r)*vt2 + fy = -a_squeeze*vn2 - a_shear*(2.0/r)*(2.0/r)*vt2 +
(2.0/r)*a_shear*n_cross_omega_t_2; (2.0/r)*a_shear*n_cross_omega_t_2;
f3 = -a_squeeze*vn3 - a_shear*(2.0/r)*(2.0/r)*vt3 + fz = -a_squeeze*vn3 - a_shear*(2.0/r)*(2.0/r)*vt3 +
(2.0/r)*a_shear*n_cross_omega_t_3; (2.0/r)*a_shear*n_cross_omega_t_3;
torque[i][0] += -(2.0/r)*a_shear*v_shear1 - a_shear*omega_t_1 - torque[i][0] += -(2.0/r)*a_shear*v_shear1 - a_shear*omega_t_1 -
@ -227,20 +226,20 @@ void PairLubricate::compute(int eflag, int vflag)
a_pump*P_dot_wrel_3 - a_twist*wn3; a_pump*P_dot_wrel_3 - a_twist*wn3;
} else { } else {
fforce = -vnnr*(3.0*PI*mu*radi/2.0)*radi/4.0/cut_inner[itype][jtype]; fpair = -vnnr*(3.0*PI*mu*radi/2.0)*radi/4.0/cut_inner[itype][jtype];
f1 = fforce*delx/r; fx = fpair*delx/r;
f2 = fforce*dely/r; fy = fpair*dely/r;
f3 = fforce*delz/r; fz = fpair*delz/r;
} }
f[i][0] += f1; f[i][0] += fx;
f[i][1] += f2; f[i][1] += fy;
f[i][2] += f3; f[i][2] += fz;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= f1; f[j][0] -= fx;
f[j][1] -= f2; f[j][1] -= fy;
f[j][2] -= f3; f[j][2] -= fz;
if (h_sep >= cut_inner[itype][jtype]) { if (h_sep >= cut_inner[itype][jtype]) {
torque[j][0] += -(2.0/r)*a_shear*v_shear1 - a_shear*omega_t_1 + torque[j][0] += -(2.0/r)*a_shear*v_shear1 - a_shear*omega_t_1 +
@ -252,23 +251,13 @@ void PairLubricate::compute(int eflag, int vflag)
} }
} }
if (vflag == 1) { if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) { 0.0,0.0,fx,fy,fz,delx,dely,delz);
f1 *= 0.5;
f2 *= 0.5;
f3 *= 0.5;
}
virial[0] += delx*f1;
virial[1] += dely*f2;
virial[2] += delz*f3;
virial[3] += delx*f2;
virial[4] += delx*f3;
virial[5] += dely*f3;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -61,18 +61,17 @@ PairDipoleCut::~PairDipoleCut()
void PairDipoleCut::compute(int eflag, int vflag) void PairDipoleCut::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fx,fy,fz;
double rsq,rinv,r2inv,r6inv,r3inv,r5inv,r7inv; double rsq,rinv,r2inv,r6inv,r3inv,r5inv,r7inv;
double forcecoulx,forcecouly,forcecoulz,fforce,crossx,crossy,crossz; double forcecoulx,forcecouly,forcecoulz,crossx,crossy,crossz;
double tixcoul,tiycoul,tizcoul,tjxcoul,tjycoul,tjzcoul; double tixcoul,tiycoul,tizcoul,tjxcoul,tjycoul,tjzcoul;
double fq,fx,fy,fz; double fq,pdotp,pidotr,pjdotr,pre1,pre2,pre3,pre4;
double pdotp,pidotr,pjdotr,pre1,pre2,pre3,pre4;
double forcelj,factor_coul,factor_lj; double forcelj,factor_coul,factor_lj;
double factor,phicoul,philj;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = eng_coul = 0.0; evdwl = ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -82,7 +81,7 @@ void PairDipoleCut::compute(int eflag, int vflag)
int *type = atom->type; int *type = atom->type;
double *dipole = atom->dipole; double *dipole = atom->dipole;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -209,15 +208,15 @@ void PairDipoleCut::compute(int eflag, int vflag)
if (rsq < cut_ljsq[itype][jtype]) { if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv; r6inv = r2inv*r2inv*r2inv;
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fforce = factor_lj * forcelj*r2inv; forcelj *= factor_lj * r2inv;
} else fforce = 0.0; } else forcelj = 0.0;
// total force // total force
fq = factor_coul*qqrd2e; fq = factor_coul*qqrd2e;
fx = fq*forcecoulx + delx*fforce; fx = fq*forcecoulx + delx*forcelj;
fy = fq*forcecouly + dely*fforce; fy = fq*forcecouly + dely*forcelj;
fz = fq*forcecoulz + delz*fforce; fz = fq*forcecoulz + delz*forcelj;
// force & torque accumulation // force & torque accumulation
@ -238,42 +237,31 @@ void PairDipoleCut::compute(int eflag, int vflag)
} }
if (eflag) { if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq[itype][jtype]) { if (rsq < cut_coulsq[itype][jtype]) {
phicoul = qtmp*q[j]*rinv; ecoul = qtmp*q[j]*rinv;
if (dipole[itype] > 0.0 && dipole[jtype] > 0.0) if (dipole[itype] > 0.0 && dipole[jtype] > 0.0)
phicoul += r3inv*pdotp - 3.0*r5inv*pidotr*pjdotr; ecoul += r3inv*pdotp - 3.0*r5inv*pidotr*pjdotr;
if (dipole[itype] > 0.0 && q[j] != 0.0) if (dipole[itype] > 0.0 && q[j] != 0.0)
phicoul += -q[j]*r3inv*pidotr; ecoul += -q[j]*r3inv*pidotr;
if (dipole[jtype] > 0.0 && qtmp != 0.0) if (dipole[jtype] > 0.0 && qtmp != 0.0)
phicoul += qtmp*r3inv*pjdotr; ecoul += qtmp*r3inv*pjdotr;
eng_coul += factor*factor_coul*qqrd2e*phicoul; ecoul *= factor_coul*qqrd2e;
} } else ecoul = 0.0;
if (rsq < cut_ljsq[itype][jtype]) { if (rsq < cut_ljsq[itype][jtype]) {
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype]; offset[itype][jtype];
eng_vdwl += factor*factor_lj*philj; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (vflag == 1) { if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) { evdwl,ecoul,fx,fy,fz,delx,dely,delz);
fx *= 0.5; fy *= 0.5; fz *= 0.5;
}
virial[0] += delx*fx;
virial[1] += dely*fy;
virial[2] += delz*fz;
virial[3] += delx*fy;
virial[4] += delx*fz;
virial[5] += dely*fz;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -65,19 +65,21 @@ PairDPD::~PairDPD()
void PairDPD::compute(int eflag, int vflag) void PairDPD::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz,vxtmp,vytmp,vztmp,delvx,delvy,delvz; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r,rinv,dot,wd,randnum,fforce,factor_dpd,phi; double vxtmp,vytmp,vztmp,delvx,delvy,delvz;
double rsq,r,rinv,dot,wd,randnum,factor_dpd;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = 0.0; evdwl = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **v = atom->v; double **v = atom->v;
double **f = atom->f; double **f = atom->f;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
double dtinvsqrt = 1.0/sqrt(update->dt); double dtinvsqrt = 1.0/sqrt(update->dt);
@ -131,39 +133,32 @@ void PairDPD::compute(int eflag, int vflag)
// drag force = -gamma * wd^2 * (delx dot delv) / r // drag force = -gamma * wd^2 * (delx dot delv) / r
// random force = sigma * wd * rnd * dtinvsqrt; // random force = sigma * wd * rnd * dtinvsqrt;
fforce = a0[itype][jtype]*wd; fpair = a0[itype][jtype]*wd;
fforce -= gamma[itype][jtype]*wd*wd*dot*rinv; fpair -= gamma[itype][jtype]*wd*wd*dot*rinv;
fforce += sigma[itype][jtype]*wd*randnum*dtinvsqrt; fpair += sigma[itype][jtype]*wd*randnum*dtinvsqrt;
fforce *= factor_dpd*rinv; fpair *= factor_dpd*rinv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
phi = a0[itype][jtype] * r * (1.0 - 0.5*r/cut[itype][jtype]); evdwl = a0[itype][jtype] * r * (1.0 - 0.5*r/cut[itype][jtype]);
if (newton_pair || j < nlocal) eng_vdwl += factor_dpd*phi; evdwl *= factor_dpd;
else eng_vdwl += 0.5*factor_dpd*phi;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,0.0,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -40,21 +40,24 @@ PairGranHertzian::PairGranHertzian(LAMMPS *lmp) : PairGranHistory(lmp)
void PairGranHertzian::compute(int eflag, int vflag) void PairGranHertzian::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum; int i,j,ii,jj,inum,jnum;
double xtmp,ytmp,ztmp,delx,dely,delz; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv; double radi,radj,radsum,rsq,r,rinv;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3; double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel; double vtr1,vtr2,vtr3,vrel;
double xmeff,damp,ccel,ccelx,ccely,ccelz,tor1,tor2,tor3; double xmeff,damp,ccel,tor1,tor2,tor3;
double fn,fs,fs1,fs2,fs3; double fn,fs,fs1,fs2,fs3;
double shrmag,rsht,rhertz; double shrmag,rsht,rhertz;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
int *touch,**firsttouch; int *touch,**firsttouch;
double *shear,*allshear,**firstshear; double *shear,*allshear,**firstshear;
double **f = atom->f; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **v = atom->v; double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega; double **omega = atom->omega;
double **torque = atom->torque; double **torque = atom->torque;
double *radius = atom->radius; double *radius = atom->radius;
@ -209,12 +212,12 @@ void PairGranHertzian::compute(int eflag, int vflag)
// forces & torques // forces & torques
ccelx = delx*ccel + fs1; fx = delx*ccel + fs1;
ccely = dely*ccel + fs2; fy = dely*ccel + fs2;
ccelz = delz*ccel + fs3; fz = delz*ccel + fs3;
f[i][0] += ccelx; f[i][0] += fx;
f[i][1] += ccely; f[i][1] += fy;
f[i][2] += ccelz; f[i][2] += fz;
rinv = 1/r; rinv = 1/r;
tor1 = rinv * (dely*fs3 - delz*fs2); tor1 = rinv * (dely*fs3 - delz*fs2);
@ -225,13 +228,16 @@ void PairGranHertzian::compute(int eflag, int vflag)
torque[i][2] -= radi*tor3; torque[i][2] -= radi*tor3;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= ccelx; f[j][0] -= fx;
f[j][1] -= ccely; f[j][1] -= fy;
f[j][2] -= ccelz; f[j][2] -= fz;
torque[j][0] -= radj*tor1; torque[j][0] -= radj*tor1;
torque[j][1] -= radj*tor2; torque[j][1] -= radj*tor2;
torque[j][2] -= radj*tor3; torque[j][2] -= radj*tor3;
} }
if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,
0.0,0.0,fx,fy,fz,delx,dely,delz);
} }
} }
} }

View File

@ -45,8 +45,6 @@ using namespace LAMMPS_NS;
PairGranHistory::PairGranHistory(LAMMPS *lmp) : Pair(lmp) PairGranHistory::PairGranHistory(LAMMPS *lmp) : Pair(lmp)
{ {
single_enable = 0; single_enable = 0;
for (int i = 0; i < 6; i++) virial[i] = 0.0;
history = 1; history = 1;
fix_history = NULL; fix_history = NULL;
} }
@ -68,21 +66,24 @@ PairGranHistory::~PairGranHistory()
void PairGranHistory::compute(int eflag, int vflag) void PairGranHistory::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum; int i,j,ii,jj,inum,jnum;
double xtmp,ytmp,ztmp,delx,dely,delz; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv; double radi,radj,radsum,rsq,r,rinv;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3; double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel; double vtr1,vtr2,vtr3,vrel;
double xmeff,damp,ccel,ccelx,ccely,ccelz,tor1,tor2,tor3; double xmeff,damp,ccel,tor1,tor2,tor3;
double fn,fs,fs1,fs2,fs3; double fn,fs,fs1,fs2,fs3;
double shrmag,rsht; double shrmag,rsht;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
int *touch,**firsttouch; int *touch,**firsttouch;
double *shear,*allshear,**firstshear; double *shear,*allshear,**firstshear;
double **f = atom->f; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **v = atom->v; double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega; double **omega = atom->omega;
double **torque = atom->torque; double **torque = atom->torque;
double *radius = atom->radius; double *radius = atom->radius;
@ -235,12 +236,12 @@ void PairGranHistory::compute(int eflag, int vflag)
// forces & torques // forces & torques
ccelx = delx*ccel + fs1; fx = delx*ccel + fs1;
ccely = dely*ccel + fs2; fy = dely*ccel + fs2;
ccelz = delz*ccel + fs3; fz = delz*ccel + fs3;
f[i][0] += ccelx; f[i][0] += fx;
f[i][1] += ccely; f[i][1] += fy;
f[i][2] += ccelz; f[i][2] += fz;
rinv = 1/r; rinv = 1/r;
tor1 = rinv * (dely*fs3 - delz*fs2); tor1 = rinv * (dely*fs3 - delz*fs2);
@ -251,13 +252,16 @@ void PairGranHistory::compute(int eflag, int vflag)
torque[i][2] -= radi*tor3; torque[i][2] -= radi*tor3;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= ccelx; f[j][0] -= fx;
f[j][1] -= ccely; f[j][1] -= fy;
f[j][2] -= ccelz; f[j][2] -= fz;
torque[j][0] -= radj*tor1; torque[j][0] -= radj*tor1;
torque[j][1] -= radj*tor2; torque[j][1] -= radj*tor2;
torque[j][2] -= radj*tor3; torque[j][2] -= radj*tor3;
} }
if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,
0.0,0.0,fx,fy,fz,delx,dely,delz);
} }
} }
} }

View File

@ -40,18 +40,21 @@ PairGranNoHistory::PairGranNoHistory(LAMMPS *lmp) : PairGranHistory(lmp)
void PairGranNoHistory::compute(int eflag, int vflag) void PairGranNoHistory::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum; int i,j,ii,jj,inum,jnum;
double xtmp,ytmp,ztmp,delx,dely,delz; double xtmp,ytmp,ztmp,delx,dely,delz,fx,fy,fz;
double radi,radj,radsum,rsq,r,rinv; double radi,radj,radsum,rsq,r,rinv;
double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3; double vr1,vr2,vr3,vnnr,vn1,vn2,vn3,vt1,vt2,vt3;
double wr1,wr2,wr3; double wr1,wr2,wr3;
double vtr1,vtr2,vtr3,vrel; double vtr1,vtr2,vtr3,vrel;
double xmeff,damp,ccel,ccelx,ccely,ccelz,tor1,tor2,tor3; double xmeff,damp,ccel,tor1,tor2,tor3;
double fn,fs,ft,fs1,fs2,fs3; double fn,fs,ft,fs1,fs2,fs3;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
double **f = atom->f; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **v = atom->v; double **v = atom->v;
double **f = atom->f;
double **omega = atom->omega; double **omega = atom->omega;
double **torque = atom->torque; double **torque = atom->torque;
double *radius = atom->radius; double *radius = atom->radius;
@ -154,12 +157,12 @@ void PairGranNoHistory::compute(int eflag, int vflag)
// forces & torques // forces & torques
ccelx = delx*ccel + fs1; fx = delx*ccel + fs1;
ccely = dely*ccel + fs2; fy = dely*ccel + fs2;
ccelz = delz*ccel + fs3; fz = delz*ccel + fs3;
f[i][0] += ccelx; f[i][0] += fx;
f[i][1] += ccely; f[i][1] += fy;
f[i][2] += ccelz; f[i][2] += fz;
rinv = 1/r; rinv = 1/r;
tor1 = rinv * (dely*fs3 - delz*fs2); tor1 = rinv * (dely*fs3 - delz*fs2);
@ -170,14 +173,19 @@ void PairGranNoHistory::compute(int eflag, int vflag)
torque[i][2] -= radi*tor3; torque[i][2] -= radi*tor3;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= ccelx; f[j][0] -= fx;
f[j][1] -= ccely; f[j][1] -= fy;
f[j][2] -= ccelz; f[j][2] -= fz;
torque[j][0] -= radj*tor1; torque[j][0] -= radj*tor1;
torque[j][1] -= radj*tor2; torque[j][1] -= radj*tor2;
torque[j][2] -= radj*tor3; torque[j][2] -= radj*tor3;
} }
if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,
0.0,0.0,fx,fy,fz,delx,dely,delz);
} }
} }
} }
if (vflag_fdotr) virial_compute();
} }

View File

@ -67,21 +67,22 @@ PairBuckCoulLong::~PairBuckCoulLong()
void PairBuckCoulLong::compute(int eflag, int vflag) void PairBuckCoulLong::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r2inv,r6inv,forcecoul,forcebuck,fforce,factor_coul,factor_lj; double rsq,r2inv,r6inv,forcecoul,forcebuck,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc; double grij,expm2,prefactor,t,erfc;
double factor,phicoul,phibuck,r,rexp; double r,rexp;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = eng_coul = 0.0; evdwl = ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -141,45 +142,36 @@ void PairBuckCoulLong::compute(int eflag, int vflag)
forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv; forcebuck = buck1[itype][jtype]*r*rexp - buck2[itype][jtype]*r6inv;
} else forcebuck = 0.0; } else forcebuck = 0.0;
fforce = (forcecoul + factor_lj*forcebuck) * r2inv; fpair = (forcecoul + factor_lj*forcebuck) * r2inv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq) { if (rsq < cut_coulsq) {
phicoul = prefactor*erfc; ecoul = prefactor*erfc;
if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
eng_coul += factor*phicoul; } else ecoul = 0.0;
}
if (rsq < cut_ljsq[itype][jtype]) { if (rsq < cut_ljsq[itype][jtype]) {
phibuck = a[itype][jtype]*rexp - c[itype][jtype]*r6inv - evdwl = a[itype][jtype]*rexp - c[itype][jtype]*r6inv -
offset[itype][jtype]; offset[itype][jtype];
eng_vdwl += factor*factor_lj*phibuck; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,ecoul,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -68,22 +68,23 @@ PairCoulLong::~PairCoulLong()
void PairCoulLong::compute(int eflag, int vflag) void PairCoulLong::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itable; int i,j,ii,jj,inum,jnum,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double r,r2inv,forcecoul,fforce,factor_coul; double fraction,table;
double r,r2inv,forcecoul,factor_coul;
double grij,expm2,prefactor,t,erfc; double grij,expm2,prefactor,t,erfc;
double phicoul;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
float rsq; float rsq;
int *int_rsq = (int *) &rsq; int *int_rsq = (int *) &rsq;
eng_coul = 0.0; ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double *q = atom->q; double *q = atom->q;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
double qqrd2e = force->qqrd2e; double qqrd2e = force->qqrd2e;
@ -142,43 +143,36 @@ void PairCoulLong::compute(int eflag, int vflag)
} }
} }
fforce = forcecoul * r2inv; fpair = forcecoul * r2inv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
if (!ncoultablebits || rsq <= tabinnersq) if (!ncoultablebits || rsq <= tabinnersq)
phicoul = prefactor*erfc; ecoul = prefactor*erfc;
else { else {
table = etable[itable] + fraction*detable[itable]; table = etable[itable] + fraction*detable[itable];
phicoul = qtmp*q[j] * table; ecoul = qtmp*q[j] * table;
} }
if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
if (newton_pair || j < nlocal) eng_coul += phicoul;
else eng_coul += 0.5*phicoul;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; 0.0,ecoul,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
allocate all arrays allocate all arrays
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */

View File

@ -84,23 +84,25 @@ PairLJCharmmCoulLong::~PairLJCharmmCoulLong()
void PairLJCharmmCoulLong::compute(int eflag, int vflag) void PairLJCharmmCoulLong::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype,itable; int i,j,ii,jj,inum,jnum,itype,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double r,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double fraction,table;
double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc; double grij,expm2,prefactor,t,erfc;
double factor,phicoul,philj,switch1,switch2; double philj,switch1,switch2;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
float rsq; float rsq;
int *int_rsq = (int *) &rsq; int *int_rsq = (int *) &rsq;
eng_vdwl = eng_coul = 0.0; evdwl = ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -179,54 +181,46 @@ void PairLJCharmmCoulLong::compute(int eflag, int vflag)
} }
} else forcelj = 0.0; } else forcelj = 0.0;
fforce = (forcecoul + factor_lj*forcelj) * r2inv; fpair = (forcecoul + factor_lj*forcelj) * r2inv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq) { if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) if (!ncoultablebits || rsq <= tabinnersq)
phicoul = prefactor*erfc; ecoul = prefactor*erfc;
else { else {
table = etable[itable] + fraction*detable[itable]; table = etable[itable] + fraction*detable[itable];
phicoul = qtmp*q[j] * table; ecoul = qtmp*q[j] * table;
} }
if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
eng_coul += factor*phicoul; } else ecoul = 0.0;
}
if (rsq < cut_ljsq) { if (rsq < cut_ljsq) {
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
if (rsq > cut_lj_innersq) { if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj;
philj *= switch1; evdwl *= switch1;
} }
eng_vdwl += factor*factor_lj*philj; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,ecoul,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -234,8 +228,8 @@ void PairLJCharmmCoulLong::compute(int eflag, int vflag)
void PairLJCharmmCoulLong::compute_inner() void PairLJCharmmCoulLong::compute_inner()
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fpair;
double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double rsw; double rsw;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
@ -244,7 +238,7 @@ void PairLJCharmmCoulLong::compute_inner()
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -298,20 +292,20 @@ void PairLJCharmmCoulLong::compute_inner()
jtype = type[j]; jtype = type[j];
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fforce = (forcecoul + factor_lj*forcelj) * r2inv; fpair = (forcecoul + factor_lj*forcelj) * r2inv;
if (rsq > cut_out_on_sq) { if (rsq > cut_out_on_sq) {
rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
fforce *= 1.0 + rsw*rsw*(2.0*rsw-3.0); fpair *= 1.0 + rsw*rsw*(2.0*rsw-3.0);
} }
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
} }
} }
@ -323,8 +317,8 @@ void PairLJCharmmCoulLong::compute_inner()
void PairLJCharmmCoulLong::compute_middle() void PairLJCharmmCoulLong::compute_middle()
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fpair;
double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double philj,switch1,switch2; double philj,switch1,switch2;
double rsw; double rsw;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
@ -334,7 +328,7 @@ void PairLJCharmmCoulLong::compute_middle()
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -402,23 +396,23 @@ void PairLJCharmmCoulLong::compute_middle()
forcelj = forcelj*switch1 + philj*switch2; forcelj = forcelj*switch1 + philj*switch2;
} }
fforce = (forcecoul + factor_lj*forcelj) * r2inv; fpair = (forcecoul + factor_lj*forcelj) * r2inv;
if (rsq < cut_in_on_sq) { if (rsq < cut_in_on_sq) {
rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff; rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff;
fforce *= rsw*rsw*(3.0 - 2.0*rsw); fpair *= rsw*rsw*(3.0 - 2.0*rsw);
} }
if (rsq > cut_out_on_sq) { if (rsq > cut_out_on_sq) {
rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
fforce *= 1.0 + rsw*rsw*(2.0*rsw - 3.0); fpair *= 1.0 + rsw*rsw*(2.0*rsw - 3.0);
} }
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
} }
} }
@ -430,24 +424,26 @@ void PairLJCharmmCoulLong::compute_middle()
void PairLJCharmmCoulLong::compute_outer(int eflag, int vflag) void PairLJCharmmCoulLong::compute_outer(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype,itable; int i,j,ii,jj,inum,jnum,itype,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double r,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double fraction,table;
double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc; double grij,expm2,prefactor,t,erfc;
double factor,phicoul,philj,switch1,switch2; double philj,switch1,switch2;
double rsw; double rsw;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
float rsq; float rsq;
int *int_rsq = (int *) &rsq; int *int_rsq = (int *) &rsq;
eng_vdwl = eng_coul = 0.0; evdwl = ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -548,46 +544,44 @@ void PairLJCharmmCoulLong::compute_outer(int eflag, int vflag)
forcelj *= rsw*rsw*(3.0 - 2.0*rsw); forcelj *= rsw*rsw*(3.0 - 2.0*rsw);
} }
} else forcelj = 0.0; } else forcelj = 0.0;
fpair = (forcecoul + forcelj) * r2inv;
fforce = (forcecoul + forcelj) * r2inv; f[i][0] += delx*fpair;
f[i][1] += dely*fpair;
f[i][0] += delx*fforce; f[i][2] += delz*fpair;
f[i][1] += dely*fforce;
f[i][2] += delz*fforce;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq) { if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) { if (!ncoultablebits || rsq <= tabinnersq) {
phicoul = prefactor*erfc; ecoul = prefactor*erfc;
if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else { } else {
table = etable[itable] + fraction*detable[itable]; table = etable[itable] + fraction*detable[itable];
phicoul = qtmp*q[j] * table; ecoul = qtmp*q[j] * table;
if (factor_coul < 1.0) { if (factor_coul < 1.0) {
table = ptable[itable] + fraction*dptable[itable]; table = ptable[itable] + fraction*dptable[itable];
prefactor = qtmp*q[j] * table; prefactor = qtmp*q[j] * table;
phicoul -= (1.0-factor_coul)*prefactor; ecoul -= (1.0-factor_coul)*prefactor;
} }
} }
eng_coul += factor*phicoul; } else ecoul = 0.0;
}
if (rsq < cut_ljsq) { if (rsq < cut_ljsq) {
r6inv = r2inv*r2inv*r2inv; r6inv = r2inv*r2inv*r2inv;
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
if (rsq > cut_lj_innersq) { if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj;
philj *= switch1; evdwl *= switch1;
} }
eng_vdwl += factor*factor_lj*philj; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (vflag) { if (vflag) {
@ -629,16 +623,11 @@ void PairLJCharmmCoulLong::compute_outer(int eflag, int vflag)
} }
} }
fforce = (forcecoul + factor_lj*forcelj) * r2inv; fpair = (forcecoul + factor_lj*forcelj) * r2inv;
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
} }
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,ecoul,fpair,delx,dely,delz);
} }
} }
} }

View File

@ -80,23 +80,24 @@ PairLJCutCoulLong::~PairLJCutCoulLong()
void PairLJCutCoulLong::compute(int eflag, int vflag) void PairLJCutCoulLong::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype,itable; int i,j,ii,jj,inum,jnum,itype,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double r,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double fraction,table;
double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc; double grij,expm2,prefactor,t,erfc;
double factor,phicoul,philj;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
float rsq; float rsq;
int *int_rsq = (int *) &rsq; int *int_rsq = (int *) &rsq;
eng_vdwl = eng_coul = 0.0; evdwl = ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -167,50 +168,42 @@ void PairLJCutCoulLong::compute(int eflag, int vflag)
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
} else forcelj = 0.0; } else forcelj = 0.0;
fforce = (forcecoul + factor_lj*forcelj) * r2inv; fpair = (forcecoul + factor_lj*forcelj) * r2inv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq) { if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) if (!ncoultablebits || rsq <= tabinnersq)
phicoul = prefactor*erfc; ecoul = prefactor*erfc;
else { else {
table = etable[itable] + fraction*detable[itable]; table = etable[itable] + fraction*detable[itable];
phicoul = qtmp*q[j] * table; ecoul = qtmp*q[j] * table;
} }
if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
eng_coul += factor*phicoul; } else ecoul = 0.0;
}
if (rsq < cut_ljsq[itype][jtype]) { if (rsq < cut_ljsq[itype][jtype]) {
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype]; offset[itype][jtype];
eng_vdwl += factor*factor_lj*philj; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,ecoul,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -218,8 +211,8 @@ void PairLJCutCoulLong::compute(int eflag, int vflag)
void PairLJCutCoulLong::compute_inner() void PairLJCutCoulLong::compute_inner()
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fpair;
double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double rsw; double rsw;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
@ -228,7 +221,7 @@ void PairLJCutCoulLong::compute_inner()
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -284,19 +277,19 @@ void PairLJCutCoulLong::compute_inner()
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
} else forcelj = 0.0; } else forcelj = 0.0;
fforce = (forcecoul + factor_lj*forcelj) * r2inv; fpair = (forcecoul + factor_lj*forcelj) * r2inv;
if (rsq > cut_out_on_sq) { if (rsq > cut_out_on_sq) {
rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
fforce *= 1.0 + rsw*rsw*(2.0*rsw-3.0); fpair *= 1.0 + rsw*rsw*(2.0*rsw-3.0);
} }
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
} }
} }
@ -308,8 +301,8 @@ void PairLJCutCoulLong::compute_inner()
void PairLJCutCoulLong::compute_middle() void PairLJCutCoulLong::compute_middle()
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fpair;
double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double rsw; double rsw;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
@ -318,7 +311,7 @@ void PairLJCutCoulLong::compute_middle()
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -379,23 +372,23 @@ void PairLJCutCoulLong::compute_middle()
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
} else forcelj = 0.0; } else forcelj = 0.0;
fforce = (forcecoul + factor_lj*forcelj) * r2inv; fpair = (forcecoul + factor_lj*forcelj) * r2inv;
if (rsq < cut_in_on_sq) { if (rsq < cut_in_on_sq) {
rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff; rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff;
fforce *= rsw*rsw*(3.0 - 2.0*rsw); fpair *= rsw*rsw*(3.0 - 2.0*rsw);
} }
if (rsq > cut_out_on_sq) { if (rsq > cut_out_on_sq) {
rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
fforce *= 1.0 + rsw*rsw*(2.0*rsw - 3.0); fpair *= 1.0 + rsw*rsw*(2.0*rsw - 3.0);
} }
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
} }
} }
@ -407,24 +400,25 @@ void PairLJCutCoulLong::compute_middle()
void PairLJCutCoulLong::compute_outer(int eflag, int vflag) void PairLJCutCoulLong::compute_outer(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype,itable; int i,j,ii,jj,inum,jnum,itype,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double r,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double fraction,table;
double r,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc; double grij,expm2,prefactor,t,erfc;
double factor,phicoul,philj;
double rsw; double rsw;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
float rsq; float rsq;
int *int_rsq = (int *) &rsq; int *int_rsq = (int *) &rsq;
eng_vdwl = eng_coul = 0.0; evdwl = ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -517,41 +511,39 @@ void PairLJCutCoulLong::compute_outer(int eflag, int vflag)
} }
} else forcelj = 0.0; } else forcelj = 0.0;
fforce = (forcecoul + forcelj) * r2inv; fpair = (forcecoul + forcelj) * r2inv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq) { if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) { if (!ncoultablebits || rsq <= tabinnersq) {
phicoul = prefactor*erfc; ecoul = prefactor*erfc;
if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
} else { } else {
table = etable[itable] + fraction*detable[itable]; table = etable[itable] + fraction*detable[itable];
phicoul = qtmp*q[j] * table; ecoul = qtmp*q[j] * table;
if (factor_coul < 1.0) { if (factor_coul < 1.0) {
table = ptable[itable] + fraction*dptable[itable]; table = ptable[itable] + fraction*dptable[itable];
prefactor = qtmp*q[j] * table; prefactor = qtmp*q[j] * table;
phicoul -= (1.0-factor_coul)*prefactor; ecoul -= (1.0-factor_coul)*prefactor;
} }
} }
eng_coul += factor*phicoul; } else ecoul = 0.0;
}
if (rsq < cut_ljsq[itype][jtype]) { if (rsq < cut_ljsq[itype][jtype]) {
r6inv = r2inv*r2inv*r2inv; r6inv = r2inv*r2inv*r2inv;
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype]; offset[itype][jtype];
eng_vdwl += factor*factor_lj*philj; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (vflag) { if (vflag) {
@ -576,16 +568,11 @@ void PairLJCutCoulLong::compute_outer(int eflag, int vflag)
} else if (rsq <= cut_in_on_sq) } else if (rsq <= cut_in_on_sq)
forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]); forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
fforce = (forcecoul + factor_lj*forcelj) * r2inv; fpair = (forcecoul + factor_lj*forcelj) * r2inv;
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5;
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
} }
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,ecoul,fpair,delx,dely,delz);
} }
} }
} }

View File

@ -71,7 +71,8 @@ PairLJCutCoulLongTIP4P::~PairLJCutCoulLongTIP4P()
void PairLJCutCoulLongTIP4P::compute(int eflag, int vflag) void PairLJCutCoulLongTIP4P::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype,itable; int i,j,ii,jj,inum,jnum,itype,jtype,itable;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,fraction,table; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double fraction,table;
double delx1,dely1,delz1,delx2,dely2,delz2,delx3,dely3,delz3; double delx1,dely1,delz1,delx2,dely2,delz2,delx3,dely3,delz3;
double r,r2inv,r6inv,forcecoul,forcelj,cforce,negforce; double r,r2inv,r6inv,forcecoul,forcelj,cforce,negforce;
double factor_coul,factor_lj; double factor_coul,factor_lj;
@ -85,35 +86,43 @@ void PairLJCutCoulLongTIP4P::compute(int eflag, int vflag)
float rsq; float rsq;
int *int_rsq = (int *) &rsq; int *int_rsq = (int *) &rsq;
// grow temporary force array if necessary evdwl = ecoul = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
if (atom->nmax > nmax) { // error check (for now)
memory->destroy_2d_double_array(ftmp);
nmax = atom->nmax;
ftmp = memory->create_2d_double_array(nmax,3,"pair:ftmp");
}
int nlocal = atom->nlocal; if (eflag_atom || vflag_atom)
int nall = atom->nlocal + atom->nghost; error->all("Pair style lj/cut/coul/long/tip4p does not yet support peratom energy/virial");
eng_vdwl = eng_coul = 0.0;
if (vflag) {
for (i = 0; i < 6; i++) virial[i] = virialtmp[i] = 0.0;
for (i = 0; i < nall; ++i) {
ftmp[i][0] = 0.0;
ftmp[i][1] = 0.0;
ftmp[i][2] = 0.0;
}
}
double **f = atom->f; double **f = atom->f;
double **x = atom->x; double **x = atom->x;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal;
int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair;
double qqrd2e = force->qqrd2e; double qqrd2e = force->qqrd2e;
// grow and zero temporary force array if necessary
if (vflag && atom->nmax > nmax) {
memory->destroy_2d_double_array(ftmp);
nmax = atom->nmax;
ftmp = memory->create_2d_double_array(nmax,3,"pair:ftmp");
}
if (vflag) {
for (i = 0; i < 6; i++) virialtmp[i] = 0.0;
for (i = 0; i < nall; i++) {
ftmp[i][0] = 0.0;
ftmp[i][1] = 0.0;
ftmp[i][2] = 0.0;
}
}
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
numneigh = list->numneigh; numneigh = list->numneigh;
@ -168,11 +177,11 @@ void PairLJCutCoulLongTIP4P::compute(int eflag, int vflag)
f[j][2] -= delz*forcelj; f[j][2] -= delz*forcelj;
if (eflag) { if (eflag) {
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) - evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
offset[itype][jtype]; offset[itype][jtype];
eng_vdwl += factor_lj*philj; evdwl *= factor_lj*philj;
} }
} } else evdwl = 0.0;
// adjust rsq for off-site O charge(s) // adjust rsq for off-site O charge(s)
@ -380,23 +389,25 @@ void PairLJCutCoulLongTIP4P::compute(int eflag, int vflag)
virialtmp[5] += 0.5 * (delz1 * fO[1] + (delz2 + delz3) * fH[1]); virialtmp[5] += 0.5 * (delz1 * fO[1] + (delz2 + delz3) * fH[1]);
} }
} }
if (eflag) { if (eflag) {
if (!ncoultablebits || rsq <= tabinnersq) if (!ncoultablebits || rsq <= tabinnersq)
phicoul = prefactor*erfc; ecoul = prefactor*erfc;
else { else {
table = etable[itable] + fraction*detable[itable]; table = etable[itable] + fraction*detable[itable];
phicoul = qtmp*q[j] * table; ecoul = qtmp*q[j] * table;
} }
if (factor_coul < 1.0) phicoul -= (1.0-factor_coul)*prefactor; if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
eng_coul += phicoul;
} }
} } else ecoul = 0.0;
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,ecoul,fpair,delx,dely,delz);
} }
} }
} }
if (vflag == 2) { if (vflag_fdotr) {
virial_compute(); virial_compute();
for (int i = 0; i < 6; i++) virial[i] += virialtmp[i]; for (int i = 0; i < 6; i++) virial[i] += virialtmp[i];
for (int i = 0; i < nall; i++) { for (int i = 0; i < nall; i++) {
@ -622,6 +633,8 @@ void *PairLJCutCoulLongTIP4P::extract(char *str)
double PairLJCutCoulLongTIP4P::memory_usage() double PairLJCutCoulLongTIP4P::memory_usage()
{ {
double bytes = 3 * nmax * sizeof(double); double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
bytes += 3 * nmax * sizeof(double);
return bytes; return bytes;
} }

View File

@ -87,17 +87,20 @@ PairAIREBO::~PairAIREBO()
void PairAIREBO::compute(int eflag, int vflag) void PairAIREBO::compute(int eflag, int vflag)
{ {
eng_vdwl = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
if (vflag) for (int i = 0; i < 6; i++) virial[i] = 0.0; else evflag = vflag_fdotr = 0;
// error check (for now)
if (eflag_atom || vflag_atom)
error->all("Pair style airebo does not yet support peratom energy/virial");
double **f = atom->f;
REBO_neigh(); REBO_neigh();
FREBO(eflag,f); FREBO(eflag,vflag);
if (ljflag) FLJ(eflag,f); if (ljflag) FLJ(eflag,vflag);
if (torflag) TORSION(eflag,f); if (torflag) TORSION(eflag,vflag);
if (vflag == 2) virial_compute(); if (vflag_fdotr == 2) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -448,24 +451,30 @@ void PairAIREBO::REBO_neigh()
REBO forces and energy REBO forces and energy
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void PairAIREBO::FREBO(int eflag, double **f) void PairAIREBO::FREBO(int eflag, int vflag)
{ {
int i,j,k,m,itype,jtype; int i,j,k,m,itype,jtype;
double delx,dely,delz,rsq,rij,wij; double delx,dely,delz,evdwl,fpair;
double rsq,rij,wij;
double Qij,Aij,alphaij,VR,pre,dVRdi,VA,term,bij,dVAdi,dVA; double Qij,Aij,alphaij,VR,pre,dVRdi,VA,term,bij,dVAdi,dVA;
double dwij,fforce,del[3]; double dwij,del[3];
int *REBO_neighs; int *REBO_neighs;
evdwl = 0.0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f;
int *type = atom->type; int *type = atom->type;
int *tag = atom->tag; int *tag = atom->tag;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
// two-body interactions from REBO neighbor list, skip half of them // two-body interactions from REBO neighbor list, skip half of them
for (i = 0; i < nlocal; i++) { for (i = 0; i < nlocal; i++) {
itype = map[type[i]]; itype = map[type[i]];
REBO_neighs = REBO_firstneigh[i]; REBO_neighs = REBO_firstneigh[i];
for (k = 0; k < REBO_numneigh[i]; k++) { for (k = 0; k < REBO_numneigh[i]; k++) {
j = REBO_neighs[k]; j = REBO_neighs[k];
if (tag[i] > tag[j]) continue; if (tag[i] > tag[j]) continue;
@ -501,14 +510,17 @@ void PairAIREBO::FREBO(int eflag, double **f)
bij = bondorder(i,j,del,rij,VA,f); bij = bondorder(i,j,del,rij,VA,f);
dVAdi = bij*dVA; dVAdi = bij*dVA;
fforce = (dVRdi+dVAdi) / rij; fpair = -(dVRdi+dVAdi) / rij;
f[i][0] -= delx*fforce; f[i][0] += delx*fpair;
f[i][1] -= dely*fforce; f[i][1] += dely*fpair;
f[i][2] -= delz*fforce; f[i][2] += delz*fpair;
f[j][0] += delx*fforce; f[j][0] -= delx*fpair;
f[j][1] += dely*fforce; f[j][1] -= dely*fpair;
f[j][2] += delz*fforce; f[j][2] -= delz*fpair;
if (eflag) eng_vdwl += VR + bij*VA;
if (eflag) evdwl = VR + bij*VA;
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,0.0,fpair,delx,dely,delz);
} }
} }
} }
@ -518,29 +530,35 @@ void PairAIREBO::FREBO(int eflag, double **f)
find 3- and 4-step paths between atoms I,J via REBO neighbor lists find 3- and 4-step paths between atoms I,J via REBO neighbor lists
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void PairAIREBO::FLJ(int eflag, double **f) void PairAIREBO::FLJ(int eflag, int vflag)
{ {
int i,j,k,m,ii,jj,kk,mm,inum,jnum,itype,jtype,ktype,mtype; int i,j,k,m,ii,jj,kk,mm,inum,jnum,itype,jtype,ktype,mtype;
int atomi,atomj,atomk,atomm; int atomi,atomj,atomk,atomm;
int testpath,npath,done; int testpath,npath,done;
double evdwl,fpair;
double rsq,best,wik,wkm,cij,rij,dwij,dwik,dwkj,dwkm,dwmj; double rsq,best,wik,wkm,cij,rij,dwij,dwik,dwkj,dwkm,dwmj;
double delij[3],rijsq,delik[3],rik,delkj[3]; double delij[3],rijsq,delik[3],rik,delkj[3];
double rkj,wkj,dC,VLJ,dVLJ,fforce,VA,Str,dStr,Stb; double rkj,wkj,dC,VLJ,dVLJ,VA,Str,dStr,Stb;
double delkm[3],rkm,delmj[3],rmj,wmj,r2inv,r6inv,scale,delscale[3]; double delkm[3],rkm,delmj[3],rmj,wmj,r2inv,r6inv,scale,delscale[3];
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
int *REBO_neighs_i,*REBO_neighs_k; int *REBO_neighs_i,*REBO_neighs_k;
double delikS[3],delkjS[3],delkmS[3],delmjS[3]; double delikS[3],delkjS[3],delkmS[3],delmjS[3];
double rikS,rkjS,rkmS,rmjS,wikS,dwikS; double rikS,rkjS,rkmS,rmjS,wikS,dwikS;
double wkjS,dwkjS,wkmS,dwkmS,wmjS,dwmjS; double wkjS,dwkjS,wkmS,dwkmS,wmjS,dwmjS;
double fpair1,fpair2,fpair3;
// I-J interaction from full neighbor list // I-J interaction from full neighbor list
// skip 1/2 of interactions since only consider each pair once // skip 1/2 of interactions since only consider each pair once
evdwl = 0.0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f;
int *tag = atom->tag; int *tag = atom->tag;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
numneigh = list->numneigh; numneigh = list->numneigh;
@ -723,65 +741,75 @@ void PairAIREBO::FLJ(int eflag, double **f)
delscale[2] = scale * delij[2]; delscale[2] = scale * delij[2];
Stb = bondorderLJ(i,j,delscale,rcmin[itype][jtype],VA,delij,rij,f); Stb = bondorderLJ(i,j,delscale,rcmin[itype][jtype],VA,delij,rij,f);
} else Stb = 0.0; } else Stb = 0.0;
VA = VA*Stb + (1.0-Str)*cij*VLJ;
fforce = (dStr * (Stb*cij*VLJ - cij*VLJ) + fpair = -(dStr * (Stb*cij*VLJ - cij*VLJ) +
dVLJ * (Str*Stb*cij + cij - Str*cij)) / rij; dVLJ * (Str*Stb*cij + cij - Str*cij)) / rij;
f[i][0] -= delij[0]*fforce; f[i][0] += delij[0]*fpair;
f[i][1] -= delij[1]*fforce; f[i][1] += delij[1]*fpair;
f[i][2] -= delij[2]*fforce; f[i][2] += delij[2]*fpair;
f[j][0] += delij[0]*fforce; f[j][0] -= delij[0]*fpair;
f[j][1] += delij[1]*fforce; f[j][1] -= delij[1]*fpair;
f[j][2] += delij[2]*fforce; f[j][2] -= delij[2]*fpair;
if (eflag) eng_vdwl += VA; if (eflag) evdwl = VA*Stb + (1.0-Str)*cij*VLJ;
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,0.0,fpair,delij[0],delij[1],delij[2]);
if (cij < 1.0) { if (cij < 1.0) {
dC = -1.0*((Str*Stb*VLJ) + ((1.0-Str)*VLJ)); dC = Str*Stb*VLJ + (1.0-Str)*VLJ;
if (npath == 2) { if (npath == 2) {
fforce = dC*dwij / rij; fpair = dC*dwij / rij;
f[atomi][0] -= delij[0]*fforce; f[atomi][0] += delij[0]*fpair;
f[atomi][1] -= delij[1]*fforce; f[atomi][1] += delij[1]*fpair;
f[atomi][2] -= delij[2]*fforce; f[atomi][2] += delij[2]*fpair;
f[atomj][0] += delij[0]*fforce; f[atomj][0] -= delij[0]*fpair;
f[atomj][1] += delij[1]*fforce; f[atomj][1] -= delij[1]*fpair;
f[atomj][2] += delij[2]*fforce; f[atomj][2] -= delij[2]*fpair;
if (vflag_atom) ev_tally(atomi,atomj,nlocal,newton_pair,
0.0,0.0,fpair,delij[0],delij[1],delij[2]);
} else if (npath == 3) { } else if (npath == 3) {
fforce = dC*dwikS*wkjS / rikS; fpair1 = dC*dwikS*wkjS / rikS;
f[atomi][0] -= delikS[0]*fforce; f[atomi][0] += delikS[0]*fpair1;
f[atomi][1] -= delikS[1]*fforce; f[atomi][1] += delikS[1]*fpair1;
f[atomi][2] -= delikS[2]*fforce; f[atomi][2] += delikS[2]*fpair1;
f[atomk][0] += delikS[0]*fforce; f[atomk][0] -= delikS[0]*fpair1;
f[atomk][1] += delikS[1]*fforce; f[atomk][1] -= delikS[1]*fpair1;
f[atomk][2] += delikS[2]*fforce; f[atomk][2] -= delikS[2]*fpair1;
fforce = dC*wikS*dwkjS / rkjS; fpair2 = dC*wikS*dwkjS / rkjS;
f[atomk][0] -= delkjS[0]*fforce; f[atomk][0] += delkjS[0]*fpair2;
f[atomk][1] -= delkjS[1]*fforce; f[atomk][1] += delkjS[1]*fpair2;
f[atomk][2] -= delkjS[2]*fforce; f[atomk][2] += delkjS[2]*fpair2;
f[atomj][0] += delkjS[0]*fforce; f[atomj][0] -= delkjS[0]*fpair2;
f[atomj][1] += delkjS[1]*fforce; f[atomj][1] -= delkjS[1]*fpair2;
f[atomj][2] += delkjS[2]*fforce; f[atomj][2] -= delkjS[2]*fpair2;
if (vflag_atom)
v_tally3(atomi,atomj,atomk,fpair1,fpair2,delikS,delkjS);
} else { } else {
fforce = dC*dwikS*wkmS*wmjS / rikS; fpair1 = dC*dwikS*wkmS*wmjS / rikS;
f[atomi][0] -= delikS[0]*fforce; f[atomi][0] += delikS[0]*fpair1;
f[atomi][1] -= delikS[1]*fforce; f[atomi][1] += delikS[1]*fpair1;
f[atomi][2] -= delikS[2]*fforce; f[atomi][2] += delikS[2]*fpair1;
f[atomk][0] += delikS[0]*fforce; f[atomk][0] -= delikS[0]*fpair1;
f[atomk][1] += delikS[1]*fforce; f[atomk][1] -= delikS[1]*fpair1;
f[atomk][2] += delikS[2]*fforce; f[atomk][2] -= delikS[2]*fpair1;
fforce = dC*wikS*dwkmS*wmjS / rkmS; fpair2 = dC*wikS*dwkmS*wmjS / rkmS;
f[atomk][0] -= delkmS[0]*fforce; f[atomk][0] += delkmS[0]*fpair2;
f[atomk][1] -= delkmS[1]*fforce; f[atomk][1] += delkmS[1]*fpair2;
f[atomk][2] -= delkmS[2]*fforce; f[atomk][2] += delkmS[2]*fpair2;
f[atomm][0] += delkmS[0]*fforce; f[atomm][0] -= delkmS[0]*fpair2;
f[atomm][1] += delkmS[1]*fforce; f[atomm][1] -= delkmS[1]*fpair2;
f[atomm][2] += delkmS[2]*fforce; f[atomm][2] -= delkmS[2]*fpair2;
fforce = dC*wikS*wkmS*dwmjS / rmjS; fpair3 = dC*wikS*wkmS*dwmjS / rmjS;
f[atomm][0] -= delmjS[0]*fforce; f[atomm][0] += delmjS[0]*fpair3;
f[atomm][1] -= delmjS[1]*fforce; f[atomm][1] += delmjS[1]*fpair3;
f[atomm][2] -= delmjS[2]*fforce; f[atomm][2] += delmjS[2]*fpair3;
f[atomj][0] += delmjS[0]*fforce; f[atomj][0] -= delmjS[0]*fpair3;
f[atomj][1] += delmjS[1]*fforce; f[atomj][1] -= delmjS[1]*fpair3;
f[atomj][2] += delmjS[2]*fforce; f[atomj][2] -= delmjS[2]*fpair3;
if (vflag_atom)
v_tally4(atomi,atomj,atomk,atomm,
fpair1,fpair2,fpair3,delikS,delkmS,delmjS);
} }
} }
} }
@ -792,10 +820,10 @@ void PairAIREBO::FLJ(int eflag, double **f)
Torsional forces and energy Torsional forces and energy
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void PairAIREBO::TORSION(int eflag, double **f) void PairAIREBO::TORSION(int eflag, int vflag)
{ {
int i,j,k,l; int i,j,k,l;
double evdwl,fpair;
double cos321; double cos321;
double w21,dw21,cos234,w34,dw34; double w21,dw21,cos234,w34,dw34;
double cross321[3],cross321mag,cross234[3],cross234mag; double cross321[3],cross321mag,cross234[3],cross234mag;
@ -811,11 +839,15 @@ void PairAIREBO::TORSION(int eflag, double **f)
double dxidij,dxidik,dxidjk,dxjdji,dxjdjl,dxjdil; double dxidij,dxidik,dxidjk,dxjdji,dxjdjl,dxjdil;
double ddndij,ddndik,ddndjk,ddndjl,ddndil,dcwddn,dcwdn,dvpdcw,Ftmp[3]; double ddndij,ddndik,ddndjk,ddndjl,ddndil,dcwddn,dcwdn,dvpdcw,Ftmp[3];
double del32[3],rsq,r32,del23[3],del21[3],r21; double del32[3],rsq,r32,del23[3],del21[3],r21;
double deljk[3],del34[3],delil[3],fforce,r23,r34; double deljk[3],del34[3],delil[3],r23,r34;
double fi[3],fj[3],fk[3],fl[3];
int itype,jtype,ktype,ltype,kk,ll,jj; int itype,jtype,ktype,ltype,kk,ll,jj;
int *REBO_neighs_i,*REBO_neighs_j; int *REBO_neighs_i,*REBO_neighs_j;
evdwl = 0.0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f;
int *type = atom->type; int *type = atom->type;
int *tag = atom->tag; int *tag = atom->tag;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
@ -923,7 +955,8 @@ void PairAIREBO::TORSION(int eflag, double **f)
ekijl = epsilonT[ktype][ltype]; ekijl = epsilonT[ktype][ltype];
Ec = 256.0*ekijl/405.0; Ec = 256.0*ekijl/405.0;
Vtors = (Ec*(pow(cw2,5.0)))-(ekijl/10.0); Vtors = (Ec*(pow(cw2,5.0)))-(ekijl/10.0);
if (eflag) eng_vdwl += Vtors*w21*w23*w34*(1.0-tspjik)*(1.0-tspijl);
if (eflag) evdwl = Vtors*w21*w23*w34*(1.0-tspjik)*(1.0-tspijl);
dndij[0] = (cross234[1]*del21[2])-(cross234[2]*del21[1]); dndij[0] = (cross234[1]*del21[2])-(cross234[2]*del21[1]);
dndij[1] = (cross234[2]*del21[0])-(cross234[0]*del21[2]); dndij[1] = (cross234[2]*del21[0])-(cross234[0]*del21[2]);
@ -977,134 +1010,143 @@ void PairAIREBO::TORSION(int eflag, double **f)
dcwdn = 1.0/cwnom; dcwdn = 1.0/cwnom;
dvpdcw = (-1.0)*Ec*(-.5)*5.0*pow(cw2,4.0) * dvpdcw = (-1.0)*Ec*(-.5)*5.0*pow(cw2,4.0) *
w23*w21*w34*(1.0-tspjik)*(1.0-tspijl); w23*w21*w34*(1.0-tspjik)*(1.0-tspijl);
Ftmp[0] = dvpdcw*((dcwdn*dndij[0])+(dcwddn*ddndij*del23[0]/r23)); Ftmp[0] = dvpdcw*((dcwdn*dndij[0])+(dcwddn*ddndij*del23[0]/r23));
Ftmp[1] = dvpdcw*((dcwdn*dndij[1])+(dcwddn*ddndij*del23[1]/r23)); Ftmp[1] = dvpdcw*((dcwdn*dndij[1])+(dcwddn*ddndij*del23[1]/r23));
Ftmp[2] = dvpdcw*((dcwdn*dndij[2])+(dcwddn*ddndij*del23[2]/r23)); Ftmp[2] = dvpdcw*((dcwdn*dndij[2])+(dcwddn*ddndij*del23[2]/r23));
f[i][0] += Ftmp[0]; fi[0] = Ftmp[0];
f[i][1] += Ftmp[1]; fi[1] = Ftmp[1];
f[i][2] += Ftmp[2]; fi[2] = Ftmp[2];
f[j][0] -= Ftmp[0]; fj[0] = -Ftmp[0];
f[j][1] -= Ftmp[1]; fj[1] = -Ftmp[1];
f[j][2] -= Ftmp[2]; fj[2] = -Ftmp[2];
Ftmp[0] = dvpdcw*((dcwdn*dndik[0])+(dcwddn*ddndik*del21[0]/r21)); Ftmp[0] = dvpdcw*((dcwdn*dndik[0])+(dcwddn*ddndik*del21[0]/r21));
Ftmp[1] = dvpdcw*((dcwdn*dndik[1])+(dcwddn*ddndik*del21[1]/r21)); Ftmp[1] = dvpdcw*((dcwdn*dndik[1])+(dcwddn*ddndik*del21[1]/r21));
Ftmp[2] = dvpdcw*((dcwdn*dndik[2])+(dcwddn*ddndik*del21[2]/r21)); Ftmp[2] = dvpdcw*((dcwdn*dndik[2])+(dcwddn*ddndik*del21[2]/r21));
f[i][0] += Ftmp[0]; fi[0] += Ftmp[0];
f[i][1] += Ftmp[1]; fi[1] += Ftmp[1];
f[i][2] += Ftmp[2]; fi[2] += Ftmp[2];
f[k][0] -= Ftmp[0]; fk[0] = -Ftmp[0];
f[k][1] -= Ftmp[1]; fk[1] = -Ftmp[1];
f[k][2] -= Ftmp[2]; fk[2] = -Ftmp[2];
Ftmp[0] = (dvpdcw*dcwddn*ddndjk*deljk[0])/rjk; Ftmp[0] = (dvpdcw*dcwddn*ddndjk*deljk[0])/rjk;
Ftmp[1] = (dvpdcw*dcwddn*ddndjk*deljk[1])/rjk; Ftmp[1] = (dvpdcw*dcwddn*ddndjk*deljk[1])/rjk;
Ftmp[2] = (dvpdcw*dcwddn*ddndjk*deljk[2])/rjk; Ftmp[2] = (dvpdcw*dcwddn*ddndjk*deljk[2])/rjk;
f[j][0] += Ftmp[0]; fj[0] += Ftmp[0];
f[j][1] += Ftmp[1]; fj[1] += Ftmp[1];
f[j][2] += Ftmp[2]; fj[2] += Ftmp[2];
f[k][0] -= Ftmp[0]; fk[0] -= Ftmp[0];
f[k][1] -= Ftmp[1]; fk[1] -= Ftmp[1];
f[k][2] -= Ftmp[2]; fk[2] -= Ftmp[2];
Ftmp[0] = dvpdcw*((dcwdn*dndjl[0])+(dcwddn*ddndjl*del34[0]/r34)); Ftmp[0] = dvpdcw*((dcwdn*dndjl[0])+(dcwddn*ddndjl*del34[0]/r34));
Ftmp[1] = dvpdcw*((dcwdn*dndjl[1])+(dcwddn*ddndjl*del34[1]/r34)); Ftmp[1] = dvpdcw*((dcwdn*dndjl[1])+(dcwddn*ddndjl*del34[1]/r34));
Ftmp[2] = dvpdcw*((dcwdn*dndjl[2])+(dcwddn*ddndjl*del34[2]/r34)); Ftmp[2] = dvpdcw*((dcwdn*dndjl[2])+(dcwddn*ddndjl*del34[2]/r34));
f[j][0] += Ftmp[0]; fj[0] += Ftmp[0];
f[j][1] += Ftmp[1]; fj[1] += Ftmp[1];
f[j][2] += Ftmp[2]; fj[2] += Ftmp[2];
f[l][0] -= Ftmp[0]; fl[0] = -Ftmp[0];
f[l][1] -= Ftmp[1]; fl[1] = -Ftmp[1];
f[l][2] -= Ftmp[2]; fl[2] = -Ftmp[2];
Ftmp[0] = (dvpdcw*dcwddn*ddndil*delil[0])/ril; Ftmp[0] = (dvpdcw*dcwddn*ddndil*delil[0])/ril;
Ftmp[1] = (dvpdcw*dcwddn*ddndil*delil[1])/ril; Ftmp[1] = (dvpdcw*dcwddn*ddndil*delil[1])/ril;
Ftmp[2] = (dvpdcw*dcwddn*ddndil*delil[2])/ril; Ftmp[2] = (dvpdcw*dcwddn*ddndil*delil[2])/ril;
f[i][0] += Ftmp[0]; fi[0] += Ftmp[0];
f[i][1] += Ftmp[1]; fi[1] += Ftmp[1];
f[i][2] += Ftmp[2]; fi[2] += Ftmp[2];
f[l][0] -= Ftmp[0]; fl[0] -= Ftmp[0];
f[l][1] -= Ftmp[1]; fl[1] -= Ftmp[1];
f[l][2] -= Ftmp[2]; fl[2] -= Ftmp[2];
// coordination forces // coordination forces
fforce = Vtors*dw21*w23*w34*(1.0-tspjik)*(1.0-tspijl) / r21; fpair = Vtors*dw21*w23*w34*(1.0-tspjik)*(1.0-tspijl) / r21;
f[i][0] -= del21[0]*fforce; fi[0] -= del21[0]*fpair;
f[i][1] -= del21[1]*fforce; fi[1] -= del21[1]*fpair;
f[i][2] -= del21[2]*fforce; fi[2] -= del21[2]*fpair;
f[k][0] += del21[0]*fforce; fk[0] += del21[0]*fpair;
f[k][1] += del21[1]*fforce; fk[1] += del21[1]*fpair;
f[k][2] += del21[2]*fforce; fk[2] += del21[2]*fpair;
fforce = Vtors*w21*dw23*w34*(1.0-tspjik)*(1.0-tspijl) / r23; fpair = Vtors*w21*dw23*w34*(1.0-tspjik)*(1.0-tspijl) / r23;
f[i][0] -= del23[0]*fforce; fi[0] -= del23[0]*fpair;
f[i][1] -= del23[1]*fforce; fi[1] -= del23[1]*fpair;
f[i][2] -= del23[2]*fforce; fi[2] -= del23[2]*fpair;
f[j][0] += del23[0]*fforce; fj[0] += del23[0]*fpair;
f[j][1] += del23[1]*fforce; fj[1] += del23[1]*fpair;
f[j][2] += del23[2]*fforce; fj[2] += del23[2]*fpair;
fforce = Vtors*w21*w23*dw34*(1.0-tspjik)*(1.0-tspijl) / r34; fpair = Vtors*w21*w23*dw34*(1.0-tspjik)*(1.0-tspijl) / r34;
f[j][0] -= del34[0]*fforce; fj[0] -= del34[0]*fpair;
f[j][1] -= del34[1]*fforce; fj[1] -= del34[1]*fpair;
f[j][2] -= del34[2]*fforce; fj[2] -= del34[2]*fpair;
f[l][0] += del34[0]*fforce; fl[0] += del34[0]*fpair;
f[l][1] += del34[1]*fforce; fl[1] += del34[1]*fpair;
f[l][2] += del34[2]*fforce; fl[2] += del34[2]*fpair;
// additional cut off function forces // additional cut off function forces
fcpc = -Vtors*w21*w23*w34*dtsjik*(1.0-tspijl); fcpc = -Vtors*w21*w23*w34*dtsjik*(1.0-tspijl);
fforce = fcpc*dcidij/rij; fpair = fcpc*dcidij/rij;
f[i][0] += fforce*del23[0]; fi[0] += fpair*del23[0];
f[i][1] += fforce*del23[1]; fi[1] += fpair*del23[1];
f[i][2] += fforce*del23[2]; fi[2] += fpair*del23[2];
f[j][0] -= fforce*del23[0]; fj[0] -= fpair*del23[0];
f[j][1] -= fforce*del23[1]; fj[1] -= fpair*del23[1];
f[j][2] -= fforce*del23[2]; fj[2] -= fpair*del23[2];
fforce = fcpc*dcidik/rik; fpair = fcpc*dcidik/rik;
f[i][0] += fforce*del21[0]; fi[0] += fpair*del21[0];
f[i][1] += fforce*del21[1]; fi[1] += fpair*del21[1];
f[i][2] += fforce*del21[2]; fi[2] += fpair*del21[2];
f[k][0] -= fforce*del21[0]; fk[0] -= fpair*del21[0];
f[k][1] -= fforce*del21[1]; fk[1] -= fpair*del21[1];
f[k][2] -= fforce*del21[2]; fk[2] -= fpair*del21[2];
fforce = fcpc*dcidjk/rjk; fpair = fcpc*dcidjk/rjk;
f[j][0] += fforce*deljk[0]; fj[0] += fpair*deljk[0];
f[j][1] += fforce*deljk[1]; fj[1] += fpair*deljk[1];
f[j][2] += fforce*deljk[2]; fj[2] += fpair*deljk[2];
f[k][0] -= fforce*deljk[0]; fk[0] -= fpair*deljk[0];
f[k][1] -= fforce*deljk[1]; fk[1] -= fpair*deljk[1];
f[k][2] -= fforce*deljk[2]; fk[2] -= fpair*deljk[2];
fcpc = -Vtors*w21*w23*w34*(1.0-tspjik)*dtsijl; fcpc = -Vtors*w21*w23*w34*(1.0-tspjik)*dtsijl;
fforce = fcpc*dcjdji/rij; fpair = fcpc*dcjdji/rij;
f[i][0] += fforce*del23[0]; fi[0] += fpair*del23[0];
f[i][1] += fforce*del23[1]; fi[1] += fpair*del23[1];
f[i][2] += fforce*del23[2]; fi[2] += fpair*del23[2];
f[j][0] -= fforce*del23[0]; fj[0] -= fpair*del23[0];
f[j][1] -= fforce*del23[1]; fj[1] -= fpair*del23[1];
f[j][2] -= fforce*del23[2]; fj[2] -= fpair*del23[2];
fforce = fcpc*dcjdjl/rjl; fpair = fcpc*dcjdjl/rjl;
f[j][0] += fforce*del34[0]; fj[0] += fpair*del34[0];
f[j][1] += fforce*del34[1]; fj[1] += fpair*del34[1];
f[j][2] += fforce*del34[2]; fj[2] += fpair*del34[2];
f[l][0] -= fforce*del34[0]; fl[0] -= fpair*del34[0];
f[l][1] -= fforce*del34[1]; fl[1] -= fpair*del34[1];
f[l][2] -= fforce*del34[2]; fl[2] -= fpair*del34[2];
fforce = fcpc*dcjdil/ril; fpair = fcpc*dcjdil/ril;
f[i][0] += fforce*delil[0]; fi[0] += fpair*delil[0];
f[i][1] += fforce*delil[1]; fi[1] += fpair*delil[1];
f[i][2] += fforce*delil[2]; fi[2] += fpair*delil[2];
f[l][0] -= fforce*delil[0]; fl[0] -= fpair*delil[0];
f[l][1] -= fforce*delil[1]; fl[1] -= fpair*delil[1];
f[l][2] -= fforce*delil[2]; fl[2] -= fpair*delil[2];
// sum per-atom forces into atom force array
f[i][0] += fi[0]; f[i][1] += fi[1]; f[i][2] += fi[2];
f[j][0] += fj[0]; f[j][1] += fj[1]; f[j][2] += fj[2];
f[k][0] += fk[0]; f[k][1] += fk[1]; f[k][2] += fk[2];
f[l][0] += fl[0]; f[l][1] += fl[1]; f[l][2] += fl[2];
//if (evflag) ev_tally4(i,j,k,l,fi,fj,fk,fl);
} }
} }
} }
@ -2030,8 +2072,8 @@ double PairAIREBO::bondorderLJ(int i, int j, double rij[3], double rijmag,
tmp3pij = tmp3; tmp3pij = tmp3;
tmp = 0.0; tmp = 0.0;
tmp2 = 0.0; tmp2 = 0.0;
tmp3 = 0.0; tmp3 = 0.0;
Etmp=0.0; Etmp = 0.0;
REBO_neighs = REBO_firstneigh[j]; REBO_neighs = REBO_firstneigh[j];
for (l = 0; l < REBO_numneigh[j]; l++) { for (l = 0; l < REBO_numneigh[j]; l++) {
@ -3979,4 +4021,3 @@ void PairAIREBO::spline_init()
Tf[2][2][1] = -0.035140; Tf[2][2][1] = -0.035140;
for (i = 2; i < 10; i++) Tf[2][2][i] = -0.0040480; for (i = 2; i < 10; i++) Tf[2][2][i] = -0.0040480;
} }

View File

@ -82,9 +82,9 @@ class PairAIREBO : public Pair {
double Tf[5][5][10],Tdfdx[5][5][10],Tdfdy[5][5][10],Tdfdz[5][5][10]; double Tf[5][5][10],Tdfdx[5][5][10],Tdfdy[5][5][10],Tdfdz[5][5][10];
void REBO_neigh(); void REBO_neigh();
void FREBO(int, double **); void FREBO(int, int);
void FLJ(int, double **); void FLJ(int, int);
void TORSION(int, double **); void TORSION(int, int);
double bondorder(int, int, double *, double, double, double **); double bondorder(int, int, double *, double, double, double **);
double bondorderLJ(int, int, double *, double, double, double bondorderLJ(int, int, double *, double, double,
@ -114,4 +114,3 @@ class PairAIREBO : public Pair {
} }
#endif #endif

View File

@ -125,11 +125,15 @@ PairEAM::~PairEAM()
void PairEAM::compute(int eflag, int vflag) void PairEAM::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,m,inum,jnum,itype,jtype; int i,j,ii,jj,m,inum,jnum,itype,jtype;
double xtmp,ytmp,ztmp,delx,dely,delz; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,r,p,fforce,rhoip,rhojp,z2,z2p,recip,phi,phip,psip; double rsq,r,p,rhoip,rhojp,z2,z2p,recip,phip,psip,phi;
double *coeff; double *coeff;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
evdwl = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
// grow energy array if necessary // grow energy array if necessary
if (atom->nmax > nmax) { if (atom->nmax > nmax) {
@ -140,9 +144,6 @@ void PairEAM::compute(int eflag, int vflag)
fp = (double *) memory->smalloc(nmax*sizeof(double),"pair:fp"); fp = (double *) memory->smalloc(nmax*sizeof(double),"pair:fp");
} }
eng_vdwl = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
int *type = atom->type; int *type = atom->type;
@ -214,7 +215,11 @@ void PairEAM::compute(int eflag, int vflag)
p = MIN(p,1.0); p = MIN(p,1.0);
coeff = frho_spline[type2frho[type[i]]][m]; coeff = frho_spline[type2frho[type[i]]][m];
fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2]; fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2];
if (eflag) eng_vdwl += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; if (eflag) {
phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
if (eflag_global) eng_vdwl += phi;
if (eflag_atom) eatom[i] += phi;
}
} }
// communicate derivative of embedding function // communicate derivative of embedding function
@ -273,35 +278,26 @@ void PairEAM::compute(int eflag, int vflag)
phi = z2*recip; phi = z2*recip;
phip = z2p*recip - phi*recip; phip = z2p*recip - phi*recip;
psip = fp[i]*rhojp + fp[j]*rhoip + phip; psip = fp[i]*rhojp + fp[j]*rhoip + phip;
fforce = -psip*recip; fpair = -psip*recip;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) evdwl = phi;
if (newton_pair || j < nlocal) eng_vdwl += phi;
else eng_vdwl += 0.5*phi;
}
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,0.0,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -805,19 +801,6 @@ void PairEAM::single(int i, int j, int itype, int jtype,
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void PairEAM::single_embed(int i, int itype, double &phi)
{
double p = rho[i]*rdrho + 1.0;
int m = static_cast<int> (p);
m = MAX(1,MIN(m,nrho-1));
p -= m;
double *coeff = frho_spline[type2frho[itype]][m];
phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
}
/* ---------------------------------------------------------------------- */
int PairEAM::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc) int PairEAM::pack_comm(int n, int *list, double *buf, int pbc_flag, int *pbc)
{ {
int i,j,m; int i,j,m;
@ -872,7 +855,9 @@ void PairEAM::unpack_reverse_comm(int n, int *list, double *buf)
double PairEAM::memory_usage() double PairEAM::memory_usage()
{ {
double bytes = 2 * nmax * sizeof(double); double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
bytes += 2 * nmax * sizeof(double);
return bytes; return bytes;
} }

View File

@ -29,8 +29,6 @@ class PairEAM : public Pair {
double init_one(int, int); double init_one(int, int);
void single(int, int, int, int, double, double, double, int, One &); void single(int, int, int, int, double, double, double, int, One &);
void single_embed(int, int, double &);
int pack_comm(int, int *, double *, int, int *); int pack_comm(int, int *, double *, int, int *);
void unpack_comm(int, int, double *); void unpack_comm(int, int, double *);
int pack_reverse_comm(int, int, double *); int pack_reverse_comm(int, int, double *);

View File

@ -75,19 +75,21 @@ PairSW::~PairSW()
void PairSW::compute(int eflag, int vflag) void PairSW::compute(int eflag, int vflag)
{ {
int i,j,k,ii,jj,kk,inum,jnum,jnumm1,itag,jtag,itype,jtype,ktype,iparam; int i,j,k,ii,jj,kk,inum,jnum,jnumm1,itag,jtag,itype,jtype,ktype,iparam;
double xtmp,ytmp,ztmp,delx,dely,delz; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,rsq1,rsq2,eng,fforce; double rsq,rsq1,rsq2;
double delr1[3],delr2[3],fj[3],fk[3]; double delr1[3],delr2[3],fj[3],fk[3];
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = 0.0; evdwl = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
int *tag = atom->tag; int *tag = atom->tag;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
@ -134,15 +136,17 @@ void PairSW::compute(int eflag, int vflag)
iparam = elem2param[itype][jtype][jtype]; iparam = elem2param[itype][jtype][jtype];
if (rsq > params[iparam].cutsq) continue; if (rsq > params[iparam].cutsq) continue;
twobody(&params[iparam],rsq,fforce,eflag,eng); twobody(&params[iparam],rsq,fpair,eflag,evdwl);
if (eflag) eng_vdwl += eng; f[i][0] += delx*fpair;
f[i][0] += fforce*delx; f[i][1] += dely*fpair;
f[i][1] += fforce*dely; f[i][2] += delz*fpair;
f[i][2] += fforce*delz; f[j][0] -= delx*fpair;
f[j][0] -= fforce*delx; f[j][1] -= dely*fpair;
f[j][1] -= fforce*dely; f[j][2] -= delz*fpair;
f[j][2] -= fforce*delz;
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,0.0,fpair,delx,dely,delz);
} }
// three-body interactions // three-body interactions
@ -172,9 +176,8 @@ void PairSW::compute(int eflag, int vflag)
rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2]; rsq2 = delr2[0]*delr2[0] + delr2[1]*delr2[1] + delr2[2]*delr2[2];
if (rsq2 > params[iparam].cutsq) continue; if (rsq2 > params[iparam].cutsq) continue;
threebody(&params[iparam],rsq1,rsq2,delr1,delr2,fj,fk,eflag,eng); threebody(&params[iparam],rsq1,rsq2,delr1,delr2,fj,fk,eflag,evdwl);
if (eflag) eng_vdwl += eng;
f[i][0] -= fj[0] + fk[0]; f[i][0] -= fj[0] + fk[0];
f[i][1] -= fj[1] + fk[1]; f[i][1] -= fj[1] + fk[1];
f[i][2] -= fj[2] + fk[2]; f[i][2] -= fj[2] + fk[2];
@ -184,10 +187,13 @@ void PairSW::compute(int eflag, int vflag)
f[k][0] += fk[0]; f[k][0] += fk[0];
f[k][1] += fk[1]; f[k][1] += fk[1];
f[k][2] += fk[2]; f[k][2] += fk[2];
if (evflag) ev_tally3(i,j,k,evdwl,0.0,fj,fk,delr1,delr2);
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */

View File

@ -77,20 +77,22 @@ void PairTersoff::compute(int eflag, int vflag)
{ {
int i,j,k,ii,jj,kk,inum,jnum; int i,j,k,ii,jj,kk,inum,jnum;
int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk; int itag,jtag,itype,jtype,ktype,iparam_ij,iparam_ijk;
double xtmp,ytmp,ztmp,delx,dely,delz; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair;
double rsq,rsq1,rsq2,eng,fforce; double rsq,rsq1,rsq2;
double delr1[3],delr2[3],fi[3],fj[3],fk[3]; double delr1[3],delr2[3],fi[3],fj[3],fk[3];
double zeta_ij,prefactor; double zeta_ij,prefactor;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = 0.0; evdwl = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
int *tag = atom->tag; int *tag = atom->tag;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int newton_pair = force->newton_pair;
inum = list->inum; inum = list->inum;
ilist = list->ilist; ilist = list->ilist;
@ -129,23 +131,25 @@ void PairTersoff::compute(int eflag, int vflag)
jtype = map[type[j]]; jtype = map[type[j]];
delx = x[j][0] - xtmp; delx = xtmp - x[j][0];
dely = x[j][1] - ytmp; dely = ytmp - x[j][1];
delz = x[j][2] - ztmp; delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz; rsq = delx*delx + dely*dely + delz*delz;
iparam_ij = elem2param[itype][jtype][jtype]; iparam_ij = elem2param[itype][jtype][jtype];
if (rsq > params[iparam_ij].cutsq) continue; if (rsq > params[iparam_ij].cutsq) continue;
repulsive(&params[iparam_ij],rsq,fforce,eflag,eng); repulsive(&params[iparam_ij],rsq,fpair,eflag,evdwl);
if (eflag) eng_vdwl += eng; f[i][0] += delx*fpair;
f[i][0] += fforce*delx; f[i][1] += dely*fpair;
f[i][1] += fforce*dely; f[i][2] += delz*fpair;
f[i][2] += fforce*delz; f[j][0] -= delx*fpair;
f[j][0] -= fforce*delx; f[j][1] -= dely*fpair;
f[j][1] -= fforce*dely; f[j][2] -= delz*fpair;
f[j][2] -= fforce*delz;
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,0.0,fpair,delx,dely,delz);
} }
// three-body interactions // three-body interactions
@ -183,15 +187,17 @@ void PairTersoff::compute(int eflag, int vflag)
// pairwise force due to zeta // pairwise force due to zeta
force_zeta(&params[iparam_ij],rsq1,zeta_ij,fforce,prefactor,eflag,eng); force_zeta(&params[iparam_ij],rsq1,zeta_ij,fpair,prefactor,eflag,evdwl);
if (eflag) eng_vdwl += eng; f[i][0] += delr1[0]*fpair;
f[i][0] += fforce*delr1[0]; f[i][1] += delr1[1]*fpair;
f[i][1] += fforce*delr1[1]; f[i][2] += delr1[2]*fpair;
f[i][2] += fforce*delr1[2]; f[j][0] -= delr1[0]*fpair;
f[j][0] -= fforce*delr1[0]; f[j][1] -= delr1[1]*fpair;
f[j][1] -= fforce*delr1[1]; f[j][2] -= delr1[2]*fpair;
f[j][2] -= fforce*delr1[2];
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,0.0,-fpair,-delr1[0],-delr1[1],-delr1[2]);
// attractive term via loop over k // attractive term via loop over k
@ -219,10 +225,13 @@ void PairTersoff::compute(int eflag, int vflag)
f[k][0] += fk[0]; f[k][0] += fk[0];
f[k][1] += fk[1]; f[k][1] += fk[1];
f[k][2] += fk[2]; f[k][2] += fk[2];
if (evflag) ev_tally3(i,j,k,evdwl,0.0,fj,fk,delr1,delr2);
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -543,8 +552,7 @@ void PairTersoff::repulsive(Param *param, double rsq, double &fforce,
tmp_fc = ters_fc(r,param); tmp_fc = ters_fc(r,param);
tmp_fc_d = ters_fc_d(r,param); tmp_fc_d = ters_fc_d(r,param);
tmp_exp = exp(-param->lam1 * r); tmp_exp = exp(-param->lam1 * r);
fforce = param->biga * tmp_exp * (tmp_fc_d - tmp_fc*param->lam1) / r; fforce = -param->biga * tmp_exp * (tmp_fc_d - tmp_fc*param->lam1) / r;
if (eflag) eng = tmp_fc * param->biga * tmp_exp; if (eflag) eng = tmp_fc * param->biga * tmp_exp;
} }

View File

@ -14,6 +14,8 @@
#include "math.h" #include "math.h"
#include "angle.h" #include "angle.h"
#include "atom.h" #include "atom.h"
#include "force.h"
#include "memory.h"
#include "error.h" #include "error.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -22,8 +24,23 @@ using namespace LAMMPS_NS;
Angle::Angle(LAMMPS *lmp) : Pointers(lmp) Angle::Angle(LAMMPS *lmp) : Pointers(lmp)
{ {
energy = 0.0;
allocated = 0; allocated = 0;
PI = 4.0*atan(1.0); PI = 4.0*atan(1.0);
THIRD = 1.0/3.0;
maxeatom = maxvatom = 0;
eatom = NULL;
vatom = NULL;
}
/* ---------------------------------------------------------------------- */
Angle::~Angle()
{
memory->sfree(eatom);
memory->destroy_2d_double_array(vatom);
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -37,3 +54,169 @@ void Angle::init()
if (setflag[i] == 0) error->all("All angle coeffs are not set"); if (setflag[i] == 0) error->all("All angle coeffs are not set");
} }
/* ----------------------------------------------------------------------
setup for energy, virial computation
see integrate::ev_set() for values of eflag (0-3) and vflag (0-6)
------------------------------------------------------------------------- */
void Angle::ev_setup(int eflag, int vflag)
{
int i,n;
evflag = 1;
eflag_either = eflag;
eflag_global = eflag % 2;
eflag_atom = eflag / 2;
vflag_either = vflag;
vflag_global = vflag % 4;
vflag_atom = vflag / 4;
// reallocate per-atom arrays if necessary
if (eflag_atom && atom->nmax > maxeatom) {
maxeatom = atom->nmax;
memory->sfree(eatom);
eatom = (double *) memory->smalloc(maxeatom*sizeof(double),"bond:eatom");
}
if (vflag_atom && atom->nmax > maxvatom) {
maxvatom = atom->nmax;
memory->destroy_2d_double_array(vatom);
vatom = memory->create_2d_double_array(maxvatom,6,"bond:vatom");
}
// zero accumulators
if (eflag_global) energy = 0.0;
if (vflag_global) for (i = 0; i < 6; i++) virial[i] = 0.0;
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
for (i = 0; i < n; i++) eatom[i] = 0.0;
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
for (i = 0; i < n; i++) {
vatom[i][0] = 0.0;
vatom[i][1] = 0.0;
vatom[i][2] = 0.0;
vatom[i][3] = 0.0;
vatom[i][4] = 0.0;
vatom[i][5] = 0.0;
}
}
}
/* ----------------------------------------------------------------------
tally energy and virial into global and per-atom accumulators
virial = r1F1 + r2F2 + r3F3 = (r1-r2) F1 + (r3-r2) F3 = del1*f1 + del2*f3
------------------------------------------------------------------------- */
void Angle::ev_tally(int i, int j, int k, int nlocal, int newton_bond,
double eangle, double *f1, double *f3,
double delx1, double dely1, double delz1,
double delx2, double dely2, double delz2)
{
double eanglethird,v[6];
if (eflag_either) {
if (eflag_global) {
if (newton_bond) energy += eangle;
else {
eanglethird = THIRD*eangle;
if (i < nlocal) energy += eanglethird;
if (j < nlocal) energy += eanglethird;
if (k < nlocal) energy += eanglethird;
}
}
if (eflag_atom) {
eanglethird = THIRD*eangle;
if (newton_bond || i < nlocal) eatom[i] += eanglethird;
if (newton_bond || j < nlocal) eatom[j] += eanglethird;
if (newton_bond || k < nlocal) eatom[k] += eanglethird;
}
}
if (vflag_either) {
v[0] = delx1*f1[0] + delx2*f3[0];
v[1] = dely1*f1[1] + dely2*f3[1];
v[2] = delz1*f1[2] + delz2*f3[2];
v[3] = delx1*f1[1] + delx2*f3[1];
v[4] = delx1*f1[2] + delx2*f3[2];
v[5] = dely1*f1[2] + dely2*f3[2];
if (vflag_global) {
if (newton_bond) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
} else {
if (i < nlocal) {
virial[0] += THIRD*v[0];
virial[1] += THIRD*v[1];
virial[2] += THIRD*v[2];
virial[3] += THIRD*v[3];
virial[4] += THIRD*v[4];
virial[5] += THIRD*v[5];
}
if (j < nlocal) {
virial[0] += THIRD*v[0];
virial[1] += THIRD*v[1];
virial[2] += THIRD*v[2];
virial[3] += THIRD*v[3];
virial[4] += THIRD*v[4];
virial[5] += THIRD*v[5];
}
if (k < nlocal) {
virial[0] += THIRD*v[0];
virial[1] += THIRD*v[1];
virial[2] += THIRD*v[2];
virial[3] += THIRD*v[3];
virial[4] += THIRD*v[4];
virial[5] += THIRD*v[5];
}
}
}
if (vflag_atom) {
if (newton_bond || i < nlocal) {
vatom[i][0] += THIRD*v[0];
vatom[i][1] += THIRD*v[1];
vatom[i][2] += THIRD*v[2];
vatom[i][3] += THIRD*v[3];
vatom[i][4] += THIRD*v[4];
vatom[i][5] += THIRD*v[5];
}
if (newton_bond || j < nlocal) {
vatom[j][0] += THIRD*v[0];
vatom[j][1] += THIRD*v[1];
vatom[j][2] += THIRD*v[2];
vatom[j][3] += THIRD*v[3];
vatom[j][4] += THIRD*v[4];
vatom[j][5] += THIRD*v[5];
}
if (newton_bond || k < nlocal) {
vatom[k][0] += THIRD*v[0];
vatom[k][1] += THIRD*v[1];
vatom[k][2] += THIRD*v[2];
vatom[k][3] += THIRD*v[3];
vatom[k][4] += THIRD*v[4];
vatom[k][5] += THIRD*v[5];
}
}
}
}
/* ---------------------------------------------------------------------- */
double Angle::memory_usage()
{
double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
return bytes;
}

View File

@ -51,13 +51,16 @@ AngleCharmm::~AngleCharmm()
void AngleCharmm::compute(int eflag, int vflag) void AngleCharmm::compute(int eflag, int vflag)
{ {
int i1,i2,i3,n,type,factor; int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2,rfactor,dtheta,tk; double delx1,dely1,delz1,delx2,dely2,delz2;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; double eangle,f1[3],f3[3];
double dtheta,tk;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
double delxUB,delyUB,delzUB,rsqUB,rUB,dr,rk,forceUB; double delxUB,delyUB,delzUB,rsqUB,rUB,dr,rk,forceUB;
energy = 0.0; eangle = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -67,21 +70,11 @@ void AngleCharmm::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) { for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0]; i1 = anglelist[n][0];
i2 = anglelist[n][1]; i2 = anglelist[n][1];
i3 = anglelist[n][2]; i3 = anglelist[n][2];
type = anglelist[n][3]; type = anglelist[n][3];
if (newton_bond) factor = 3;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
}
rfactor = factor/3.0;
// 1st bond // 1st bond
delx1 = x[i1][0] - x[i2][0]; delx1 = x[i1][0] - x[i2][0];
@ -112,6 +105,16 @@ void AngleCharmm::compute(int eflag, int vflag)
rsqUB = delxUB*delxUB + delyUB*delyUB + delzUB*delzUB; rsqUB = delxUB*delxUB + delyUB*delyUB + delzUB*delzUB;
rUB = sqrt(rsqUB); rUB = sqrt(rsqUB);
// Urey-Bradley force & energy
dr = rUB - r_ub[type];
rk = k_ub[type] * dr;
if (rUB > 0.0) forceUB = -2.0*rk/rUB;
else forceUB = 0.0;
if (eflag) eangle = rk*dr;
// angle (cos and sin) // angle (cos and sin)
c = delx1*delx2 + dely1*dely2 + delz1*delz2; c = delx1*delx2 + dely1*dely2 + delz1*delz2;
@ -129,61 +132,43 @@ void AngleCharmm::compute(int eflag, int vflag)
dtheta = acos(c) - theta0[type]; dtheta = acos(c) - theta0[type];
tk = k[type] * dtheta; tk = k[type] * dtheta;
if (eflag) energy += rfactor * tk*dtheta; if (eflag) eangle += tk*dtheta;
a = 2.0 * tk * s; a = -2.0 * tk * s;
a11 = a*c / rsq1; a11 = a*c / rsq1;
a12 = -a / (r1*r2); a12 = -a / (r1*r2);
a22 = a*c / rsq2; a22 = a*c / rsq2;
vx1 = a11*delx1 + a12*delx2;
vx2 = a22*delx2 + a12*delx1;
vy1 = a11*dely1 + a12*dely2;
vy2 = a22*dely2 + a12*dely1;
vz1 = a11*delz1 + a12*delz2;
vz2 = a22*delz2 + a12*delz1;
// Urey-Bradley force & energy f1[0] = a11*delx1 + a12*delx2 - delxUB*forceUB;
f1[1] = a11*dely1 + a12*dely2 - delyUB*forceUB;
f1[2] = a11*delz1 + a12*delz2 - delzUB*forceUB;
dr = rUB - r_ub[type]; f3[0] = a22*delx2 + a12*delx1 + delxUB*forceUB;
rk = k_ub[type] * dr; f3[1] = a22*dely2 + a12*dely1 + delyUB*forceUB;
f3[2] = a22*delz2 + a12*delz1 + delzUB*forceUB;
if (rUB > 0.0) forceUB = -2.0*rk/rUB;
else forceUB = 0.0;
if (eflag) energy += rfactor * rk*dr;
// apply force to each of 3 atoms // apply force to each of 3 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= vx1 + delxUB*forceUB; f[i1][0] += f1[0];
f[i1][1] -= vy1 + delyUB*forceUB; f[i1][1] += f1[1];
f[i1][2] -= vz1 + delzUB*forceUB; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += vx1 + vx2; f[i2][0] -= f1[0] + f3[0];
f[i2][1] += vy1 + vy2; f[i2][1] -= f1[1] + f3[1];
f[i2][2] += vz1 + vz2; f[i2][2] -= f1[2] + f3[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] -= vx2 - delxUB*forceUB; f[i3][0] += f3[0];
f[i3][1] -= vy2 - delyUB*forceUB; f[i3][1] += f3[1];
f[i3][2] -= vz2 - delzUB*forceUB; f[i3][2] += f3[2];
} }
// virial contribution if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
if (vflag) {
virial[0] -= rfactor * (delx1*vx1 + delx2*vx2 - delxUB*delxUB*forceUB);
virial[1] -= rfactor * (dely1*vy1 + dely2*vy2 - delyUB*delyUB*forceUB);
virial[2] -= rfactor * (delz1*vz1 + delz2*vz2 - delzUB*delzUB*forceUB);
virial[3] -= rfactor * (delx1*vy1 + delx2*vy2 - delxUB*delyUB*forceUB);
virial[4] -= rfactor * (delx1*vz1 + delx2*vz2 - delxUB*delzUB*forceUB);
virial[5] -= rfactor * (dely1*vz1 + dely2*vz2 - delyUB*delzUB*forceUB);
}
} }
} }

View File

@ -44,12 +44,14 @@ AngleCosine::~AngleCosine()
void AngleCosine::compute(int eflag, int vflag) void AngleCosine::compute(int eflag, int vflag)
{ {
int i1,i2,i3,n,type,factor; int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2,rfactor; double delx1,dely1,delz1,delx2,dely2,delz2;
double rsq1,rsq2,r1,r2,c,a,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; double eangle,f1[3],f3[3];
double rsq1,rsq2,r1,r2,c,a,a11,a12,a22;
energy = 0.0; eangle = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -59,21 +61,11 @@ void AngleCosine::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) { for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0]; i1 = anglelist[n][0];
i2 = anglelist[n][1]; i2 = anglelist[n][1];
i3 = anglelist[n][2]; i3 = anglelist[n][2];
type = anglelist[n][3]; type = anglelist[n][3];
if (newton_bond) factor = 3;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
}
rfactor = factor/3.0;
// 1st bond // 1st bond
delx1 = x[i1][0] - x[i2][0]; delx1 = x[i1][0] - x[i2][0];
@ -103,51 +95,42 @@ void AngleCosine::compute(int eflag, int vflag)
// force & energy // force & energy
if (eflag) energy += rfactor * k[type]*(1.0+c); if (eflag) eangle = k[type]*(1.0+c);
a = -k[type]; a = k[type];
a11 = a*c / rsq1; a11 = a*c / rsq1;
a12 = -a / (r1*r2); a12 = -a / (r1*r2);
a22 = a*c / rsq2; a22 = a*c / rsq2;
vx1 = a11*delx1 + a12*delx2; f1[0] = a11*delx1 + a12*delx2;
vx2 = a22*delx2 + a12*delx1; f1[1] = a11*dely1 + a12*dely2;
vy1 = a11*dely1 + a12*dely2; f1[2] = a11*delz1 + a12*delz2;
vy2 = a22*dely2 + a12*dely1; f3[0] = a22*delx2 + a12*delx1;
vz1 = a11*delz1 + a12*delz2; f3[1] = a22*dely2 + a12*dely1;
vz2 = a22*delz2 + a12*delz1; f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 atoms // apply force to each of 3 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= vx1; f[i1][0] += f1[0];
f[i1][1] -= vy1; f[i1][1] += f1[1];
f[i1][2] -= vz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += vx1 + vx2; f[i2][0] -= f1[0] + f3[0];
f[i2][1] += vy1 + vy2; f[i2][1] -= f1[1] + f3[1];
f[i2][2] += vz1 + vz2; f[i2][2] -= f1[2] + f3[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] -= vx2; f[i3][0] += f3[0];
f[i3][1] -= vy2; f[i3][1] += f3[1];
f[i3][2] -= vz2; f[i3][2] += f3[2];
} }
// virial contribution if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
if (vflag) {
virial[0] -= rfactor * (delx1*vx1 + delx2*vx2);
virial[1] -= rfactor * (dely1*vy1 + dely2*vy2);
virial[2] -= rfactor * (delz1*vz1 + delz2*vz2);
virial[3] -= rfactor * (delx1*vy1 + delx2*vy2);
virial[4] -= rfactor * (delx1*vz1 + delx2*vz2);
virial[5] -= rfactor * (dely1*vz1 + dely2*vz2);
}
} }
} }

View File

@ -49,12 +49,15 @@ AngleCosineSquared::~AngleCosineSquared()
void AngleCosineSquared::compute(int eflag, int vflag) void AngleCosineSquared::compute(int eflag, int vflag)
{ {
int i1,i2,i3,n,type,factor; int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2,rfactor,dcostheta,tk; double delx1,dely1,delz1,delx2,dely2,delz2;
double rsq1,rsq2,r1,r2,c,a,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; double eangle,f1[3],f3[3];
double dcostheta,tk;
double rsq1,rsq2,r1,r2,c,a,a11,a12,a22;
energy = 0.0; eangle = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -64,21 +67,11 @@ void AngleCosineSquared::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) { for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0]; i1 = anglelist[n][0];
i2 = anglelist[n][1]; i2 = anglelist[n][1];
i3 = anglelist[n][2]; i3 = anglelist[n][2];
type = anglelist[n][3]; type = anglelist[n][3];
if (newton_bond) factor = 3;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
}
rfactor = factor/3.0;
// 1st bond // 1st bond
delx1 = x[i1][0] - x[i2][0]; delx1 = x[i1][0] - x[i2][0];
@ -112,51 +105,42 @@ void AngleCosineSquared::compute(int eflag, int vflag)
dcostheta = c - cos(theta0[type]); dcostheta = c - cos(theta0[type]);
tk = k[type] * dcostheta; tk = k[type] * dcostheta;
if (eflag) energy += rfactor * tk*dcostheta; if (eflag) eangle = tk*dcostheta;
a = -2.0 * tk; a = 2.0 * tk;
a11 = a*c / rsq1; a11 = a*c / rsq1;
a12 = -a / (r1*r2); a12 = -a / (r1*r2);
a22 = a*c / rsq2; a22 = a*c / rsq2;
vx1 = a11*delx1 + a12*delx2; f1[0] = a11*delx1 + a12*delx2;
vx2 = a22*delx2 + a12*delx1; f1[1] = a11*dely1 + a12*dely2;
vy1 = a11*dely1 + a12*dely2; f1[2] = a11*delz1 + a12*delz2;
vy2 = a22*dely2 + a12*dely1; f3[0] = a22*delx2 + a12*delx1;
vz1 = a11*delz1 + a12*delz2; f3[1] = a22*dely2 + a12*dely1;
vz2 = a22*delz2 + a12*delz1; f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 atoms // apply force to each of 3 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= vx1; f[i1][0] += f1[0];
f[i1][1] -= vy1; f[i1][1] += f1[1];
f[i1][2] -= vz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += vx1 + vx2; f[i2][0] -= f1[0] + f3[0];
f[i2][1] += vy1 + vy2; f[i2][1] -= f1[1] + f3[1];
f[i2][2] += vz1 + vz2; f[i2][2] -= f1[2] + f3[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] -= vx2; f[i3][0] += f3[0];
f[i3][1] -= vy2; f[i3][1] += f3[1];
f[i3][2] -= vz2; f[i3][2] += f3[2];
} }
// virial contribution if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
if (vflag) {
virial[0] -= rfactor * (delx1*vx1 + delx2*vx2);
virial[1] -= rfactor * (dely1*vy1 + dely2*vy2);
virial[2] -= rfactor * (delz1*vz1 + delz2*vz2);
virial[3] -= rfactor * (delx1*vy1 + delx2*vy2);
virial[4] -= rfactor * (delx1*vz1 + delx2*vz2);
virial[5] -= rfactor * (dely1*vz1 + dely2*vz2);
}
} }
} }

View File

@ -45,12 +45,15 @@ AngleHarmonic::~AngleHarmonic()
void AngleHarmonic::compute(int eflag, int vflag) void AngleHarmonic::compute(int eflag, int vflag)
{ {
int i1,i2,i3,n,type,factor; int i1,i2,i3,n,type;
double delx1,dely1,delz1,delx2,dely2,delz2,rfactor,dtheta,tk; double delx1,dely1,delz1,delx2,dely2,delz2;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22,vx1,vx2,vy1,vy2,vz1,vz2; double eangle,f1[3],f3[3];
double dtheta,tk;
double rsq1,rsq2,r1,r2,c,s,a,a11,a12,a22;
energy = 0.0; eangle = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -60,21 +63,11 @@ void AngleHarmonic::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nanglelist; n++) { for (n = 0; n < nanglelist; n++) {
i1 = anglelist[n][0]; i1 = anglelist[n][0];
i2 = anglelist[n][1]; i2 = anglelist[n][1];
i3 = anglelist[n][2]; i3 = anglelist[n][2];
type = anglelist[n][3]; type = anglelist[n][3];
if (newton_bond) factor = 3;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
}
rfactor = factor/3.0;
// 1st bond // 1st bond
delx1 = x[i1][0] - x[i2][0]; delx1 = x[i1][0] - x[i2][0];
@ -112,51 +105,42 @@ void AngleHarmonic::compute(int eflag, int vflag)
dtheta = acos(c) - theta0[type]; dtheta = acos(c) - theta0[type];
tk = k[type] * dtheta; tk = k[type] * dtheta;
if (eflag) energy += rfactor * tk*dtheta; if (eflag) eangle = tk*dtheta;
a = 2.0 * tk * s; a = -2.0 * tk * s;
a11 = a*c / rsq1; a11 = a*c / rsq1;
a12 = -a / (r1*r2); a12 = -a / (r1*r2);
a22 = a*c / rsq2; a22 = a*c / rsq2;
vx1 = a11*delx1 + a12*delx2; f1[0] = a11*delx1 + a12*delx2;
vx2 = a22*delx2 + a12*delx1; f1[1] = a11*dely1 + a12*dely2;
vy1 = a11*dely1 + a12*dely2; f1[2] = a11*delz1 + a12*delz2;
vy2 = a22*dely2 + a12*dely1; f3[0] = a22*delx2 + a12*delx1;
vz1 = a11*delz1 + a12*delz2; f3[1] = a22*dely2 + a12*dely1;
vz2 = a22*delz2 + a12*delz1; f3[2] = a22*delz2 + a12*delz1;
// apply force to each of 3 atoms // apply force to each of 3 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= vx1; f[i1][0] += f1[0];
f[i1][1] -= vy1; f[i1][1] += f1[1];
f[i1][2] -= vz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += vx1 + vx2; f[i2][0] -= f1[0] + f3[0];
f[i2][1] += vy1 + vy2; f[i2][1] -= f1[1] + f3[1];
f[i2][2] += vz1 + vz2; f[i2][2] -= f1[2] + f3[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] -= vx2; f[i3][0] += f3[0];
f[i3][1] -= vy2; f[i3][1] += f3[1];
f[i3][2] -= vz2; f[i3][2] += f3[2];
} }
// virial contribution if (evflag) ev_tally(i1,i2,i3,nlocal,newton_bond,eangle,f1,f3,
delx1,dely1,delz1,delx2,dely2,delz2);
if (vflag) {
virial[0] -= rfactor * (delx1*vx1 + delx2*vx2);
virial[1] -= rfactor * (dely1*vy1 + dely2*vy2);
virial[2] -= rfactor * (delz1*vz1 + delz2*vz2);
virial[3] -= rfactor * (delx1*vy1 + delx2*vy2);
virial[4] -= rfactor * (delx1*vz1 + delx2*vz2);
virial[5] -= rfactor * (dely1*vz1 + dely2*vz2);
}
} }
} }

View File

@ -59,7 +59,7 @@ AngleHybrid::~AngleHybrid()
void AngleHybrid::compute(int eflag, int vflag) void AngleHybrid::compute(int eflag, int vflag)
{ {
int i,m,n; int i,j,m,n;
// save ptrs to original anglelist // save ptrs to original anglelist
@ -96,19 +96,36 @@ void AngleHybrid::compute(int eflag, int vflag)
} }
// call each sub-style's compute function // call each sub-style's compute function
// must set neighbor->anglelist to sub-style anglelist before call // set neighbor->anglelist to sub-style anglelist before call
// accumulate sub-style energy,virial in hybrid's energy,virial // accumulate sub-style global/peratom energy/virial in hybrid
energy = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; else evflag = 0;
for (m = 0; m < nstyles; m++) { for (m = 0; m < nstyles; m++) {
if (styles[m] == NULL) continue; if (styles[m] == NULL) continue;
neighbor->nanglelist = nanglelist[m]; neighbor->nanglelist = nanglelist[m];
neighbor->anglelist = anglelist[m]; neighbor->anglelist = anglelist[m];
styles[m]->compute(eflag,vflag); styles[m]->compute(eflag,vflag);
if (eflag) energy += styles[m]->energy;
if (vflag) for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n]; if (eflag_global) energy += styles[m]->energy;
if (vflag_global)
for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n];
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
double *eatom_substyle = styles[m]->eatom;
for (i = 0; i < n; i++) eatom[i] += eatom_substyle[i];
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
double **vatom_substyle = styles[m]->vatom;
for (i = 0; i < n; i++)
for (j = 0; j < 6; j++)
vatom[i][j] += vatom_substyle[i][j];
}
} }
// restore ptrs to original anglelist // restore ptrs to original anglelist
@ -253,7 +270,8 @@ double AngleHybrid::single(int type, int i1, int i2, int i3)
double AngleHybrid::memory_usage() double AngleHybrid::memory_usage()
{ {
double bytes = 0.0; double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
for (int m = 0; m < nstyles; m++) bytes += maxangle[m]*4 * sizeof(int); for (int m = 0; m < nstyles; m++) bytes += maxangle[m]*4 * sizeof(int);
for (int m = 0; m < nstyles; m++) for (int m = 0; m < nstyles; m++)
if (styles[m]) bytes += styles[m]->memory_usage(); if (styles[m]) bytes += styles[m]->memory_usage();

View File

@ -14,6 +14,8 @@
#include "string.h" #include "string.h"
#include "bond.h" #include "bond.h"
#include "atom.h" #include "atom.h"
#include "force.h"
#include "memory.h"
#include "error.h" #include "error.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -25,8 +27,21 @@ using namespace LAMMPS_NS;
Bond::Bond(LAMMPS *lmp) : Pointers(lmp) Bond::Bond(LAMMPS *lmp) : Pointers(lmp)
{ {
energy = 0.0;
allocated = 0; allocated = 0;
eng_vdwl = 0.0;
maxeatom = maxvatom = 0;
eatom = NULL;
vatom = NULL;
}
/* ---------------------------------------------------------------------- */
Bond::~Bond()
{
memory->sfree(eatom);
memory->destroy_2d_double_array(vatom);
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -40,3 +55,150 @@ void Bond::init()
if (setflag[i] == 0) error->all("All bond coeffs are not set"); if (setflag[i] == 0) error->all("All bond coeffs are not set");
init_style(); init_style();
} }
/* ----------------------------------------------------------------------
setup for energy, virial computation
see integrate::ev_set() for values of eflag (0-3) and vflag (0-6)
------------------------------------------------------------------------- */
void Bond::ev_setup(int eflag, int vflag)
{
int i,n;
evflag = 1;
eflag_either = eflag;
eflag_global = eflag % 2;
eflag_atom = eflag / 2;
vflag_either = vflag;
vflag_global = vflag % 4;
vflag_atom = vflag / 4;
// reallocate per-atom arrays if necessary
if (eflag_atom && atom->nmax > maxeatom) {
maxeatom = atom->nmax;
memory->sfree(eatom);
eatom = (double *) memory->smalloc(maxeatom*sizeof(double),"bond:eatom");
}
if (vflag_atom && atom->nmax > maxvatom) {
maxvatom = atom->nmax;
memory->destroy_2d_double_array(vatom);
vatom = memory->create_2d_double_array(maxvatom,6,"bond:vatom");
}
// zero accumulators
if (eflag_global) energy = 0.0;
if (vflag_global) for (i = 0; i < 6; i++) virial[i] = 0.0;
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
for (i = 0; i < n; i++) eatom[i] = 0.0;
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
for (i = 0; i < n; i++) {
vatom[i][0] = 0.0;
vatom[i][1] = 0.0;
vatom[i][2] = 0.0;
vatom[i][3] = 0.0;
vatom[i][4] = 0.0;
vatom[i][5] = 0.0;
}
}
}
/* ----------------------------------------------------------------------
tally energy and virial into global and per-atom accumulators
------------------------------------------------------------------------- */
void Bond::ev_tally(int i, int j, int nlocal, int newton_bond,
double ebond, double fbond,
double delx, double dely, double delz)
{
double ebondhalf,v[6];
if (eflag_either) {
if (eflag_global) {
if (newton_bond) energy += ebond;
else {
ebondhalf = 0.5*ebond;
if (i < nlocal) energy += ebondhalf;
if (j < nlocal) energy += ebondhalf;
}
}
if (eflag_atom) {
ebondhalf = 0.5*ebond;
if (newton_bond || i < nlocal) eatom[i] += ebondhalf;
if (newton_bond || j < nlocal) eatom[j] += ebondhalf;
}
}
if (vflag_either) {
v[0] = delx*delx*fbond;
v[1] = dely*dely*fbond;
v[2] = delz*delz*fbond;
v[3] = delx*dely*fbond;
v[4] = delx*delz*fbond;
v[5] = dely*delz*fbond;
if (vflag_global) {
if (newton_bond) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
} else {
if (i < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
if (j < nlocal) {
virial[0] += 0.5*v[0];
virial[1] += 0.5*v[1];
virial[2] += 0.5*v[2];
virial[3] += 0.5*v[3];
virial[4] += 0.5*v[4];
virial[5] += 0.5*v[5];
}
}
}
if (vflag_atom) {
if (newton_bond || i < nlocal) {
vatom[i][0] += 0.5*v[0];
vatom[i][1] += 0.5*v[1];
vatom[i][2] += 0.5*v[2];
vatom[i][3] += 0.5*v[3];
vatom[i][4] += 0.5*v[4];
vatom[i][5] += 0.5*v[5];
}
if (newton_bond || j < nlocal) {
vatom[j][0] += 0.5*v[0];
vatom[j][1] += 0.5*v[1];
vatom[j][2] += 0.5*v[2];
vatom[j][3] += 0.5*v[3];
vatom[j][4] += 0.5*v[4];
vatom[j][5] += 0.5*v[5];
}
}
}
}
/* ---------------------------------------------------------------------- */
double Bond::memory_usage()
{
double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
return bytes;
}

View File

@ -49,11 +49,13 @@ BondFENE::~BondFENE()
void BondFENE::compute(int eflag, int vflag) void BondFENE::compute(int eflag, int vflag)
{ {
int i1,i2,n,type,factor; int i1,i2,n,type;
double delx,dely,delz,rsq,r0sq,rlogarg,fforce,sr2,sr6,rfactor; double delx,dely,delz,ebond,fbond;
double rsq,r0sq,rlogarg,sr2,sr6;
energy = 0.0; ebond = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -63,19 +65,10 @@ void BondFENE::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nbondlist; n++) { for (n = 0; n < nbondlist; n++) {
i1 = bondlist[n][0]; i1 = bondlist[n][0];
i2 = bondlist[n][1]; i2 = bondlist[n][1];
type = bondlist[n][2]; type = bondlist[n][2];
if (newton_bond) factor = 2;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
}
rfactor = 0.5*factor;
delx = x[i1][0] - x[i2][0]; delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1]; dely = x[i1][1] - x[i2][1];
delz = x[i1][2] - x[i2][2]; delz = x[i1][2] - x[i2][2];
@ -100,48 +93,39 @@ void BondFENE::compute(int eflag, int vflag)
rlogarg = 0.1; rlogarg = 0.1;
} }
fforce = -k[type]/rlogarg; fbond = -k[type]/rlogarg;
// force from LJ term // force from LJ term
if (rsq < TWO_1_3*sigma[type]*sigma[type]) { if (rsq < TWO_1_3*sigma[type]*sigma[type]) {
sr2 = sigma[type]*sigma[type]/rsq; sr2 = sigma[type]*sigma[type]/rsq;
sr6 = sr2*sr2*sr2; sr6 = sr2*sr2*sr2;
fforce += 48.0*epsilon[type]*sr6*(sr6-0.5)/rsq; fbond += 48.0*epsilon[type]*sr6*(sr6-0.5)/rsq;
} }
// energy // energy
if (eflag) { if (eflag) {
energy -= 0.5*rfactor * k[type]*r0sq*log(rlogarg); ebond = -0.5 * k[type]*r0sq*log(rlogarg);
if (rsq < TWO_1_3*sigma[type]*sigma[type]) if (rsq < TWO_1_3*sigma[type]*sigma[type])
energy += rfactor * (4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type]); ebond += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
} }
// apply force to each of 2 atoms // apply force to each of 2 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] += delx*fforce; f[i1][0] += delx*fbond;
f[i1][1] += dely*fforce; f[i1][1] += dely*fbond;
f[i1][2] += delz*fforce; f[i1][2] += delz*fbond;
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx*fforce; f[i2][0] -= delx*fbond;
f[i2][1] -= dely*fforce; f[i2][1] -= dely*fbond;
f[i2][2] -= delz*fforce; f[i2][2] -= delz*fbond;
} }
// virial contribution if (evflag) ev_tally(i1,i2,nlocal,newton_bond,ebond,fbond,delx,dely,delz);
if (vflag) {
virial[0] += rfactor * delx*delx*fforce;
virial[1] += rfactor * dely*dely*fforce;
virial[2] += rfactor * delz*delz*fforce;
virial[3] += rfactor * delx*dely*fforce;
virial[4] += rfactor * delx*delz*fforce;
virial[5] += rfactor * dely*delz*fforce;
}
} }
} }
@ -233,8 +217,7 @@ void BondFENE::read_restart(FILE *fp)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void BondFENE::single(int type, double rsq, int i, int j, void BondFENE::single(int type, double rsq, int i, int j, double &eng)
int eflag, double &fforce, double &eng)
{ {
double r0sq = r0[type] * r0[type]; double r0sq = r0[type] * r0[type];
double rlogarg = 1.0 - rsq/r0sq; double rlogarg = 1.0 - rsq/r0sq;
@ -251,22 +234,11 @@ void BondFENE::single(int type, double rsq, int i, int j,
rlogarg = 0.1; rlogarg = 0.1;
} }
fforce = -k[type]/rlogarg; eng = -0.5 * k[type]*r0sq*log(rlogarg);
// force from LJ term
double sr2,sr6;
if (rsq < TWO_1_3*sigma[type]*sigma[type]) { if (rsq < TWO_1_3*sigma[type]*sigma[type]) {
double sr2,sr6;
sr2 = sigma[type]*sigma[type]/rsq; sr2 = sigma[type]*sigma[type]/rsq;
sr6 = sr2*sr2*sr2; sr6 = sr2*sr2*sr2;
fforce += 48.0*epsilon[type]*sr6*(sr6-0.5)/rsq; eng += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
}
// energy
if (eflag) {
eng = -0.5 * k[type]*r0sq*log(rlogarg);
if (rsq < TWO_1_3*sigma[type]*sigma[type])
eng += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
} }
} }

View File

@ -28,7 +28,7 @@ class BondFENE : public Bond {
double equilibrium_distance(int); double equilibrium_distance(int);
void write_restart(FILE *); void write_restart(FILE *);
void read_restart(FILE *); void read_restart(FILE *);
void single(int, double, int, int, int, double &, double &); void single(int, double, int, int, double &);
private: private:
double TWO_1_3; double TWO_1_3;

View File

@ -50,12 +50,14 @@ BondFENEExpand::~BondFENEExpand()
void BondFENEExpand::compute(int eflag, int vflag) void BondFENEExpand::compute(int eflag, int vflag)
{ {
int i1,i2,n,type,factor; int i1,i2,n,type;
double delx,dely,delz,rsq,r0sq,rlogarg,fforce,sr2,sr6,rfactor; double delx,dely,delz,ebond,fbond;
double rsq,r0sq,rlogarg,sr2,sr6;
double r,rshift,rshiftsq; double r,rshift,rshiftsq;
energy = 0.0; ebond = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -65,19 +67,10 @@ void BondFENEExpand::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nbondlist; n++) { for (n = 0; n < nbondlist; n++) {
i1 = bondlist[n][0]; i1 = bondlist[n][0];
i2 = bondlist[n][1]; i2 = bondlist[n][1];
type = bondlist[n][2]; type = bondlist[n][2];
if (newton_bond) factor = 2;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
}
rfactor = 0.5*factor;
delx = x[i1][0] - x[i2][0]; delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1]; dely = x[i1][1] - x[i2][1];
delz = x[i1][2] - x[i2][2]; delz = x[i1][2] - x[i2][2];
@ -105,50 +98,39 @@ void BondFENEExpand::compute(int eflag, int vflag)
rlogarg = 0.1; rlogarg = 0.1;
} }
fforce = -k[type]*rshift/rlogarg/r; fbond = -k[type]*rshift/rlogarg/r;
// force from LJ term // force from LJ term
if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) { if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) {
sr2 = sigma[type]*sigma[type]/rshiftsq; sr2 = sigma[type]*sigma[type]/rshiftsq;
sr6 = sr2*sr2*sr2; sr6 = sr2*sr2*sr2;
fforce += 48.0*epsilon[type]*sr6*(sr6-0.5)/rshift/r; fbond += 48.0*epsilon[type]*sr6*(sr6-0.5)/rshift/r;
} }
// energy // energy
if (eflag) { if (eflag) {
energy -= 0.5*rfactor * k[type]*r0sq*log(rlogarg); ebond = -0.5 * k[type]*r0sq*log(rlogarg);
if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) if (rshiftsq < TWO_1_3*sigma[type]*sigma[type])
energy += 0.5*factor * ebond += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
(4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type]);
} }
// apply force to each of 2 atoms // apply force to each of 2 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] += delx*fforce; f[i1][0] += delx*fbond;
f[i1][1] += dely*fforce; f[i1][1] += dely*fbond;
f[i1][2] += delz*fforce; f[i1][2] += delz*fbond;
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx*fforce; f[i2][0] -= delx*fbond;
f[i2][1] -= dely*fforce; f[i2][1] -= dely*fbond;
f[i2][2] -= delz*fforce; f[i2][2] -= delz*fbond;
} }
// virial contribution if (evflag) ev_tally(i1,i2,nlocal,newton_bond,ebond,fbond,delx,dely,delz);
if (vflag) {
virial[0] += rfactor * delx*delx*fforce;
virial[1] += rfactor * dely*dely*fforce;
virial[2] += rfactor * delz*delz*fforce;
virial[3] += rfactor * delx*dely*fforce;
virial[4] += rfactor * delx*delz*fforce;
virial[5] += rfactor * dely*delz*fforce;
}
} }
} }
@ -246,8 +228,7 @@ void BondFENEExpand::read_restart(FILE *fp)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void BondFENEExpand::single(int type, double rsq, int i, int j, void BondFENEExpand::single(int type, double rsq, int i, int j, double &eng)
int eflag, double &fforce, double &eng)
{ {
double r = sqrt(rsq); double r = sqrt(rsq);
double rshift = r - shift[type]; double rshift = r - shift[type];
@ -267,22 +248,11 @@ void BondFENEExpand::single(int type, double rsq, int i, int j,
rlogarg = 0.1; rlogarg = 0.1;
} }
fforce = -k[type]*rshift/rlogarg/r; eng = -0.5 * k[type]*r0sq*log(rlogarg);
// force from LJ term
double sr2,sr6;
if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) { if (rshiftsq < TWO_1_3*sigma[type]*sigma[type]) {
double sr2,sr6;
sr2 = sigma[type]*sigma[type]/rshiftsq; sr2 = sigma[type]*sigma[type]/rshiftsq;
sr6 = sr2*sr2*sr2; sr6 = sr2*sr2*sr2;
fforce += 48.0*epsilon[type]*sr6*(sr6-0.5)/rshift/r; eng += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
}
// energy
if (eflag) {
eng = -0.5 * k[type]*r0sq*log(rlogarg);
if (rshiftsq < TWO_1_3*sigma[type]*sigma[type])
eng += 4.0*epsilon[type]*sr6*(sr6-1.0) + epsilon[type];
} }
} }

View File

@ -28,7 +28,7 @@ class BondFENEExpand : public Bond {
double equilibrium_distance(int); double equilibrium_distance(int);
void write_restart(FILE *); void write_restart(FILE *);
void read_restart(FILE *); void read_restart(FILE *);
void single(int, double, int, int, int, double &, double &); void single(int, double, int, int, double &);
private: private:
double TWO_1_3; double TWO_1_3;

View File

@ -43,11 +43,13 @@ BondHarmonic::~BondHarmonic()
void BondHarmonic::compute(int eflag, int vflag) void BondHarmonic::compute(int eflag, int vflag)
{ {
int i1,i2,n,type,factor; int i1,i2,n,type;
double delx,dely,delz,rsq,r,dr,rk,fforce,rfactor; double delx,dely,delz,ebond,fbond;
double rsq,r,dr,rk;
energy = 0.0; ebond = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -57,19 +59,10 @@ void BondHarmonic::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nbondlist; n++) { for (n = 0; n < nbondlist; n++) {
i1 = bondlist[n][0]; i1 = bondlist[n][0];
i2 = bondlist[n][1]; i2 = bondlist[n][1];
type = bondlist[n][2]; type = bondlist[n][2];
if (newton_bond) factor = 2;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
}
rfactor = 0.5 * factor;
delx = x[i1][0] - x[i2][0]; delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1]; dely = x[i1][1] - x[i2][1];
delz = x[i1][2] - x[i2][2]; delz = x[i1][2] - x[i2][2];
@ -82,35 +75,26 @@ void BondHarmonic::compute(int eflag, int vflag)
// force & energy // force & energy
if (r > 0.0) fforce = -2.0*rk/r; if (r > 0.0) fbond = -2.0*rk/r;
else fforce = 0.0; else fbond = 0.0;
if (eflag) energy += rfactor * rk*dr; if (eflag) ebond = rk*dr;
// apply force to each of 2 atoms // apply force to each of 2 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] += delx*fforce; f[i1][0] += delx*fbond;
f[i1][1] += dely*fforce; f[i1][1] += dely*fbond;
f[i1][2] += delz*fforce; f[i1][2] += delz*fbond;
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx*fforce; f[i2][0] -= delx*fbond;
f[i2][1] -= dely*fforce; f[i2][1] -= dely*fbond;
f[i2][2] -= delz*fforce; f[i2][2] -= delz*fbond;
} }
// virial contribution if (evflag) ev_tally(i1,i2,nlocal,newton_bond,ebond,fbond,delx,dely,delz);
if (vflag) {
virial[0] += rfactor*delx*delx*fforce;
virial[1] += rfactor*dely*dely*fforce;
virial[2] += rfactor*delz*delz*fforce;
virial[3] += rfactor*delx*dely*fforce;
virial[4] += rfactor*delx*delz*fforce;
virial[5] += rfactor*dely*delz*fforce;
}
} }
} }
@ -193,16 +177,10 @@ void BondHarmonic::read_restart(FILE *fp)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void BondHarmonic::single(int type, double rsq, int i, int j, void BondHarmonic::single(int type, double rsq, int i, int j, double &eng)
int eflag, double &fforce, double &eng)
{ {
double r = sqrt(rsq); double r = sqrt(rsq);
double dr = r - r0[type]; double dr = r - r0[type];
double rk = k[type] * dr; double rk = k[type] * dr;
eng = rk*dr;
// force & energy
if (r > 0.0) fforce = -2.0*rk/r;
else fforce = 0.0;
if (eflag) eng = rk*dr;
} }

View File

@ -28,7 +28,7 @@ class BondHarmonic : public Bond {
double equilibrium_distance(int); double equilibrium_distance(int);
void write_restart(FILE *); void write_restart(FILE *);
void read_restart(FILE *); void read_restart(FILE *);
void single(int, double, int, int, int, double &, double &); void single(int, double, int, int, double &);
private: private:
double *k,*r0; double *k,*r0;

View File

@ -59,7 +59,7 @@ BondHybrid::~BondHybrid()
void BondHybrid::compute(int eflag, int vflag) void BondHybrid::compute(int eflag, int vflag)
{ {
int i,m,n; int i,j,m,n;
// save ptrs to original bondlist // save ptrs to original bondlist
@ -95,23 +95,36 @@ void BondHybrid::compute(int eflag, int vflag)
} }
// call each sub-style's compute function // call each sub-style's compute function
// must set neighbor->bondlist to sub-style bondlist before call // set neighbor->bondlist to sub-style bondlist before call
// accumulate sub-style energy,virial in hybrid's energy,virial // accumulate sub-style global/peratom energy/virial in hybrid
energy = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
eng_vdwl = 0.0; else evflag = 0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0;
for (m = 0; m < nstyles; m++) { for (m = 0; m < nstyles; m++) {
if (styles[m] == NULL) continue; if (styles[m] == NULL) continue;
neighbor->nbondlist = nbondlist[m]; neighbor->nbondlist = nbondlist[m];
neighbor->bondlist = bondlist[m]; neighbor->bondlist = bondlist[m];
styles[m]->compute(eflag,vflag); styles[m]->compute(eflag,vflag);
if (eflag) {
energy += styles[m]->energy; if (eflag_global) energy += styles[m]->energy;
eng_vdwl += styles[m]->eng_vdwl; if (vflag_global)
for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n];
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
double *eatom_substyle = styles[m]->eatom;
for (i = 0; i < n; i++) eatom[i] += eatom_substyle[i];
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
double **vatom_substyle = styles[m]->vatom;
for (i = 0; i < n; i++)
for (j = 0; j < 6; j++)
vatom[i][j] += vatom_substyle[i][j];
} }
if (vflag) for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n];
} }
// restore ptrs to original bondlist // restore ptrs to original bondlist
@ -250,11 +263,9 @@ void BondHybrid::read_restart(FILE *fp)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void BondHybrid::single(int type, double rsq, int i, int j, void BondHybrid::single(int type, double rsq, int i, int j, double &eng)
int eflag, double &fforce, double &eng)
{ {
if (styles[map[type]]) if (styles[map[type]]) styles[map[type]]->single(type,rsq,i,j,eng);
styles[map[type]]->single(type,rsq,i,j,eflag,fforce,eng);
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -263,7 +274,8 @@ void BondHybrid::single(int type, double rsq, int i, int j,
double BondHybrid::memory_usage() double BondHybrid::memory_usage()
{ {
double bytes = 0.0; double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
for (int m = 0; m < nstyles; m++) bytes += maxbond[m]*3 * sizeof(int); for (int m = 0; m < nstyles; m++) bytes += maxbond[m]*3 * sizeof(int);
for (int m = 0; m < nstyles; m++) for (int m = 0; m < nstyles; m++)
if (styles[m]) bytes += styles[m]->memory_usage(); if (styles[m]) bytes += styles[m]->memory_usage();

View File

@ -48,11 +48,13 @@ BondMorse::~BondMorse()
void BondMorse::compute(int eflag, int vflag) void BondMorse::compute(int eflag, int vflag)
{ {
int i1,i2,n,type,factor; int i1,i2,n,type;
double delx,dely,delz,rsq,r,dr,fforce,rfactor,ralpha; double delx,dely,delz,ebond,fbond;
double rsq,r,dr,ralpha;
energy = 0.0; ebond = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -62,19 +64,10 @@ void BondMorse::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nbondlist; n++) { for (n = 0; n < nbondlist; n++) {
i1 = bondlist[n][0]; i1 = bondlist[n][0];
i2 = bondlist[n][1]; i2 = bondlist[n][1];
type = bondlist[n][2]; type = bondlist[n][2];
if (newton_bond) factor = 2;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
}
rfactor = 0.5 * factor;
delx = x[i1][0] - x[i2][0]; delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1]; dely = x[i1][1] - x[i2][1];
delz = x[i1][2] - x[i2][2]; delz = x[i1][2] - x[i2][2];
@ -87,35 +80,26 @@ void BondMorse::compute(int eflag, int vflag)
// force & energy // force & energy
if (r > 0.0) fforce = -2.0*d0[type]*alpha[type]*(1-ralpha)*ralpha/r; if (r > 0.0) fbond = -2.0*d0[type]*alpha[type]*(1-ralpha)*ralpha/r;
else fforce = 0.0; else fbond = 0.0;
if (eflag) energy += rfactor * d0[type]*(1-ralpha)*(1-ralpha); if (eflag) ebond = d0[type]*(1-ralpha)*(1-ralpha);
// apply force to each of 2 atoms // apply force to each of 2 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] += delx*fforce; f[i1][0] += delx*fbond;
f[i1][1] += dely*fforce; f[i1][1] += dely*fbond;
f[i1][2] += delz*fforce; f[i1][2] += delz*fbond;
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx*fforce; f[i2][0] -= delx*fbond;
f[i2][1] -= dely*fforce; f[i2][1] -= dely*fbond;
f[i2][2] -= delz*fforce; f[i2][2] -= delz*fbond;
} }
// virial contribution if (evflag) ev_tally(i1,i2,nlocal,newton_bond,ebond,fbond,delx,dely,delz);
if (vflag) {
virial[0] += rfactor*delx*delx*fforce;
virial[1] += rfactor*dely*dely*fforce;
virial[2] += rfactor*delz*delz*fforce;
virial[3] += rfactor*delx*dely*fforce;
virial[4] += rfactor*delx*delz*fforce;
virial[5] += rfactor*dely*delz*fforce;
}
} }
} }
@ -203,16 +187,10 @@ void BondMorse::read_restart(FILE *fp)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void BondMorse::single(int type, double rsq, int i, int j, void BondMorse::single(int type, double rsq, int i, int j, double &eng)
int eflag, double &fforce, double &eng)
{ {
double r = sqrt(rsq); double r = sqrt(rsq);
double dr = r - r0[type]; double dr = r - r0[type];
double ralpha = exp(-alpha[type]*dr); double ralpha = exp(-alpha[type]*dr);
eng = d0[type]*(1-ralpha)*(1-ralpha);
// force & energy
if (r > 0.0) fforce = -2.0*d0[type]*alpha[type]*(1-ralpha)*ralpha/r;
else fforce = 0.0;
if (eflag) eng = d0[type]*(1-ralpha)*(1-ralpha);
} }

View File

@ -28,7 +28,7 @@ class BondMorse : public Bond {
double equilibrium_distance(int); double equilibrium_distance(int);
void write_restart(FILE *); void write_restart(FILE *);
void read_restart(FILE *); void read_restart(FILE *);
void single(int, double, int, int, int, double &, double &); void single(int, double, int, int, double &);
private: private:
double *d0,*alpha,*r0; double *d0,*alpha,*r0;

View File

@ -44,11 +44,13 @@ BondNonlinear::~BondNonlinear()
void BondNonlinear::compute(int eflag, int vflag) void BondNonlinear::compute(int eflag, int vflag)
{ {
int i1,i2,n,type,factor; int i1,i2,n,type;
double delx,dely,delz,rsq,r,dr,drsq,lamdasq,denom,denomsq,fforce,rfactor; double delx,dely,delz,ebond,fbond;
double rsq,r,dr,drsq,lamdasq,denom,denomsq;
energy = 0.0; ebond = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -58,19 +60,10 @@ void BondNonlinear::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nbondlist; n++) { for (n = 0; n < nbondlist; n++) {
i1 = bondlist[n][0]; i1 = bondlist[n][0];
i2 = bondlist[n][1]; i2 = bondlist[n][1];
type = bondlist[n][2]; type = bondlist[n][2];
if (newton_bond) factor = 2;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
}
rfactor = 0.5 * factor;
delx = x[i1][0] - x[i2][0]; delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1]; dely = x[i1][1] - x[i2][1];
delz = x[i1][2] - x[i2][2]; delz = x[i1][2] - x[i2][2];
@ -86,33 +79,24 @@ void BondNonlinear::compute(int eflag, int vflag)
// force & energy // force & energy
fforce = -epsilon[type]/r * 2.0*dr*lamdasq/denomsq; fbond = -epsilon[type]/r * 2.0*dr*lamdasq/denomsq;
if (eflag) energy += rfactor * epsilon[type] * drsq / denom; if (eflag) ebond = epsilon[type] * drsq / denom;
// apply force to each of 2 atoms // apply force to each of 2 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] += delx*fforce; f[i1][0] += delx*fbond;
f[i1][1] += dely*fforce; f[i1][1] += dely*fbond;
f[i1][2] += delz*fforce; f[i1][2] += delz*fbond;
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx*fforce; f[i2][0] -= delx*fbond;
f[i2][1] -= dely*fforce; f[i2][1] -= dely*fbond;
f[i2][2] -= delz*fforce; f[i2][2] -= delz*fbond;
} }
// virial contribution if (evflag) ev_tally(i1,i2,nlocal,newton_bond,ebond,fbond,delx,dely,delz);
if (vflag) {
virial[0] += rfactor*delx*delx*fforce;
virial[1] += rfactor*dely*dely*fforce;
virial[2] += rfactor*delz*delz*fforce;
virial[3] += rfactor*delx*dely*fforce;
virial[4] += rfactor*delx*delz*fforce;
virial[5] += rfactor*dely*delz*fforce;
}
} }
} }
@ -198,18 +182,12 @@ void BondNonlinear::read_restart(FILE *fp)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void BondNonlinear::single(int type, double rsq, int i, int j, void BondNonlinear::single(int type, double rsq, int i, int j, double &eng)
int eflag, double &fforce, double &eng)
{ {
double r = sqrt(rsq); double r = sqrt(rsq);
double dr = r - r0[type]; double dr = r - r0[type];
double drsq = dr*dr; double drsq = dr*dr;
double lamdasq = lamda[type]*lamda[type]; double lamdasq = lamda[type]*lamda[type];
double denom = lamdasq - drsq; double denom = lamdasq - drsq;
double denomsq = denom*denom; eng = epsilon[type] * drsq / denom;
// force & energy
fforce = -epsilon[type]/r * 2.0*dr*lamdasq/denomsq;
if (eflag) eng = epsilon[type] * drsq / denom;
} }

View File

@ -28,7 +28,7 @@ class BondNonlinear : public Bond {
double equilibrium_distance(int); double equilibrium_distance(int);
void write_restart(FILE *); void write_restart(FILE *);
void read_restart(FILE *); void read_restart(FILE *);
void single(int, double, int, int, int, double &, double &); void single(int, double, int, int, double &);
private: private:
double *epsilon,*r0,*lamda; double *epsilon,*r0,*lamda;

View File

@ -55,13 +55,19 @@ BondQuartic::~BondQuartic()
void BondQuartic::compute(int eflag, int vflag) void BondQuartic::compute(int eflag, int vflag)
{ {
int i1,i2,n,m,type,factor,itype,jtype; int i1,i2,n,m,type,itype,jtype;
double delx,dely,delz,r,rsq,dr,r2,ra,rb,fforce,sr2,sr6,rfactor; double delx,dely,delz,ebond,fbond,evdwl,fpair;
double r,rsq,dr,r2,ra,rb,sr2,sr6;
Pair::One one; Pair::One one;
energy = 0.0; ebond = evdwl = 0.0;
eng_vdwl = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; else evflag = 0;
// insure pair->ev_tally() will use bond virial contribution
if (vflag_global == 2)
force->pair->vflag_either = force->pair->vflag_global = 1;
double **cutsq = force->pair->cutsq; double **cutsq = force->pair->cutsq;
double **x = atom->x; double **x = atom->x;
@ -81,14 +87,6 @@ void BondQuartic::compute(int eflag, int vflag)
i2 = bondlist[n][1]; i2 = bondlist[n][1];
type = bondlist[n][2]; type = bondlist[n][2];
if (newton_bond) factor = 2;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
}
rfactor = 0.5*factor;
delx = x[i1][0] - x[i2][0]; delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1]; dely = x[i1][1] - x[i2][1];
delz = x[i1][2] - x[i2][2]; delz = x[i1][2] - x[i2][2];
@ -114,18 +112,6 @@ void BondQuartic::compute(int eflag, int vflag)
continue; continue;
} }
// subtract out pairwise contribution from 2 atoms via pair->single()
// required since special_bond = 1,1,1
itype = atom->type[i1];
jtype = atom->type[i2];
if (rsq < cutsq[itype][jtype]) {
force->pair->single(i1,i2,itype,jtype,rsq,1.0,1.0,eflag,one);
fforce = -one.fforce;
if (eflag) eng_vdwl -= one.eng_vdwl + one.eng_coul;
} else fforce = 0.0;
// quartic bond // quartic bond
// 1st portion is from quartic term // 1st portion is from quartic term
// 2nd portion is from LJ term cut at 2^(1/6) with eps = sigma = 1.0 // 2nd portion is from LJ term cut at 2^(1/6) with eps = sigma = 1.0
@ -135,42 +121,60 @@ void BondQuartic::compute(int eflag, int vflag)
r2 = dr*dr; r2 = dr*dr;
ra = dr - b1[type]; ra = dr - b1[type];
rb = dr - b2[type]; rb = dr - b2[type];
fforce += -k[type]/r * (r2*(ra+rb) + 2.0*dr*ra*rb); fbond = -k[type]/r * (r2*(ra+rb) + 2.0*dr*ra*rb);
if (rsq < TWO_1_3) { if (rsq < TWO_1_3) {
sr2 = 1.0/rsq; sr2 = 1.0/rsq;
sr6 = sr2*sr2*sr2; sr6 = sr2*sr2*sr2;
fforce += 48.0*sr6*(sr6-0.5)/rsq; fbond += 48.0*sr6*(sr6-0.5)/rsq;
} }
if (eflag) { if (eflag) {
energy += rfactor*(k[type]*r2*ra*rb + u0[type]); ebond = k[type]*r2*ra*rb + u0[type];
if (rsq < TWO_1_3) energy += rfactor * (4.0*sr6*(sr6-1.0) + 1.0); if (rsq < TWO_1_3) ebond += 4.0*sr6*(sr6-1.0) + 1.0;
} }
// apply force to each of 2 atoms // apply force to each of 2 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] += delx*fforce; f[i1][0] += delx*fbond;
f[i1][1] += dely*fforce; f[i1][1] += dely*fbond;
f[i1][2] += delz*fforce; f[i1][2] += delz*fbond;
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx*fforce; f[i2][0] -= delx*fbond;
f[i2][1] -= dely*fforce; f[i2][1] -= dely*fbond;
f[i2][2] -= delz*fforce; f[i2][2] -= delz*fbond;
} }
// virial contribution if (evflag) ev_tally(i1,i2,nlocal,newton_bond,ebond,fbond,delx,dely,delz);
if (vflag) { // subtract out pairwise contribution from 2 atoms via pair->single()
virial[0] += rfactor * delx*delx*fforce; // required since special_bond = 1,1,1
virial[1] += rfactor * dely*dely*fforce; // tally energy/virial in pair, using newton_bond as newton flag
virial[2] += rfactor * delz*delz*fforce;
virial[3] += rfactor * delx*dely*fforce; itype = atom->type[i1];
virial[4] += rfactor * delx*delz*fforce; jtype = atom->type[i2];
virial[5] += rfactor * dely*delz*fforce;
if (rsq < cutsq[itype][jtype]) {
force->pair->single(i1,i2,itype,jtype,rsq,1.0,1.0,eflag,one);
fpair = -one.fforce;
if (eflag) evdwl = -(one.eng_vdwl + one.eng_coul);
if (newton_bond || i1 < nlocal) {
f[i1][0] += delx*fpair;
f[i1][1] += dely*fpair;
f[i1][2] += delz*fpair;
}
if (newton_bond || i2 < nlocal) {
f[i2][0] -= delx*fpair;
f[i2][1] -= dely*fpair;
f[i2][2] -= delz*fpair;
}
if (evflag) force->pair->ev_tally(i1,i2,nlocal,newton_bond,
evdwl,0.0,fpair,delx,dely,delz);
} }
} }
} }
@ -295,12 +299,11 @@ void BondQuartic::read_restart(FILE *fp)
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void BondQuartic::single(int type, double rsq, int i, int j, void BondQuartic::single(int type, double rsq, int i, int j, double &eng)
int eflag, double &fforce, double &eng)
{ {
double r,dr,r2,ra,rb,sr2,sr6; double r,dr,r2,ra,rb,sr2,sr6;
fforce = eng = 0.0; eng = 0.0;
if (type <= 0) return; if (type <= 0) return;
// subtract out pairwise contribution from 2 atoms via pair->single() // subtract out pairwise contribution from 2 atoms via pair->single()
@ -311,9 +314,8 @@ void BondQuartic::single(int type, double rsq, int i, int j,
if (rsq < force->pair->cutsq[itype][jtype]) { if (rsq < force->pair->cutsq[itype][jtype]) {
Pair::One one; Pair::One one;
force->pair->single(i,j,itype,jtype,rsq,1.0,1.0,eflag,one); force->pair->single(i,j,itype,jtype,rsq,1.0,1.0,1,one);
fforce = -one.fforce; eng = -one.eng_coul - one.eng_vdwl;
if (eflag) eng = -one.eng_coul - one.eng_vdwl;
} }
// quartic bond // quartic bond
@ -325,16 +327,11 @@ void BondQuartic::single(int type, double rsq, int i, int j,
r2 = dr*dr; r2 = dr*dr;
ra = dr - b1[type]; ra = dr - b1[type];
rb = dr - b2[type]; rb = dr - b2[type];
fforce += -k[type]/r * (r2*(ra+rb) + 2.0*dr*ra*rb);
eng += k[type]*r2*ra*rb + u0[type];
if (rsq < TWO_1_3) { if (rsq < TWO_1_3) {
sr2 = 1.0/rsq; sr2 = 1.0/rsq;
sr6 = sr2*sr2*sr2; sr6 = sr2*sr2*sr2;
fforce += 48.0*sr6*(sr6-0.5)/rsq; eng += 4.0*sr6*(sr6-1.0) + 1.0;
}
if (eflag) {
eng += k[type]*r2*ra*rb + u0[type];
if (rsq < TWO_1_3) eng += 4.0*sr6*(sr6-1.0) + 1.0;
} }
} }

View File

@ -29,7 +29,7 @@ class BondQuartic : public Bond {
double equilibrium_distance(int); double equilibrium_distance(int);
void write_restart(FILE *); void write_restart(FILE *);
void read_restart(FILE *); void read_restart(FILE *);
void single(int, double, int, int, int, double &, double &); void single(int, double, int, int, double &);
private: private:
double TWO_1_3; double TWO_1_3;

View File

@ -14,6 +14,10 @@
#include "math.h" #include "math.h"
#include "dihedral.h" #include "dihedral.h"
#include "atom.h" #include "atom.h"
#include "atom.h"
#include "force.h"
#include "pair.h"
#include "memory.h"
#include "error.h" #include "error.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -25,9 +29,22 @@ using namespace LAMMPS_NS;
Dihedral::Dihedral(LAMMPS *lmp) : Pointers(lmp) Dihedral::Dihedral(LAMMPS *lmp) : Pointers(lmp)
{ {
energy = 0.0;
allocated = 0; allocated = 0;
eng_vdwl = eng_coul = 0.0;
PI = 4.0*atan(1.0); PI = 4.0*atan(1.0);
maxeatom = maxvatom = 0;
eatom = NULL;
vatom = NULL;
}
/* ---------------------------------------------------------------------- */
Dihedral::~Dihedral()
{
memory->sfree(eatom);
memory->destroy_2d_double_array(vatom);
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -42,3 +59,191 @@ void Dihedral::init()
init_style(); init_style();
} }
/* ----------------------------------------------------------------------
setup for energy, virial computation
see integrate::ev_set() for values of eflag (0-3) and vflag (0-6)
------------------------------------------------------------------------- */
void Dihedral::ev_setup(int eflag, int vflag)
{
int i,n;
evflag = 1;
eflag_either = eflag;
eflag_global = eflag % 2;
eflag_atom = eflag / 2;
vflag_either = vflag;
vflag_global = vflag % 4;
vflag_atom = vflag / 4;
// reallocate per-atom arrays if necessary
if (eflag_atom && atom->nmax > maxeatom) {
maxeatom = atom->nmax;
memory->sfree(eatom);
eatom = (double *) memory->smalloc(maxeatom*sizeof(double),"bond:eatom");
}
if (vflag_atom && atom->nmax > maxvatom) {
maxvatom = atom->nmax;
memory->destroy_2d_double_array(vatom);
vatom = memory->create_2d_double_array(maxvatom,6,"bond:vatom");
}
// zero accumulators
if (eflag_global) energy = 0.0;
if (vflag_global) for (i = 0; i < 6; i++) virial[i] = 0.0;
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
for (i = 0; i < n; i++) eatom[i] = 0.0;
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
for (i = 0; i < n; i++) {
vatom[i][0] = 0.0;
vatom[i][1] = 0.0;
vatom[i][2] = 0.0;
vatom[i][3] = 0.0;
vatom[i][4] = 0.0;
vatom[i][5] = 0.0;
}
}
}
/* ----------------------------------------------------------------------
tally energy and virial into global and per-atom accumulators
virial = r1F1 + r2F2 + r3F3 + r4F4 = (r1-r2) F1 + (r3-r2) F3 + (r4-r2) F4
= (r1-r2) F1 + (r3-r2) F3 + (r4-r3 + r3-r2) F4
= vb1*f1 + vb2*f3 + (vb3+vb2)*f4
------------------------------------------------------------------------- */
void Dihedral::ev_tally(int i1, int i2, int i3, int i4,
int nlocal, int newton_bond,
double edihedral, double *f1, double *f3, double *f4,
double vb1x, double vb1y, double vb1z,
double vb2x, double vb2y, double vb2z,
double vb3x, double vb3y, double vb3z)
{
double edihedralquarter,v[6];
if (eflag_either) {
if (eflag_global) {
if (newton_bond) energy += edihedral;
else {
edihedralquarter = 0.25*edihedral;
if (i1 < nlocal) energy += edihedralquarter;
if (i2 < nlocal) energy += edihedralquarter;
if (i3 < nlocal) energy += edihedralquarter;
if (i4 < nlocal) energy += edihedralquarter;
}
}
if (eflag_atom) {
edihedralquarter = 0.25*edihedral;
if (newton_bond || i1 < nlocal) eatom[i1] += edihedralquarter;
if (newton_bond || i2 < nlocal) eatom[i2] += edihedralquarter;
if (newton_bond || i3 < nlocal) eatom[i3] += edihedralquarter;
if (newton_bond || i4 < nlocal) eatom[i4] += edihedralquarter;
}
}
if (vflag_either) {
v[0] = vb1x*f1[0] + vb2x*f3[0] + (vb3x+vb2x)*f4[0];
v[1] = vb1y*f1[1] + vb2y*f3[1] + (vb3y+vb2y)*f4[1];
v[2] = vb1z*f1[2] + vb2z*f3[2] + (vb3z+vb2z)*f4[2];
v[3] = vb1x*f1[1] + vb2x*f3[1] + (vb3x+vb2x)*f4[1];
v[4] = vb1x*f1[2] + vb2x*f3[2] + (vb3x+vb2x)*f4[2];
v[5] = vb1y*f1[2] + vb2y*f3[2] + (vb3y+vb2y)*f4[2];
if (vflag_global) {
if (newton_bond) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
} else {
if (i1 < nlocal) {
virial[0] += 0.25*v[0];
virial[1] += 0.25*v[1];
virial[2] += 0.25*v[2];
virial[3] += 0.25*v[3];
virial[4] += 0.25*v[4];
virial[5] += 0.25*v[5];
}
if (i2 < nlocal) {
virial[0] += 0.25*v[0];
virial[1] += 0.25*v[1];
virial[2] += 0.25*v[2];
virial[3] += 0.25*v[3];
virial[4] += 0.25*v[4];
virial[5] += 0.25*v[5];
}
if (i3 < nlocal) {
virial[0] += 0.25*v[0];
virial[1] += 0.25*v[1];
virial[2] += 0.25*v[2];
virial[3] += 0.25*v[3];
virial[4] += 0.25*v[4];
virial[5] += 0.25*v[5];
}
if (i4 < nlocal) {
virial[0] += 0.25*v[0];
virial[1] += 0.25*v[1];
virial[2] += 0.25*v[2];
virial[3] += 0.25*v[3];
virial[4] += 0.25*v[4];
virial[5] += 0.25*v[5];
}
}
}
if (vflag_atom) {
if (newton_bond || i1 < nlocal) {
vatom[i1][0] += 0.25*v[0];
vatom[i1][1] += 0.25*v[1];
vatom[i1][2] += 0.25*v[2];
vatom[i1][3] += 0.25*v[3];
vatom[i1][4] += 0.25*v[4];
vatom[i1][5] += 0.25*v[5];
}
if (newton_bond || i2 < nlocal) {
vatom[i2][0] += 0.25*v[0];
vatom[i2][1] += 0.25*v[1];
vatom[i2][2] += 0.25*v[2];
vatom[i2][3] += 0.25*v[3];
vatom[i2][4] += 0.25*v[4];
vatom[i2][5] += 0.25*v[5];
}
if (newton_bond || i3 < nlocal) {
vatom[i3][0] += 0.25*v[0];
vatom[i3][1] += 0.25*v[1];
vatom[i3][2] += 0.25*v[2];
vatom[i3][3] += 0.25*v[3];
vatom[i3][4] += 0.25*v[4];
vatom[i3][5] += 0.25*v[5];
}
if (newton_bond || i4 < nlocal) {
vatom[i4][0] += 0.25*v[0];
vatom[i4][1] += 0.25*v[1];
vatom[i4][2] += 0.25*v[2];
vatom[i4][3] += 0.25*v[3];
vatom[i4][4] += 0.25*v[4];
vatom[i4][5] += 0.25*v[5];
}
}
}
}
/* ---------------------------------------------------------------------- */
double Dihedral::memory_usage()
{
double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
return bytes;
}

View File

@ -57,21 +57,25 @@ DihedralCharmm::~DihedralCharmm()
void DihedralCharmm::compute(int eflag, int vflag) void DihedralCharmm::compute(int eflag, int vflag)
{ {
int i,m,n,i1,i2,i3,i4,type,factor; int i1,i2,i3,i4,i,m,n,type;
double rfactor; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double vb1x,vb1y,vb1z,vb2x,vb2y; double edihedral,f1[3],f2[3],f3[3],f4[3];
double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z;
double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv; double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv;
double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb; double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb;
double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;
double c,s,p,sx1,sx2,sx12,sy1,sy2,sy12,sz1,sz2,sz12; double c,s,p,sx2,sy2,sz2;
int itype,jtype; int itype,jtype;
double delx,dely,delz,rsq,r2inv,r6inv; double delx,dely,delz,rsq,r2inv,r6inv;
double fforce,forcecoul,forcelj,phicoul,philj; double forcecoul,forcelj,fpair,ecoul,evdwl;
energy = 0.0; edihedral = evdwl = ecoul = 0.0;
eng_coul = eng_vdwl = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; else evflag = 0;
// insure pair->ev_tally() will use 1-4 virial contribution
if (vflag_global == 2)
force->pair->vflag_either = force->pair->vflag_global = 1;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -84,23 +88,12 @@ void DihedralCharmm::compute(int eflag, int vflag)
double qqrd2e = force->qqrd2e; double qqrd2e = force->qqrd2e;
for (n = 0; n < ndihedrallist; n++) { for (n = 0; n < ndihedrallist; n++) {
i1 = dihedrallist[n][0]; i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1]; i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2]; i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3]; i4 = dihedrallist[n][3];
type = dihedrallist[n][4]; type = dihedrallist[n][4];
if (newton_bond) factor = 4;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
if (i4 < nlocal) factor++;
}
rfactor = 0.25 * factor;
// 1st bond // 1st bond
vb1x = x[i1][0] - x[i2][0]; vb1x = x[i1][0] - x[i2][0];
@ -191,7 +184,7 @@ void DihedralCharmm::compute(int eflag, int vflag)
df1 = 0.0; df1 = 0.0;
} }
if (eflag) energy += rfactor * k[type] * p; if (eflag) edihedral = k[type] * p;
fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm;
hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm;
@ -210,60 +203,62 @@ void DihedralCharmm::compute(int eflag, int vflag)
dthy = gbb*by; dthy = gbb*by;
dthz = gbb*bz; dthz = gbb*bz;
df = k[type] * df1; df = -k[type] * df1;
sx1 = df*dtfx; sx2 = df*dtgx;
sy1 = df*dtfy; sy2 = df*dtgy;
sz1 = df*dtfz; sz2 = df*dtgz;
sx2 = -df*dtgx;
sy2 = -df*dtgy; f1[0] = df*dtfx;
sz2 = -df*dtgz; f1[1] = df*dtfy;
sx12 = df*dthx; f1[2] = df*dtfz;
sy12 = df*dthy;
sz12 = df*dthz; f2[0] = sx2 - f1[0];
f2[1] = sy2 - f1[1];
f2[2] = sz2 - f1[2];
f4[0] = df*dthx;
f4[1] = df*dthy;
f4[2] = df*dthz;
f3[0] = -sx2 - f4[0];
f3[1] = -sy2 - f4[1];
f3[2] = -sz2 - f4[2];
// apply force to each of 4 atoms // apply force to each of 4 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= sx1; f[i1][0] += f1[0];
f[i1][1] -= sy1; f[i1][1] += f1[1];
f[i1][2] -= sz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += sx2 + sx1; f[i2][0] += f2[0];
f[i2][1] += sy2 + sy1; f[i2][1] += f2[1];
f[i2][2] += sz2 + sz1; f[i2][2] += f2[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] += sx12 - sx2; f[i3][0] += f3[0];
f[i3][1] += sy12 - sy2; f[i3][1] += f3[1];
f[i3][2] += sz12 - sz2; f[i3][2] += f3[2];
} }
if (newton_bond || i4 < nlocal) { if (newton_bond || i4 < nlocal) {
f[i4][0] -= sx12; f[i4][0] += f4[0];
f[i4][1] -= sy12; f[i4][1] += f4[1];
f[i4][2] -= sz12; f[i4][2] += f4[2];
} }
// virial contribution if (evflag)
ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4,
if (vflag) { vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12);
virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12);
virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12);
virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12);
virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12);
virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12);
}
// 1-4 LJ and Coulomb interactions // 1-4 LJ and Coulomb interactions
// force, energy, and virial // tally energy/virial in pair, using newton_bond as newton flag
if (weight[type] > 0.0) { if (weight[type] > 0.0) {
itype = atomtype[i1]; itype = atomtype[i1];
jtype = atomtype[i4]; jtype = atomtype[i4];
@ -278,35 +273,27 @@ void DihedralCharmm::compute(int eflag, int vflag)
if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv; if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv;
else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv); else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv);
forcelj = r6inv * (lj14_1[itype][jtype]*r6inv - lj14_2[itype][jtype]); forcelj = r6inv * (lj14_1[itype][jtype]*r6inv - lj14_2[itype][jtype]);
fforce = weight[type] * (forcelj+forcecoul)*r2inv; fpair = weight[type] * (forcelj+forcecoul)*r2inv;
if (eflag) { if (eflag) {
phicoul = weight[type] * rfactor * forcecoul; ecoul = weight[type] * forcecoul;
philj = r6inv * (lj14_3[itype][jtype]*r6inv - lj14_4[itype][jtype]); evdwl = r6inv * (lj14_3[itype][jtype]*r6inv - lj14_4[itype][jtype]);
philj = weight[type] * rfactor * philj; evdwl *= weight[type];
eng_coul += phicoul;
eng_vdwl += philj;
} }
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] += delx*fforce; f[i1][0] += delx*fpair;
f[i1][1] += dely*fforce; f[i1][1] += dely*fpair;
f[i1][2] += delz*fforce; f[i1][2] += delz*fpair;
} }
if (newton_bond || i4 < nlocal) { if (newton_bond || i4 < nlocal) {
f[i4][0] -= delx*fforce; f[i4][0] -= delx*fpair;
f[i4][1] -= dely*fforce; f[i4][1] -= dely*fpair;
f[i4][2] -= delz*fforce; f[i4][2] -= delz*fpair;
} }
if (vflag) { if (evflag) force->pair->ev_tally(i1,i4,nlocal,newton_bond,
virial[0] += rfactor * delx*delx*fforce; evdwl,ecoul,fpair,delx,dely,delz);
virial[1] += rfactor * dely*dely*fforce;
virial[2] += rfactor * delz*delz*fforce;
virial[3] += rfactor * delx*dely*fforce;
virial[4] += rfactor * delx*delz*fforce;
virial[5] += rfactor * dely*delz*fforce;
}
} }
} }
} }

View File

@ -55,17 +55,17 @@ DihedralHarmonic::~DihedralHarmonic()
void DihedralHarmonic::compute(int eflag, int vflag) void DihedralHarmonic::compute(int eflag, int vflag)
{ {
int i,m,n,i1,i2,i3,i4,type,factor; int i1,i2,i3,i4,i,m,n,type;
double rfactor; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double vb1x,vb1y,vb1z,vb2x,vb2y; double edihedral,f1[3],f2[3],f3[3],f4[3];
double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z;
double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv; double ax,ay,az,bx,by,bz,rasq,rbsq,rgsq,rg,rginv,ra2inv,rb2inv,rabinv;
double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb; double df,df1,ddf1,fg,hg,fga,hgb,gaa,gbb;
double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz; double dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;
double c,s,p,sx1,sx2,sx12,sy1,sy2,sy12,sz1,sz2,sz12; double c,s,p,sx2,sy2,sz2;
energy = 0.0; edihedral = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -75,23 +75,12 @@ void DihedralHarmonic::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < ndihedrallist; n++) { for (n = 0; n < ndihedrallist; n++) {
i1 = dihedrallist[n][0]; i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1]; i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2]; i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3]; i4 = dihedrallist[n][3];
type = dihedrallist[n][4]; type = dihedrallist[n][4];
if (newton_bond) factor = 4;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
if (i4 < nlocal) factor++;
}
rfactor = 0.25 * factor;
// 1st bond // 1st bond
vb1x = x[i1][0] - x[i2][0]; vb1x = x[i1][0] - x[i2][0];
@ -184,7 +173,7 @@ void DihedralHarmonic::compute(int eflag, int vflag)
df1 = 0.0; df1 = 0.0;
} }
if (eflag) energy += rfactor * k[type] * p; if (eflag) edihedral = k[type] * p;
fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm; fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm;
hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm; hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm;
@ -203,54 +192,57 @@ void DihedralHarmonic::compute(int eflag, int vflag)
dthy = gbb*by; dthy = gbb*by;
dthz = gbb*bz; dthz = gbb*bz;
df = k[type] * df1; df = -k[type] * df1;
sx1 = df*dtfx; sx2 = df*dtgx;
sy1 = df*dtfy; sy2 = df*dtgy;
sz1 = df*dtfz; sz2 = df*dtgz;
sx2 = -df*dtgx;
sy2 = -df*dtgy; f1[0] = df*dtfx;
sz2 = -df*dtgz; f1[1] = df*dtfy;
sx12 = df*dthx; f1[2] = df*dtfz;
sy12 = df*dthy;
sz12 = df*dthz; f2[0] = sx2 - f1[0];
f2[1] = sy2 - f1[1];
f2[2] = sz2 - f1[2];
f4[0] = df*dthx;
f4[1] = df*dthy;
f4[2] = df*dthz;
f3[0] = -sx2 - f4[0];
f3[1] = -sy2 - f4[1];
f3[2] = -sz2 - f4[2];
// apply force to each of 4 atoms // apply force to each of 4 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= sx1; f[i1][0] += f1[0];
f[i1][1] -= sy1; f[i1][1] += f1[1];
f[i1][2] -= sz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += sx2 + sx1; f[i2][0] += f2[0];
f[i2][1] += sy2 + sy1; f[i2][1] += f2[1];
f[i2][2] += sz2 + sz1; f[i2][2] += f2[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] += sx12 - sx2; f[i3][0] += f3[0];
f[i3][1] += sy12 - sy2; f[i3][1] += f3[1];
f[i3][2] += sz12 - sz2; f[i3][2] += f3[2];
} }
if (newton_bond || i4 < nlocal) { if (newton_bond || i4 < nlocal) {
f[i4][0] -= sx12; f[i4][0] += f4[0];
f[i4][1] -= sy12; f[i4][1] += f4[1];
f[i4][2] -= sz12; f[i4][2] += f4[2];
} }
// virial contribution if (evflag)
ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4,
if (vflag) { vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12);
virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12);
virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12);
virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12);
virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12);
virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12);
}
} }
} }

View File

@ -58,18 +58,18 @@ DihedralHelix::~DihedralHelix()
void DihedralHelix::compute(int eflag, int vflag) void DihedralHelix::compute(int eflag, int vflag)
{ {
int n,i1,i2,i3,i4,type,factor; int i1,i2,i3,i4,n,type;
double rfactor; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double vb1x,vb1y,vb1z,vb2x,vb2y; double edihedral,f1[3],f2[3],f3[3],f4[3];
double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z,sb1; double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22; double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22;
double a33,a12,a13,a23,sx1,sx2,sx12,sy1,sy2,sy12; double a33,a12,a13,a23,sx2,sy2,sz2;
double sz1,sz2,sz12,s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2; double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
energy = 0.0; edihedral = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -79,23 +79,12 @@ void DihedralHelix::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < ndihedrallist; n++) { for (n = 0; n < ndihedrallist; n++) {
i1 = dihedrallist[n][0]; i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1]; i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2]; i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3]; i4 = dihedrallist[n][3];
type = dihedrallist[n][4]; type = dihedrallist[n][4];
if (newton_bond) factor = 4;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
if (i4 < nlocal) factor++;
}
rfactor = 0.25 * factor;
// 1st bond // 1st bond
vb1x = x[i1][0] - x[i2][0]; vb1x = x[i1][0] - x[i2][0];
@ -207,64 +196,67 @@ void DihedralHelix::compute(int eflag, int vflag)
pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv + pd = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv +
cphi[type]*sin(phi + 0.25*PI)*siinv; cphi[type]*sin(phi + 0.25*PI)*siinv;
if (eflag) energy += rfactor * p; if (eflag) edihedral = p;
a = pd; a = pd;
c = c * a; c = c * a;
s12 = s12 * a; s12 = s12 * a;
a11 = -c*sb1*s1; a11 = c*sb1*s1;
a22 = sb2 * (2.0*c0*s12 - c*(s1+s2)); a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
a33 = -c*sb3*s2; a33 = c*sb3*s2;
a12 = r12c1 * (c1mag*c*s1 + c2mag*s12); a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12);
a13 = rb1*rb3*s12; a13 = -rb1*rb3*s12;
a23 = r12c2 * (-c2mag*c*s2 - c1mag*s12); a23 = r12c2 * (c2mag*c*s2 + c1mag*s12);
sx1 = a11*vb1x + a12*vb2x + a13*vb3x;
sx2 = a12*vb1x + a22*vb2x + a23*vb3x; sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sx12 = a13*vb1x + a23*vb2x + a33*vb3x;
sy1 = a11*vb1y + a12*vb2y + a13*vb3y;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y; sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sy12 = a13*vb1y + a23*vb2y + a33*vb3y;
sz1 = a11*vb1z + a12*vb2z + a13*vb3z;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z; sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
sz12 = a13*vb1z + a23*vb2z + a33*vb3z;
f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// apply force to each of 4 atoms // apply force to each of 4 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= sx1; f[i1][0] += f1[0];
f[i1][1] -= sy1; f[i1][1] += f1[1];
f[i1][2] -= sz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += sx2 + sx1; f[i2][0] += f2[0];
f[i2][1] += sy2 + sy1; f[i2][1] += f2[1];
f[i2][2] += sz2 + sz1; f[i2][2] += f2[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] += sx12 - sx2; f[i3][0] += f3[0];
f[i3][1] += sy12 - sy2; f[i3][1] += f3[1];
f[i3][2] += sz12 - sz2; f[i3][2] += f3[2];
} }
if (newton_bond || i4 < nlocal) { if (newton_bond || i4 < nlocal) {
f[i4][0] -= sx12; f[i4][0] += f4[0];
f[i4][1] -= sy12; f[i4][1] += f4[1];
f[i4][2] -= sz12; f[i4][2] += f4[2];
} }
// virial contribution if (evflag)
ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4,
if (vflag) { vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12);
virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12);
virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12);
virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12);
virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12);
virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12);
}
} }
} }

View File

@ -59,7 +59,7 @@ DihedralHybrid::~DihedralHybrid()
void DihedralHybrid::compute(int eflag, int vflag) void DihedralHybrid::compute(int eflag, int vflag)
{ {
int i,m,n; int i,j,m,n;
// save ptrs to original dihedrallist // save ptrs to original dihedrallist
@ -98,24 +98,36 @@ void DihedralHybrid::compute(int eflag, int vflag)
} }
// call each sub-style's compute function // call each sub-style's compute function
// must set neighbor->dihedrallist to sub-style dihedrallist before call // set neighbor->dihedrallist to sub-style dihedrallist before call
// accumulate sub-style energy,virial in hybrid's energy,virial // accumulate sub-style global/peratom energy/virial in hybrid
energy = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
eng_vdwl = eng_coul = 0.0; else evflag = 0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0;
for (m = 0; m < nstyles; m++) { for (m = 0; m < nstyles; m++) {
if (styles[m] == NULL) continue; if (styles[m] == NULL) continue;
neighbor->ndihedrallist = ndihedrallist[m]; neighbor->ndihedrallist = ndihedrallist[m];
neighbor->dihedrallist = dihedrallist[m]; neighbor->dihedrallist = dihedrallist[m];
styles[m]->compute(eflag,vflag); styles[m]->compute(eflag,vflag);
if (eflag) {
energy += styles[m]->energy; if (eflag_global) energy += styles[m]->energy;
eng_vdwl += styles[m]->eng_vdwl; if (vflag_global)
eng_coul += styles[m]->eng_coul; for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n];
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
double *eatom_substyle = styles[m]->eatom;
for (i = 0; i < n; i++) eatom[i] += eatom_substyle[i];
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
double **vatom_substyle = styles[m]->vatom;
for (i = 0; i < n; i++)
for (j = 0; j < 6; j++)
vatom[i][j] += vatom_substyle[i][j];
} }
if (vflag) for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n];
} }
// restore ptrs to original dihedrallist // restore ptrs to original dihedrallist
@ -250,7 +262,8 @@ void DihedralHybrid::read_restart(FILE *fp)
double DihedralHybrid::memory_usage() double DihedralHybrid::memory_usage()
{ {
double bytes = 0.0; double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
for (int m = 0; m < nstyles; m++) bytes += maxdihedral[m]*5 * sizeof(int); for (int m = 0; m < nstyles; m++) bytes += maxdihedral[m]*5 * sizeof(int);
for (int m = 0; m < nstyles; m++) for (int m = 0; m < nstyles; m++)
if (styles[m]) bytes += styles[m]->memory_usage(); if (styles[m]) bytes += styles[m]->memory_usage();

View File

@ -57,18 +57,18 @@ DihedralMultiHarmonic::~DihedralMultiHarmonic()
void DihedralMultiHarmonic::compute(int eflag, int vflag) void DihedralMultiHarmonic::compute(int eflag, int vflag)
{ {
int n,i1,i2,i3,i4,type,factor; int i1,i2,i3,i4,n,type;
double rfactor; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double vb1x,vb1y,vb1z,vb2x,vb2y; double edihedral,f1[3],f2[3],f3[3],f4[3];
double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z,sb1; double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22; double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22;
double a33,a12,a13,a23,sx1,sx2,sx12,sy1,sy2,sy12; double a33,a12,a13,a23,sx2,sy2,sz2;
double sz1,sz2,sz12,s2,sin2; double s2,sin2;
energy = 0.0; edihedral = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -78,23 +78,12 @@ void DihedralMultiHarmonic::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < ndihedrallist; n++) { for (n = 0; n < ndihedrallist; n++) {
i1 = dihedrallist[n][0]; i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1]; i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2]; i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3]; i4 = dihedrallist[n][3];
type = dihedrallist[n][4]; type = dihedrallist[n][4];
if (newton_bond) factor = 4;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
if (i4 < nlocal) factor++;
}
rfactor = 0.25 * factor;
// 1st bond // 1st bond
vb1x = x[i1][0] - x[i2][0]; vb1x = x[i1][0] - x[i2][0];
@ -194,64 +183,67 @@ void DihedralMultiHarmonic::compute(int eflag, int vflag)
p = a1[type] + c*(a2[type] + c*(a3[type] + c*(a4[type] + c*a5[type]))); p = a1[type] + c*(a2[type] + c*(a3[type] + c*(a4[type] + c*a5[type])));
pd = a2[type] + c*(2.0*a3[type] + c*(3.0*a4[type] + c*4.0*a5[type])); pd = a2[type] + c*(2.0*a3[type] + c*(3.0*a4[type] + c*4.0*a5[type]));
if (eflag) energy += rfactor * p; if (eflag) edihedral = p;
a = pd; a = pd;
c = c * a; c = c * a;
s12 = s12 * a; s12 = s12 * a;
a11 = (-c*sb1*s1); a11 = c*sb1*s1;
a22 = sb2*(2.0*c0*s12 - c*(s1+s2)); a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
a33 = (-c*sb3*s2); a33 = c*sb3*s2;
a12 = r12c1*(c1mag*c*s1 + c2mag*s12); a12 = -r12c1*(c1mag*c*s1 + c2mag*s12);
a13 = rb1*rb3*s12; a13 = -rb1*rb3*s12;
a23 = r12c2*(-c2mag*c*s2 - c1mag*s12); a23 = r12c2*(c2mag*c*s2 + c1mag*s12);
sx1 = a11*vb1x + a12*vb2x + a13*vb3x;
sx2 = a12*vb1x + a22*vb2x + a23*vb3x; sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sx12 = a13*vb1x + a23*vb2x + a33*vb3x;
sy1 = a11*vb1y + a12*vb2y + a13*vb3y;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y; sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sy12 = a13*vb1y + a23*vb2y + a33*vb3y;
sz1 = a11*vb1z + a12*vb2z + a13*vb3z;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z; sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
sz12 = a13*vb1z + a23*vb2z + a33*vb3z;
f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// apply force to each of 4 atoms // apply force to each of 4 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= sx1; f[i1][0] += f1[0];
f[i1][1] -= sy1; f[i1][1] += f1[1];
f[i1][2] -= sz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += sx2 + sx1; f[i2][0] += f2[0];
f[i2][1] += sy2 + sy1; f[i2][1] += f2[1];
f[i2][2] += sz2 + sz1; f[i2][2] += f2[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] += sx12 - sx2; f[i3][0] += f3[0];
f[i3][1] += sy12 - sy2; f[i3][1] += f3[1];
f[i3][2] += sz12 - sz2; f[i3][2] += f3[2];
} }
if (newton_bond || i4 < nlocal) { if (newton_bond || i4 < nlocal) {
f[i4][0] -= sx12; f[i4][0] += f4[0];
f[i4][1] -= sy12; f[i4][1] += f4[1];
f[i4][2] -= sz12; f[i4][2] += f4[2];
} }
// virial contribution if (evflag)
ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4,
if (vflag) { vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12);
virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12);
virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12);
virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12);
virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12);
virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12);
}
} }
} }

View File

@ -57,18 +57,18 @@ DihedralOPLS::~DihedralOPLS()
void DihedralOPLS::compute(int eflag, int vflag) void DihedralOPLS::compute(int eflag, int vflag)
{ {
int n,i1,i2,i3,i4,type,factor; int i1,i2,i3,i4,n,type;
double rfactor; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double vb1x,vb1y,vb1z,vb2x,vb2y; double edihedral,f1[3],f2[3],f3[3],f4[3];
double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z,sb1; double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22; double c2mag,sc1,sc2,s1,s12,c,p,pd,a,a11,a22;
double a33,a12,a13,a23,sx1,sx2,sx12,sy1,sy2,sy12; double a33,a12,a13,a23,sx2,sy2,sz2;
double sz1,sz2,sz12,s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2; double s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
energy = 0.0; edihedral = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -78,23 +78,12 @@ void DihedralOPLS::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < ndihedrallist; n++) { for (n = 0; n < ndihedrallist; n++) {
i1 = dihedrallist[n][0]; i1 = dihedrallist[n][0];
i2 = dihedrallist[n][1]; i2 = dihedrallist[n][1];
i3 = dihedrallist[n][2]; i3 = dihedrallist[n][2];
i4 = dihedrallist[n][3]; i4 = dihedrallist[n][3];
type = dihedrallist[n][4]; type = dihedrallist[n][4];
if (newton_bond) factor = 4;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
if (i4 < nlocal) factor++;
}
rfactor = 0.25 * factor;
// 1st bond // 1st bond
vb1x = x[i1][0] - x[i2][0]; vb1x = x[i1][0] - x[i2][0];
@ -208,64 +197,67 @@ void DihedralOPLS::compute(int eflag, int vflag)
pd = k1[type] - 2.0*k2[type]*sin(2.0*phi)*siinv + pd = k1[type] - 2.0*k2[type]*sin(2.0*phi)*siinv +
3.0*k3[type]*sin(3.0*phi)*siinv - 4.0*k4[type]*sin(4.0*phi)*siinv; 3.0*k3[type]*sin(3.0*phi)*siinv - 4.0*k4[type]*sin(4.0*phi)*siinv;
if (eflag) energy += rfactor * p; if (eflag) edihedral = p;
a = pd; a = pd;
c = c * a; c = c * a;
s12 = s12 * a; s12 = s12 * a;
a11 = -c*sb1*s1; a11 = c*sb1*s1;
a22 = sb2 * (2.0*c0*s12 - c*(s1+s2)); a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
a33 = -c*sb3*s2; a33 = c*sb3*s2;
a12 = r12c1 * (c1mag*c*s1 + c2mag*s12); a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12);
a13 = rb1*rb3*s12; a13 = -rb1*rb3*s12;
a23 = r12c2 * (-c2mag*c*s2 - c1mag*s12); a23 = r12c2 * (c2mag*c*s2 + c1mag*s12);
sx1 = a11*vb1x + a12*vb2x + a13*vb3x;
sx2 = a12*vb1x + a22*vb2x + a23*vb3x; sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sx12 = a13*vb1x + a23*vb2x + a33*vb3x;
sy1 = a11*vb1y + a12*vb2y + a13*vb3y;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y; sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sy12 = a13*vb1y + a23*vb2y + a33*vb3y;
sz1 = a11*vb1z + a12*vb2z + a13*vb3z;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z; sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
sz12 = a13*vb1z + a23*vb2z + a33*vb3z;
f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// apply force to each of 4 atoms // apply force to each of 4 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= sx1; f[i1][0] += f1[0];
f[i1][1] -= sy1; f[i1][1] += f1[1];
f[i1][2] -= sz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += sx2 + sx1; f[i2][0] += f2[0];
f[i2][1] += sy2 + sy1; f[i2][1] += f2[1];
f[i2][2] += sz2 + sz1; f[i2][2] += f2[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] += sx12 - sx2; f[i3][0] += f3[0];
f[i3][1] += sy12 - sy2; f[i3][1] += f3[1];
f[i3][2] += sz12 - sz2; f[i3][2] += f3[2];
} }
if (newton_bond || i4 < nlocal) { if (newton_bond || i4 < nlocal) {
f[i4][0] -= sx12; f[i4][0] += f4[0];
f[i4][1] -= sy12; f[i4][1] += f4[1];
f[i4][2] -= sz12; f[i4][2] += f4[2];
} }
// virial contribution if (evflag)
ev_tally(i1,i2,i3,i4,nlocal,newton_bond,edihedral,f1,f3,f4,
if (vflag) { vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12);
virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12);
virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12);
virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12);
virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12);
virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12);
}
} }
} }

View File

@ -14,6 +14,8 @@
#include "math.h" #include "math.h"
#include "improper.h" #include "improper.h"
#include "atom.h" #include "atom.h"
#include "force.h"
#include "memory.h"
#include "error.h" #include "error.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -22,8 +24,22 @@ using namespace LAMMPS_NS;
Improper::Improper(LAMMPS *lmp) : Pointers(lmp) Improper::Improper(LAMMPS *lmp) : Pointers(lmp)
{ {
energy = 0.0;
allocated = 0; allocated = 0;
PI = 4.0*atan(1.0); PI = 4.0*atan(1.0);
maxeatom = maxvatom = 0;
eatom = NULL;
vatom = NULL;
}
/* ---------------------------------------------------------------------- */
Improper::~Improper()
{
memory->sfree(eatom);
memory->destroy_2d_double_array(vatom);
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -36,3 +52,192 @@ void Improper::init()
for (int i = 1; i <= atom->nimpropertypes; i++) for (int i = 1; i <= atom->nimpropertypes; i++)
if (setflag[i] == 0) error->all("All improper coeffs are not set"); if (setflag[i] == 0) error->all("All improper coeffs are not set");
} }
/* ----------------------------------------------------------------------
setup for energy, virial computation
see integrate::ev_set() for values of eflag (0-3) and vflag (0-6)
------------------------------------------------------------------------- */
void Improper::ev_setup(int eflag, int vflag)
{
int i,n;
evflag = 1;
eflag_either = eflag;
eflag_global = eflag % 2;
eflag_atom = eflag / 2;
vflag_either = vflag;
vflag_global = vflag % 4;
vflag_atom = vflag / 4;
// reallocate per-atom arrays if necessary
if (eflag_atom && atom->nmax > maxeatom) {
maxeatom = atom->nmax;
memory->sfree(eatom);
eatom = (double *) memory->smalloc(maxeatom*sizeof(double),"bond:eatom");
}
if (vflag_atom && atom->nmax > maxvatom) {
maxvatom = atom->nmax;
memory->destroy_2d_double_array(vatom);
vatom = memory->create_2d_double_array(maxvatom,6,"bond:vatom");
}
// zero accumulators
if (eflag_global) energy = 0.0;
if (vflag_global) for (i = 0; i < 6; i++) virial[i] = 0.0;
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
for (i = 0; i < n; i++) eatom[i] = 0.0;
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
for (i = 0; i < n; i++) {
vatom[i][0] = 0.0;
vatom[i][1] = 0.0;
vatom[i][2] = 0.0;
vatom[i][3] = 0.0;
vatom[i][4] = 0.0;
vatom[i][5] = 0.0;
}
}
}
/* ----------------------------------------------------------------------
tally energy and virial into global and per-atom accumulators
virial = r1F1 + r2F2 + r3F3 + r4F4 = (r1-r2) F1 + (r3-r2) F3 + (r4-r2) F4
= (r1-r2) F1 + (r3-r2) F3 + (r4-r3 + r3-r2) F4
= vb1*f1 + vb2*f3 + (vb3+vb2)*f4
------------------------------------------------------------------------- */
void Improper::ev_tally(int i1, int i2, int i3, int i4,
int nlocal, int newton_bond,
double eimproper, double *f1, double *f3, double *f4,
double vb1x, double vb1y, double vb1z,
double vb2x, double vb2y, double vb2z,
double vb3x, double vb3y, double vb3z)
{
double eimproperquarter,v[6];
if (eflag_either) {
if (eflag_global) {
if (newton_bond) energy += eimproper;
else {
eimproperquarter = 0.25*eimproper;
if (i1 < nlocal) energy += eimproperquarter;
if (i2 < nlocal) energy += eimproperquarter;
if (i3 < nlocal) energy += eimproperquarter;
if (i4 < nlocal) energy += eimproperquarter;
}
}
if (eflag_atom) {
eimproperquarter = 0.25*eimproper;
if (newton_bond || i1 < nlocal) eatom[i1] += eimproperquarter;
if (newton_bond || i2 < nlocal) eatom[i2] += eimproperquarter;
if (newton_bond || i3 < nlocal) eatom[i3] += eimproperquarter;
if (newton_bond || i4 < nlocal) eatom[i4] += eimproperquarter;
}
}
if (vflag_either) {
v[0] = vb1x*f1[0] + vb2x*f3[0] + (vb3x+vb2x)*f4[0];
v[1] = vb1y*f1[1] + vb2y*f3[1] + (vb3y+vb2y)*f4[1];
v[2] = vb1z*f1[2] + vb2z*f3[2] + (vb3z+vb2z)*f4[2];
v[3] = vb1x*f1[1] + vb2x*f3[1] + (vb3x+vb2x)*f4[1];
v[4] = vb1x*f1[2] + vb2x*f3[2] + (vb3x+vb2x)*f4[2];
v[5] = vb1y*f1[2] + vb2y*f3[2] + (vb3y+vb2y)*f4[2];
if (vflag_global) {
if (newton_bond) {
virial[0] += v[0];
virial[1] += v[1];
virial[2] += v[2];
virial[3] += v[3];
virial[4] += v[4];
virial[5] += v[5];
} else {
if (i1 < nlocal) {
virial[0] += 0.25*v[0];
virial[1] += 0.25*v[1];
virial[2] += 0.25*v[2];
virial[3] += 0.25*v[3];
virial[4] += 0.25*v[4];
virial[5] += 0.25*v[5];
}
if (i2 < nlocal) {
virial[0] += 0.25*v[0];
virial[1] += 0.25*v[1];
virial[2] += 0.25*v[2];
virial[3] += 0.25*v[3];
virial[4] += 0.25*v[4];
virial[5] += 0.25*v[5];
}
if (i3 < nlocal) {
virial[0] += 0.25*v[0];
virial[1] += 0.25*v[1];
virial[2] += 0.25*v[2];
virial[3] += 0.25*v[3];
virial[4] += 0.25*v[4];
virial[5] += 0.25*v[5];
}
if (i4 < nlocal) {
virial[0] += 0.25*v[0];
virial[1] += 0.25*v[1];
virial[2] += 0.25*v[2];
virial[3] += 0.25*v[3];
virial[4] += 0.25*v[4];
virial[5] += 0.25*v[5];
}
}
}
if (vflag_atom) {
if (newton_bond || i1 < nlocal) {
vatom[i1][0] += 0.25*v[0];
vatom[i1][1] += 0.25*v[1];
vatom[i1][2] += 0.25*v[2];
vatom[i1][3] += 0.25*v[3];
vatom[i1][4] += 0.25*v[4];
vatom[i1][5] += 0.25*v[5];
}
if (newton_bond || i2 < nlocal) {
vatom[i2][0] += 0.25*v[0];
vatom[i2][1] += 0.25*v[1];
vatom[i2][2] += 0.25*v[2];
vatom[i2][3] += 0.25*v[3];
vatom[i2][4] += 0.25*v[4];
vatom[i2][5] += 0.25*v[5];
}
if (newton_bond || i3 < nlocal) {
vatom[i3][0] += 0.25*v[0];
vatom[i3][1] += 0.25*v[1];
vatom[i3][2] += 0.25*v[2];
vatom[i3][3] += 0.25*v[3];
vatom[i3][4] += 0.25*v[4];
vatom[i3][5] += 0.25*v[5];
}
if (newton_bond || i4 < nlocal) {
vatom[i4][0] += 0.25*v[0];
vatom[i4][1] += 0.25*v[1];
vatom[i4][2] += 0.25*v[2];
vatom[i4][3] += 0.25*v[3];
vatom[i4][4] += 0.25*v[4];
vatom[i4][5] += 0.25*v[5];
}
}
}
}
/* ---------------------------------------------------------------------- */
double Improper::memory_usage()
{
double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
return bytes;
}

View File

@ -49,18 +49,17 @@ ImproperCvff::~ImproperCvff()
void ImproperCvff::compute(int eflag, int vflag) void ImproperCvff::compute(int eflag, int vflag)
{ {
int m,n,i1,i2,i3,i4,type,factor; int i1,i2,i3,i4,m,n,type;
double rfactor; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double vb1x,vb1y,vb1z,vb2x,vb2y; double eimproper,f1[3],f2[3],f3[3],f4[3];
double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z,sb1; double sb1,sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2; double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
double c2mag,sc1,sc2,s1,s12,c,p,pd,rc2,a,a11,a22; double c2mag,sc1,sc2,s1,s2,s12,c,p,pd,rc2,a,a11,a22;
double a33,a12,a13,a23,sx1,sx2,sx12,sy1,sy2,sy12; double a33,a12,a13,a23,sx2,sy2,sz2;
double sz1,sz2,sz12,s2;
energy = 0.0; eimproper = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -70,23 +69,12 @@ void ImproperCvff::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nimproperlist; n++) { for (n = 0; n < nimproperlist; n++) {
i1 = improperlist[n][0]; i1 = improperlist[n][0];
i2 = improperlist[n][1]; i2 = improperlist[n][1];
i3 = improperlist[n][2]; i3 = improperlist[n][2];
i4 = improperlist[n][3]; i4 = improperlist[n][3];
type = improperlist[n][4]; type = improperlist[n][4];
if (newton_bond) factor = 4;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
if (i4 < nlocal) factor++;
}
rfactor = 0.25 * factor;
// 1st bond // 1st bond
vb1x = x[i1][0] - x[i2][0]; vb1x = x[i1][0] - x[i2][0];
@ -218,64 +206,67 @@ void ImproperCvff::compute(int eflag, int vflag)
pd = -pd; pd = -pd;
} }
if (eflag) energy += rfactor * k[type] * p; if (eflag) eimproper = k[type]*p;
a = 2.0 * k[type] * pd; a = 2.0 * k[type] * pd;
c = c * a; c = c * a;
s12 = s12 * a; s12 = s12 * a;
a11 = (-c*sb1*s1); a11 = c*sb1*s1;
a22 = sb2*(2.0*c0*s12 - c*(s1+s2)); a22 = -sb2*(2.0*c0*s12 - c*(s1+s2));
a33 = (-c*sb3*s2); a33 = c*sb3*s2;
a12 = r12c1*(c1mag*c*s1 + c2mag*s12); a12 = -r12c1*(c1mag*c*s1 + c2mag*s12);
a13 = rb1*rb3*s12; a13 = -rb1*rb3*s12;
a23 = r12c2*(-c2mag*c*s2 - c1mag*s12); a23 = r12c2*(c2mag*c*s2 + c1mag*s12);
sx1 = a11*vb1x + a12*vb2x + a13*vb3x;
sx2 = a12*vb1x + a22*vb2x + a23*vb3x; sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sx12 = a13*vb1x + a23*vb2x + a33*vb3x;
sy1 = a11*vb1y + a12*vb2y + a13*vb3y;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y; sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sy12 = a13*vb1y + a23*vb2y + a33*vb3y;
sz1 = a11*vb1z + a12*vb2z + a13*vb3z;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z; sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
sz12 = a13*vb1z + a23*vb2z + a33*vb3z;
f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// apply force to each of 4 atoms // apply force to each of 4 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= sx1; f[i1][0] += f1[0];
f[i1][1] -= sy1; f[i1][1] += f1[1];
f[i1][2] -= sz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += sx2 + sx1; f[i2][0] += f2[0];
f[i2][1] += sy2 + sy1; f[i2][1] += f2[1];
f[i2][2] += sz2 + sz1; f[i2][2] += f2[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] += sx12 - sx2; f[i3][0] += f3[0];
f[i3][1] += sy12 - sy2; f[i3][1] += f3[1];
f[i3][2] += sz12 - sz2; f[i3][2] += f3[2];
} }
if (newton_bond || i4 < nlocal) { if (newton_bond || i4 < nlocal) {
f[i4][0] -= sx12; f[i4][0] += f4[0];
f[i4][1] -= sy12; f[i4][1] += f4[1];
f[i4][2] -= sz12; f[i4][2] += f4[2];
} }
// virial contribution if (evflag)
ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,f1,f3,f4,
if (vflag) { vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
virial[0] -= rfactor * (vb1x*sx1 + vb2x*sx2 + vb3x*sx12);
virial[1] -= rfactor * (vb1y*sy1 + vb2y*sy2 + vb3y*sy12);
virial[2] -= rfactor * (vb1z*sz1 + vb2z*sz2 + vb3z*sz12);
virial[3] -= rfactor * (vb1x*sy1 + vb2x*sy2 + vb3x*sy12);
virial[4] -= rfactor * (vb1x*sz1 + vb2x*sz2 + vb3x*sz12);
virial[5] -= rfactor * (vb1y*sz1 + vb2y*sz2 + vb3y*sz12);
}
} }
} }

View File

@ -48,15 +48,16 @@ ImproperHarmonic::~ImproperHarmonic()
void ImproperHarmonic::compute(int eflag, int vflag) void ImproperHarmonic::compute(int eflag, int vflag)
{ {
int n,i1,i2,i3,i4,type,factor; int i1,i2,i3,i4,n,type;
double rfactor; double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z;
double v1x,v1y,v1z,v2x,v2y,v2z,v3x; double eimproper,f1[3],f2[3],f3[3],f4[3];
double v3y,v3z,ss1,ss2,ss3,r1,r2,r3,c0,c1,c2,s1,s2; double ss1,ss2,ss3,r1,r2,r3,c0,c1,c2,s1,s2;
double s12,c,s,domega,a,a11,a22,a33,a12,a13,a23,sx1; double s12,c,s,domega,a,a11,a22,a33,a12,a13,a23;
double sx2,sx12,sy1,sy2,sy12,sz1,sz2,sz12; double sx2,sy2,sz2;
energy = 0.0; eimproper = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
@ -66,43 +67,32 @@ void ImproperHarmonic::compute(int eflag, int vflag)
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
for (n = 0; n < nimproperlist; n++) { for (n = 0; n < nimproperlist; n++) {
i1 = improperlist[n][0]; i1 = improperlist[n][0];
i2 = improperlist[n][1]; i2 = improperlist[n][1];
i3 = improperlist[n][2]; i3 = improperlist[n][2];
i4 = improperlist[n][3]; i4 = improperlist[n][3];
type = improperlist[n][4]; type = improperlist[n][4];
if (newton_bond) factor = 4;
else {
factor = 0;
if (i1 < nlocal) factor++;
if (i2 < nlocal) factor++;
if (i3 < nlocal) factor++;
if (i4 < nlocal) factor++;
}
rfactor = 0.25 * factor;
// geometry of 4-body // geometry of 4-body
v1x = x[i2][0] - x[i1][0]; vb1x = x[i1][0] - x[i2][0];
v1y = x[i2][1] - x[i1][1]; vb1y = x[i1][1] - x[i2][1];
v1z = x[i2][2] - x[i1][2]; vb1z = x[i1][2] - x[i2][2];
domain->minimum_image(v1x,v1y,v1z); domain->minimum_image(vb1x,vb1y,vb1z);
v2x = x[i3][0] - x[i2][0]; vb2x = x[i3][0] - x[i2][0];
v2y = x[i3][1] - x[i2][1]; vb2y = x[i3][1] - x[i2][1];
v2z = x[i3][2] - x[i2][2]; vb2z = x[i3][2] - x[i2][2];
domain->minimum_image(v2x,v2y,v2z); domain->minimum_image(vb2x,vb2y,vb2z);
v3x = x[i4][0] - x[i3][0]; vb3x = x[i4][0] - x[i3][0];
v3y = x[i4][1] - x[i3][1]; vb3y = x[i4][1] - x[i3][1];
v3z = x[i4][2] - x[i3][2]; vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(v3x,v3y,v3z); domain->minimum_image(vb3x,vb3y,vb3z);
ss1 = 1.0 / (v1x*v1x + v1y*v1y + v1z*v1z); ss1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
ss2 = 1.0 / (v2x*v2x + v2y*v2y + v2z*v2z); ss2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
ss3 = 1.0 / (v3x*v3x + v3y*v3y + v3z*v3z); ss3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
r1 = sqrt(ss1); r1 = sqrt(ss1);
r2 = sqrt(ss2); r2 = sqrt(ss2);
@ -110,9 +100,9 @@ void ImproperHarmonic::compute(int eflag, int vflag)
// sin and cos of angle // sin and cos of angle
c0 = -(v1x * v3x + v1y * v3y + v1z * v3z) * r1 * r3; c0 = (vb1x * vb3x + vb1y * vb3y + vb1z * vb3z) * r1 * r3;
c1 = -(v1x * v2x + v1y * v2y + v1z * v2z) * r1 * r2; c1 = (vb1x * vb2x + vb1y * vb2y + vb1z * vb2z) * r1 * r2;
c2 = -(v3x * v2x + v3y * v2y + v3z * v2z) * r3 * r2; c2 = -(vb3x * vb2x + vb3y * vb2y + vb3z * vb2z) * r3 * r2;
s1 = 1.0 - c1*c1; s1 = 1.0 - c1*c1;
if (s1 < SMALL) s1 = SMALL; if (s1 < SMALL) s1 = SMALL;
@ -156,65 +146,67 @@ void ImproperHarmonic::compute(int eflag, int vflag)
domega = acos(c) - chi[type]; domega = acos(c) - chi[type];
a = k[type] * domega; a = k[type] * domega;
if (eflag) energy += rfactor * a * domega; if (eflag) eimproper = a*domega;
a = -a * 2.0/s; a = -a * 2.0/s;
c = c * a; c = c * a;
s12 = s12 * a; s12 = s12 * a;
a11 = (-c * ss1 * s1); a11 = c*ss1*s1;
a22 = ss2 * (2.0 * c0 * s12 - c * (s1 + s2)); a22 = -ss2 * (2.0*c0*s12 - c*(s1+s2));
a33 = (-c * ss3 * s2); a33 = c*ss3*s2;
a12 = r1 * r2 * (c1 * c * s1 + c2 * s12); a12 = -r1*r2*(c1*c*s1 + c2*s12);
a13 = r1 * r3 * s12; a13 = -r1*r3*s12;
a23 = r2 * r3 * (-c2 * c * s2 - c1 * s12); a23 = r2*r3*(c2*c*s2 + c1*s12);
sx1 = a12*v2x + a13*v3x - a11*v1x; sx2 = a22*vb2x + a23*vb3x + a12*vb1x;
sx2 = a22*v2x + a23*v3x - a12*v1x; sy2 = a22*vb2y + a23*vb3y + a12*vb1y;
sx12 = a23*v2x + a33*v3x - a13*v1x; sz2 = a22*vb2z + a23*vb3z + a12*vb1z;
sy1 = a12*v2y + a13*v3y - a11*v1y;
sy2 = a22*v2y + a23*v3y - a12*v1y; f1[0] = a12*vb2x + a13*vb3x + a11*vb1x;
sy12 = a23*v2y + a33*v3y - a13*v1y; f1[1] = a12*vb2y + a13*vb3y + a11*vb1y;
sz1 = a12*v2z + a13*v3z - a11*v1z; f1[2] = a12*vb2z + a13*vb3z + a11*vb1z;
sz2 = a22*v2z + a23*v3z - a12*v1z;
sz12 = a23*v2z + a33*v3z - a13*v1z; f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a23*vb2x + a33*vb3x + a13*vb1x;
f4[1] = a23*vb2y + a33*vb3y + a13*vb1y;
f4[2] = a23*vb2z + a33*vb3z + a13*vb1z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// apply force to each of 4 atoms // apply force to each of 4 atoms
if (newton_bond || i1 < nlocal) { if (newton_bond || i1 < nlocal) {
f[i1][0] -= sx1; f[i1][0] += f1[0];
f[i1][1] -= sy1; f[i1][1] += f1[1];
f[i1][2] -= sz1; f[i1][2] += f1[2];
} }
if (newton_bond || i2 < nlocal) { if (newton_bond || i2 < nlocal) {
f[i2][0] += sx2 + sx1; f[i2][0] += f2[0];
f[i2][1] += sy2 + sy1; f[i2][1] += f2[1];
f[i2][2] += sz2 + sz1; f[i2][2] += f2[2];
} }
if (newton_bond || i3 < nlocal) { if (newton_bond || i3 < nlocal) {
f[i3][0] += sx12 - sx2; f[i3][0] += f3[0];
f[i3][1] += sy12 - sy2; f[i3][1] += f3[1];
f[i3][2] += sz12 - sz2; f[i3][2] += f3[2];
} }
if (newton_bond || i4 < nlocal) { if (newton_bond || i4 < nlocal) {
f[i4][0] -= sx12; f[i4][0] += f4[0];
f[i4][1] -= sy12; f[i4][1] += f4[1];
f[i4][2] -= sz12; f[i4][2] += f4[2];
} }
// virial contribution if (evflag)
ev_tally(i1,i2,i3,i4,nlocal,newton_bond,eimproper,f1,f3,f4,
if (vflag) { vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z);
virial[0] += rfactor * (v1x*sx1 - v2x*sx2 - v3x*sx12);
virial[1] += rfactor * (v1y*sy1 - v2y*sy2 - v3y*sy12);
virial[2] += rfactor * (v1z*sz1 - v2z*sz2 - v3z*sz12);
virial[3] += rfactor * (v1x*sy1 - v2x*sy2 - v3x*sy12);
virial[4] += rfactor * (v1x*sz1 - v2x*sz2 - v3x*sz12);
virial[5] += rfactor * (v1y*sz1 - v2y*sz2 - v3y*sz12);
}
} }
} }

View File

@ -59,7 +59,7 @@ ImproperHybrid::~ImproperHybrid()
void ImproperHybrid::compute(int eflag, int vflag) void ImproperHybrid::compute(int eflag, int vflag)
{ {
int i,m,n; int i,j,m,n;
// save ptrs to original improperlist // save ptrs to original improperlist
@ -98,19 +98,36 @@ void ImproperHybrid::compute(int eflag, int vflag)
} }
// call each sub-style's compute function // call each sub-style's compute function
// must set neighbor->improperlist to sub-style improperlist before call // set neighbor->improperlist to sub-style improperlist before call
// accumulate sub-style energy,virial in hybrid's energy,virial // accumulate sub-style global/peratom energy/virial in hybrid
energy = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0; else evflag = 0;
for (m = 0; m < nstyles; m++) { for (m = 0; m < nstyles; m++) {
if (styles[m] == NULL) continue; if (styles[m] == NULL) continue;
neighbor->nimproperlist = nimproperlist[m]; neighbor->nimproperlist = nimproperlist[m];
neighbor->improperlist = improperlist[m]; neighbor->improperlist = improperlist[m];
styles[m]->compute(eflag,vflag); styles[m]->compute(eflag,vflag);
if (eflag) energy += styles[m]->energy;
if (vflag) for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n]; if (eflag_global) energy += styles[m]->energy;
if (vflag_global)
for (n = 0; n < 6; n++) virial[n] += styles[m]->virial[n];
if (eflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
double *eatom_substyle = styles[m]->eatom;
for (i = 0; i < n; i++) eatom[i] += eatom_substyle[i];
}
if (vflag_atom) {
n = atom->nlocal;
if (force->newton_bond) n += atom->nghost;
double **vatom_substyle = styles[m]->vatom;
for (i = 0; i < n; i++)
for (j = 0; j < 6; j++)
vatom[i][j] += vatom_substyle[i][j];
}
} }
// restore ptrs to original improperlist // restore ptrs to original improperlist
@ -237,7 +254,8 @@ void ImproperHybrid::read_restart(FILE *fp)
double ImproperHybrid::memory_usage() double ImproperHybrid::memory_usage()
{ {
double bytes = 0.0; double bytes = maxeatom * sizeof(double);
bytes += maxvatom*6 * sizeof(double);
for (int m = 0; m < nstyles; m++) bytes += maximproper[m]*5 * sizeof(int); for (int m = 0; m < nstyles; m++) bytes += maximproper[m]*5 * sizeof(int);
for (int m = 0; m < nstyles; m++) for (int m = 0; m < nstyles; m++)
if (styles[m]) bytes += styles[m]->memory_usage(); if (styles[m]) bytes += styles[m]->memory_usage();

View File

@ -68,20 +68,21 @@ PairLJCharmmCoulCharmm::~PairLJCharmmCoulCharmm()
void PairLJCharmmCoulCharmm::compute(int eflag, int vflag) void PairLJCharmmCoulCharmm::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double factor,phicoul,philj,switch1,switch2; double philj,switch1,switch2;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = eng_coul = 0.0; evdwl = ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -147,54 +148,46 @@ void PairLJCharmmCoulCharmm::compute(int eflag, int vflag)
} }
} else forcelj = 0.0; } else forcelj = 0.0;
fforce = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv; fpair = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq) { if (rsq < cut_coulsq) {
phicoul = qqrd2e * qtmp*q[j]*sqrt(r2inv); ecoul = qqrd2e * qtmp*q[j]*sqrt(r2inv);
if (rsq > cut_coul_innersq) { if (rsq > cut_coul_innersq) {
switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) *
(cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) / (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) /
denom_coul; denom_coul;
phicoul *= switch1; ecoul *= switch1;
} }
eng_coul += factor*factor_coul*phicoul; ecoul *= factor_coul;
} } else ecoul = 0.0;
if (rsq < cut_ljsq) { if (rsq < cut_ljsq) {
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
if (rsq > cut_lj_innersq) { if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj;
philj *= switch1; evdwl *= switch1;
} }
eng_vdwl += factor*factor_lj*philj; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,ecoul,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -33,20 +33,21 @@ PairLJCharmmCoulCharmmImplicit::PairLJCharmmCoulCharmmImplicit(LAMMPS *lmp) :
void PairLJCharmmCoulCharmmImplicit::compute(int eflag, int vflag) void PairLJCharmmCoulCharmmImplicit::compute(int eflag, int vflag)
{ {
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double qtmp,xtmp,ytmp,ztmp,delx,dely,delz; double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul,fpair;
double rsq,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double rsq,r2inv,r6inv,forcecoul,forcelj,factor_coul,factor_lj;
double factor,phicoul,philj,switch1,switch2; double philj,switch1,switch2;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
eng_vdwl = eng_coul = 0.0; evdwl = ecoul = 0.0;
if (vflag) for (i = 0; i < 6; i++) virial[i] = 0.0; if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x; double **x = atom->x;
double **f = atom->f; double **f = atom->f;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -112,54 +113,46 @@ void PairLJCharmmCoulCharmmImplicit::compute(int eflag, int vflag)
} }
} else forcelj = 0.0; } else forcelj = 0.0;
fforce = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv; fpair = (factor_coul*forcecoul + factor_lj*forcelj) * r2inv;
f[i][0] += delx*fforce; f[i][0] += delx*fpair;
f[i][1] += dely*fforce; f[i][1] += dely*fpair;
f[i][2] += delz*fforce; f[i][2] += delz*fpair;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
f[j][0] -= delx*fforce; f[j][0] -= delx*fpair;
f[j][1] -= dely*fforce; f[j][1] -= dely*fpair;
f[j][2] -= delz*fforce; f[j][2] -= delz*fpair;
} }
if (eflag) { if (eflag) {
if (newton_pair || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq) { if (rsq < cut_coulsq) {
phicoul = qqrd2e * qtmp*q[j]*r2inv; ecoul = qqrd2e * qtmp*q[j]*r2inv;
if (rsq > cut_coul_innersq) { if (rsq > cut_coul_innersq) {
switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) * switch1 = (cut_coulsq-rsq) * (cut_coulsq-rsq) *
(cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) / (cut_coulsq + 2.0*rsq - 3.0*cut_coul_innersq) /
denom_coul; denom_coul;
phicoul *= switch1; ecoul *= switch1;
} }
eng_coul += factor*factor_coul*phicoul; ecoul *= factor_coul;
} } else ecoul = 0.0;
if (rsq < cut_ljsq) { if (rsq < cut_ljsq) {
philj = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]); evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
if (rsq > cut_lj_innersq) { if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj; (cut_ljsq + 2.0*rsq - 3.0*cut_lj_innersq) / denom_lj;
philj *= switch1; evdwl *= switch1;
} }
eng_vdwl += factor*factor_lj*philj; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (vflag == 1) { if (evflag) ev_tally(i,j,nlocal,newton_pair,
if (newton_pair == 0 && j >= nlocal) fforce *= 0.5; evdwl,ecoul,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */

View File

@ -31,34 +31,19 @@ PairEAMOpt::PairEAMOpt(LAMMPS *lmp) : PairEAM(lmp) {}
void PairEAMOpt::compute(int eflag, int vflag) void PairEAMOpt::compute(int eflag, int vflag)
{ {
if (eflag) { if (eflag || vflag) ev_setup(eflag,vflag);
if (force->newton_pair) { else evflag = vflag_fdotr = 0;
switch (vflag) {
case 0: return eval<1,0,1>(); if (evflag) {
case 1: return eval<1,1,1>(); if (eflag) {
case 2: return eval<1,2,1>(); if (force->newton_pair) return eval<1,1,1>();
} else return eval<1,1,0>();
} else { } else {
switch (vflag) { if (force->newton_pair) return eval<1,0,1>();
case 0: return eval<1,0,0>(); else return eval<1,0,0>();
case 1: return eval<1,1,0>();
case 2: return eval<1,2,0>();
}
} }
} else { } else {
if (force->newton_pair) { if (force->newton_pair) return eval<0,0,1>();
switch (vflag) { else return eval<0,0,0>();
case 0: return eval<0,0,1>();
case 1: return eval<0,1,1>();
case 2: return eval<0,2,1>();
}
} else {
switch (vflag) {
case 0: return eval<0,0,0>();
case 1: return eval<0,1,0>();
case 2: return eval<0,2,0>();
}
}
} }
} }

View File

@ -45,10 +45,10 @@ class PairEAMOpt : virtual public PairEAM {
void compute(int, int); void compute(int, int);
private: private:
template < int EFLAG, int VFLAG, int NEWTON_PAIR > void eval(); template < int EVFLAG, int EFLAG, int NEWTON_PAIR > void eval();
}; };
template < int EFLAG, int VFLAG, int NEWTON_PAIR > template < int EVFLAG, int EFLAG, int NEWTON_PAIR >
void PairEAMOpt::eval() void PairEAMOpt::eval()
{ {
typedef struct { double x,y,z; } vec3_t; typedef struct { double x,y,z; } vec3_t;
@ -71,8 +71,9 @@ void PairEAMOpt::eval()
} fast_gamma_t; } fast_gamma_t;
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double evdwl = 0.0;
double* __restrict__ coeff; double* __restrict__ coeff;
// grow energy array if necessary // grow energy array if necessary
if (atom->nmax > nmax) { if (atom->nmax > nmax) {
@ -83,9 +84,6 @@ void PairEAMOpt::eval()
fp = (double *) memory->smalloc(nmax*sizeof(double),"pair:fp"); fp = (double *) memory->smalloc(nmax*sizeof(double),"pair:fp");
} }
eng_vdwl = 0.0;
if (VFLAG) for (i = 0; i < 6; i++) virial[i] = 0.0;
double** __restrict__ x = atom->x; double** __restrict__ x = atom->x;
double** __restrict__ f = atom->f; double** __restrict__ f = atom->f;
int* __restrict__ type = atom->type; int* __restrict__ type = atom->type;
@ -179,7 +177,6 @@ void PairEAMOpt::eval()
double rsq = delx*delx + dely*dely + delz*delz; double rsq = delx*delx + dely*dely + delz*delz;
if (rsq < tmp_cutforcesq) { if (rsq < tmp_cutforcesq) {
jtype = type[j] - 1; jtype = type[j] - 1;
double p = sqrt(rsq)*tmp_rdr; double p = sqrt(rsq)*tmp_rdr;
@ -197,9 +194,7 @@ void PairEAMOpt::eval()
if (NEWTON_PAIR || j < nlocal) { if (NEWTON_PAIR || j < nlocal) {
rho[j] += a.rhor3i+a.rhor2i+a.rhor1i+a.rhor0i; rho[j] += a.rhor3i+a.rhor2i+a.rhor1i+a.rhor0i;
} }
} }
} }
} }
rho[i] = tmprho; rho[i] = tmprho;
@ -220,7 +215,11 @@ void PairEAMOpt::eval()
++m; ++m;
coeff = frho_spline[type2frho[type[i]]][m]; coeff = frho_spline[type2frho[type[i]]][m];
fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2]; fp[i] = (coeff[0]*p + coeff[1])*p + coeff[2];
if (EFLAG) eng_vdwl += ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6]; if (EFLAG) {
double phi = ((coeff[3]*p + coeff[4])*p + coeff[5])*p + coeff[6];
if (eflag_global) eng_vdwl += phi;
if (eflag_atom) eatom[i] += phi;
}
} }
// communicate derivative of embedding function // communicate derivative of embedding function
@ -291,33 +290,24 @@ void PairEAMOpt::eval()
double phi = z2*recip; double phi = z2*recip;
double phip = z2p*recip - phi*recip; double phip = z2p*recip - phi*recip;
double psip = fp[i]*rhojp + fp[j]*rhoip + phip; double psip = fp[i]*rhojp + fp[j]*rhoip + phip;
double fforce = -psip*recip; double fpair = -psip*recip;
tmpfx += delx*fforce; tmpfx += delx*fpair;
tmpfy += dely*fforce; tmpfy += dely*fpair;
tmpfz += delz*fforce; tmpfz += delz*fpair;
if (NEWTON_PAIR || j < nlocal) { if (NEWTON_PAIR || j < nlocal) {
ff[j].x -= delx*fforce; ff[j].x -= delx*fpair;
ff[j].y -= dely*fforce; ff[j].y -= dely*fpair;
ff[j].z -= delz*fforce; ff[j].z -= delz*fpair;
} }
if (EFLAG) { if (EFLAG) evdwl = phi;
if (NEWTON_PAIR || j < nlocal) eng_vdwl += phi;
else eng_vdwl += 0.5*phi;
}
if (VFLAG == 1) { if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR,
if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5; evdwl,0.0,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
ff[i].x += tmpfx; ff[i].x += tmpfx;
ff[i].y += tmpfy; ff[i].y += tmpfy;
ff[i].z += tmpfz; ff[i].z += tmpfz;
@ -326,7 +316,7 @@ void PairEAMOpt::eval()
free(fast_alpha); fast_alpha = 0; free(fast_alpha); fast_alpha = 0;
free(fast_gamma); fast_gamma = 0; free(fast_gamma); fast_gamma = 0;
if (VFLAG == 2) virial_compute(); if (vflag_fdotr) virial_compute();
} }
} }

View File

@ -31,34 +31,19 @@ PairLJCharmmCoulLongOpt::PairLJCharmmCoulLongOpt(LAMMPS *lmp) :
void PairLJCharmmCoulLongOpt::compute(int eflag, int vflag) void PairLJCharmmCoulLongOpt::compute(int eflag, int vflag)
{ {
if (eflag) { if (eflag || vflag) ev_setup(eflag,vflag);
if (force->newton_pair) { else evflag = vflag_fdotr = 0;
switch (vflag) {
case 0: return eval<1,0,1>(); if (evflag) {
case 1: return eval<1,1,1>(); if (eflag) {
case 2: return eval<1,2,1>(); if (force->newton_pair) return eval<1,1,1>();
} else return eval<1,1,0>();
} else { } else {
switch (vflag) { if (force->newton_pair) return eval<1,0,1>();
case 0: return eval<1,0,0>(); else return eval<1,0,0>();
case 1: return eval<1,1,0>();
case 2: return eval<1,2,0>();
}
} }
} else { } else {
if (force->newton_pair) { if (force->newton_pair) return eval<0,0,1>();
switch (vflag) { else return eval<0,0,0>();
case 0: return eval<0,0,1>();
case 1: return eval<0,1,1>();
case 2: return eval<0,2,1>();
}
} else {
switch (vflag) {
case 0: return eval<0,0,0>();
case 1: return eval<0,1,0>();
case 2: return eval<0,2,0>();
}
}
} }
} }

View File

@ -47,10 +47,10 @@ class PairLJCharmmCoulLongOpt : public PairLJCharmmCoulLong {
void compute(int, int); void compute(int, int);
private: private:
template < int EFLAG, int VFLAG, int NEWTON_PAIR > void eval(); template < int EVFLAG, int EFLAG, int NEWTON_PAIR > void eval();
}; };
template < int EFLAG, int VFLAG, int NEWTON_PAIR > template < int EVFLAG, int EFLAG, int NEWTON_PAIR >
void PairLJCharmmCoulLongOpt::eval() void PairLJCharmmCoulLongOpt::eval()
{ {
typedef struct { double x,y,z; } vec3_t; typedef struct { double x,y,z; } vec3_t;
@ -64,13 +64,13 @@ void PairLJCharmmCoulLongOpt::eval()
double fraction,table; double fraction,table;
double r,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj; double r,r2inv,r6inv,forcecoul,forcelj,fforce,factor_coul,factor_lj;
double grij,expm2,prefactor,t,erfc; double grij,expm2,prefactor,t,erfc;
double factor,phicoul,philj,switch1,switch2; double philj,switch1,switch2;
float rsq; float rsq;
int *int_rsq = (int *) &rsq; int *int_rsq = (int *) &rsq;
eng_vdwl = eng_coul = 0.0; double evdwl = 0.0;
if (VFLAG) for (i = 0; i < 6; i++) virial[i] = 0.0; double ecoul = 0.0;
double** __restrict__ x = atom->x; double** __restrict__ x = atom->x;
double** __restrict__ f = atom->f; double** __restrict__ f = atom->f;
@ -174,51 +174,42 @@ void PairLJCharmmCoulLongOpt::eval()
} }
} }
fforce = (forcecoul + forcelj) * r2inv; double fpair = (forcecoul + forcelj) * r2inv;
tmpfx += delx*fforce; tmpfx += delx*fpair;
tmpfy += dely*fforce; tmpfy += dely*fpair;
tmpfz += delz*fforce; tmpfz += delz*fpair;
if (NEWTON_PAIR || j < nlocal) { if (NEWTON_PAIR || j < nlocal) {
ff[j].x -= delx*fforce; ff[j].x -= delx*fpair;
ff[j].y -= dely*fforce; ff[j].y -= dely*fpair;
ff[j].z -= delz*fforce; ff[j].z -= delz*fpair;
} }
if (EFLAG) { if (EFLAG) {
if (NEWTON_PAIR || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq) { if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) if (!ncoultablebits || rsq <= tabinnersq)
phicoul = prefactor*erfc; ecoul = prefactor*erfc;
else { else {
table = etable[itable] + fraction*detable[itable]; table = etable[itable] + fraction*detable[itable];
phicoul = tmp_coef3 * table; ecoul = tmp_coef3 * table;
} }
eng_coul += factor*phicoul; } else ecoul = 0.0;
}
if (rsq < cut_ljsq) { if (rsq < cut_ljsq) {
fast_alpha_t& a = tabsixi[jtype]; fast_alpha_t& a = tabsixi[jtype];
philj = r6inv*(a.lj3*r6inv-a.lj4); evdwl = r6inv*(a.lj3*r6inv-a.lj4);
if (rsq > cut_lj_innersq) { if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(tmp_coef2 + 2.0*rsq) * tmp_coef1; (tmp_coef2 + 2.0*rsq) * tmp_coef1;
philj *= switch1; evdwl *= switch1;
} }
eng_vdwl += factor*philj; } else evdwl = 0.0;
}
}
if (VFLAG == 1) {
if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5;
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
} }
if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR,
evdwl,ecoul,fpair,delx,dely,delz);
} }
} else { } else {
factor_coul = special_coul[j/nall]; factor_coul = special_coul[j/nall];
factor_lj = special_lj[j/nall]; factor_lj = special_lj[j/nall];
@ -276,61 +267,54 @@ void PairLJCharmmCoulLongOpt::eval()
} }
} }
fforce = (forcecoul + factor_lj*forcelj) * r2inv; double fpair = (forcecoul + factor_lj*forcelj) * r2inv;
tmpfx += delx*fforce; tmpfx += delx*fpair;
tmpfy += dely*fforce; tmpfy += dely*fpair;
tmpfz += delz*fforce; tmpfz += delz*fpair;
if (NEWTON_PAIR || j < nlocal) { if (NEWTON_PAIR || j < nlocal) {
ff[j].x -= delx*fforce; ff[j].x -= delx*fpair;
ff[j].y -= dely*fforce; ff[j].y -= dely*fpair;
ff[j].z -= delz*fforce; ff[j].z -= delz*fpair;
} }
if (EFLAG) { if (EFLAG) {
if (NEWTON_PAIR || j < nlocal) factor = 1.0;
else factor = 0.5;
if (rsq < cut_coulsq) { if (rsq < cut_coulsq) {
if (!ncoultablebits || rsq <= tabinnersq) if (!ncoultablebits || rsq <= tabinnersq)
phicoul = prefactor*erfc; ecoul = prefactor*erfc;
else { else {
table = etable[itable] + fraction*detable[itable]; table = etable[itable] + fraction*detable[itable];
phicoul = tmp_coef3 * table; ecoul = tmp_coef3 * table;
} }
if (factor_coul < 1.0) if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
phicoul -= (1.0-factor_coul)*prefactor; } else ecoul = 0.0;
eng_coul += factor*phicoul;
}
if (rsq < cut_ljsq) { if (rsq < cut_ljsq) {
fast_alpha_t& a = tabsixi[jtype]; fast_alpha_t& a = tabsixi[jtype];
philj = r6inv*(a.lj3*r6inv-a.lj4); evdwl = r6inv*(a.lj3*r6inv-a.lj4);
if (rsq > cut_lj_innersq) { if (rsq > cut_lj_innersq) {
switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) * switch1 = (cut_ljsq-rsq) * (cut_ljsq-rsq) *
(tmp_coef2 + 2.0*rsq) * tmp_coef1; (tmp_coef2 + 2.0*rsq) * tmp_coef1;
philj *= switch1; evdwl *= switch1;
} }
eng_vdwl += factor*factor_lj*philj; evdwl *= factor_lj;
} } else evdwl = 0.0;
} }
if (VFLAG == 1) { if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR,
if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5; evdwl,ecoul,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
ff[i].x += tmpfx; ff[i].x += tmpfx;
ff[i].y += tmpfy; ff[i].y += tmpfy;
ff[i].z += tmpfz; ff[i].z += tmpfz;
} }
if (VFLAG == 2) virial_compute();
free(fast_alpha); fast_alpha = 0; free(fast_alpha); fast_alpha = 0;
if (vflag_fdotr) virial_compute();
} }
} }

View File

@ -30,34 +30,19 @@ PairLJCutOpt::PairLJCutOpt(LAMMPS *lmp) : PairLJCut(lmp) {}
void PairLJCutOpt::compute(int eflag, int vflag) void PairLJCutOpt::compute(int eflag, int vflag)
{ {
if (eflag) { if (eflag || vflag) ev_setup(eflag,vflag);
if (force->newton_pair) { else evflag = vflag_fdotr = 0;
switch (vflag) {
case 0: return eval<1,0,1>(); if (evflag) {
case 1: return eval<1,1,1>(); if (eflag) {
case 2: return eval<1,2,1>(); if (force->newton_pair) return eval<1,1,1>();
} else return eval<1,1,0>();
} else { } else {
switch (vflag) { if (force->newton_pair) return eval<1,0,1>();
case 0: return eval<1,0,0>(); else return eval<1,0,0>();
case 1: return eval<1,1,0>();
case 2: return eval<1,2,0>();
}
} }
} else { } else {
if (force->newton_pair) { if (force->newton_pair) return eval<0,0,1>();
switch (vflag) { else return eval<0,0,0>();
case 0: return eval<0,0,1>();
case 1: return eval<0,1,1>();
case 2: return eval<0,2,1>();
}
} else {
switch (vflag) {
case 0: return eval<0,0,0>();
case 1: return eval<0,1,0>();
case 2: return eval<0,2,0>();
}
}
} }
} }

View File

@ -35,10 +35,10 @@ class PairLJCutOpt : public PairLJCut {
void compute(int, int); void compute(int, int);
private: private:
template < int EFLAG, int VFLAG, int NEWTON_PAIR > void eval(); template < int EVFLAG, int EFLAG, int NEWTON_PAIR > void eval();
}; };
template < int EFLAG, int VFLAG, int NEWTON_PAIR > template < int EVFLAG, int EFLAG, int NEWTON_PAIR >
void PairLJCutOpt::eval() void PairLJCutOpt::eval()
{ {
typedef struct { double x,y,z; } vec3_t; typedef struct { double x,y,z; } vec3_t;
@ -49,9 +49,7 @@ void PairLJCutOpt::eval()
} fast_alpha_t; } fast_alpha_t;
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double evdwl = 0.0;
eng_vdwl = 0.0;
if (VFLAG) for (i = 0; i < 6; i++) virial[i] = 0.0;
double** __restrict__ x = atom->x; double** __restrict__ x = atom->x;
double** __restrict__ f = atom->f; double** __restrict__ f = atom->f;
@ -119,37 +117,28 @@ void PairLJCutOpt::eval()
double r2inv = 1.0/rsq; double r2inv = 1.0/rsq;
double r6inv = r2inv*r2inv*r2inv; double r6inv = r2inv*r2inv*r2inv;
double forcelj = r6inv * (a.lj1*r6inv - a.lj2); double forcelj = r6inv * (a.lj1*r6inv - a.lj2);
if (EFLAG) { double fpair = forcelj*r2inv;
double philj = r6inv*(a.lj3*r6inv-a.lj4) - a.offset;
if (NEWTON_PAIR || j < nlocal) eng_vdwl += philj;
else eng_vdwl += 0.5*philj;
}
double fforce = forcelj*r2inv;
tmpfx += delx*fforce; tmpfx += delx*fpair;
tmpfy += dely*fforce; tmpfy += dely*fpair;
tmpfz += delz*fforce; tmpfz += delz*fpair;
if (NEWTON_PAIR || j < nlocal) { if (NEWTON_PAIR || j < nlocal) {
ff[j].x -= delx*fforce; ff[j].x -= delx*fpair;
ff[j].y -= dely*fforce; ff[j].y -= dely*fpair;
ff[j].z -= delz*fforce; ff[j].z -= delz*fpair;
}
if (VFLAG == 1) {
if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5;
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
} }
if (EFLAG) evdwl = r6inv*(a.lj3*r6inv-a.lj4) - a.offset;
if (EVFLAG)
ev_tally(i,j,nlocal,NEWTON_PAIR,
evdwl,0.0,fpair,delx,dely,delz);
} }
} else { } else {
factor_lj = special_lj[j/nall]; factor_lj = special_lj[j/nall];
j = j % nall; j = j % nall;
double delx = xtmp - xx[j].x; double delx = xtmp - xx[j].x;
double dely = ytmp - xx[j].y; double dely = ytmp - xx[j].y;
double delz = ztmp - xx[j].z; double delz = ztmp - xx[j].z;
@ -160,49 +149,40 @@ void PairLJCutOpt::eval()
fast_alpha_t& a = tabsixi[jtype]; fast_alpha_t& a = tabsixi[jtype];
if (rsq < a.cutsq) { if (rsq < a.cutsq) {
double r2inv = 1.0/rsq; double r2inv = 1.0/rsq;
double r6inv = r2inv*r2inv*r2inv; double r6inv = r2inv*r2inv*r2inv;
fast_alpha_t& a = tabsixi[jtype]; fast_alpha_t& a = tabsixi[jtype];
double forcelj = r6inv * (a.lj1*r6inv - a.lj2); double forcelj = r6inv * (a.lj1*r6inv - a.lj2);
if (EFLAG) { double fpair = factor_lj*forcelj*r2inv;
double philj = r6inv*(a.lj3*r6inv-a.lj4) - a.offset;
if (NEWTON_PAIR || j < nlocal) eng_vdwl += factor_lj*philj;
else eng_vdwl += 0.5*factor_lj*philj;
}
double fforce = factor_lj*forcelj*r2inv; tmpfx += delx*fpair;
tmpfy += dely*fpair;
tmpfx += delx*fforce; tmpfz += delz*fpair;
tmpfy += dely*fforce;
tmpfz += delz*fforce;
if (NEWTON_PAIR || j < nlocal) { if (NEWTON_PAIR || j < nlocal) {
ff[j].x -= delx*fforce; ff[j].x -= delx*fpair;
ff[j].y -= dely*fforce; ff[j].y -= dely*fpair;
ff[j].z -= delz*fforce; ff[j].z -= delz*fpair;
}
if (EFLAG) {
evdwl = r6inv*(a.lj3*r6inv-a.lj4) - a.offset;
evdwl *= factor_lj;
} }
if (VFLAG == 1) { if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR,
if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5; evdwl,0.0,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
ff[i].x += tmpfx; ff[i].x += tmpfx;
ff[i].y += tmpfy; ff[i].y += tmpfy;
ff[i].z += tmpfz; ff[i].z += tmpfz;
} }
if (VFLAG == 2) virial_compute();
free(fast_alpha); fast_alpha = 0; free(fast_alpha); fast_alpha = 0;
if (vflag_fdotr) virial_compute();
} }
} }

View File

@ -30,34 +30,19 @@ PairMorseOpt::PairMorseOpt(LAMMPS *lmp) : PairMorse(lmp) {}
void PairMorseOpt::compute(int eflag, int vflag) void PairMorseOpt::compute(int eflag, int vflag)
{ {
if (eflag) { if (eflag || vflag) ev_setup(eflag,vflag);
if (force->newton_pair) { else evflag = vflag_fdotr = 0;
switch (vflag) {
case 0: return eval<1,0,1>(); if (evflag) {
case 1: return eval<1,1,1>(); if (eflag) {
case 2: return eval<1,2,1>(); if (force->newton_pair) return eval<1,1,1>();
} else return eval<1,1,0>();
} else { } else {
switch (vflag) { if (force->newton_pair) return eval<1,0,1>();
case 0: return eval<1,0,0>(); else return eval<1,0,0>();
case 1: return eval<1,1,0>();
case 2: return eval<1,2,0>();
}
} }
} else { } else {
if (force->newton_pair) { if (force->newton_pair) return eval<0,0,1>();
switch (vflag) { else return eval<0,0,0>();
case 0: return eval<0,0,1>();
case 1: return eval<0,1,1>();
case 2: return eval<0,2,1>();
}
} else {
switch (vflag) {
case 0: return eval<0,0,0>();
case 1: return eval<0,1,0>();
case 2: return eval<0,2,0>();
}
}
} }
} }

View File

@ -36,10 +36,10 @@ class PairMorseOpt : public PairMorse {
void compute(int, int); void compute(int, int);
private: private:
template < int EFLAG, int VFLAG, int NEWTON_PAIR > void eval(); template < int EVFLAG, int EFLAG, int NEWTON_PAIR > void eval();
}; };
template < int EFLAG, int VFLAG, int NEWTON_PAIR > template < int EVFLAG, int EFLAG, int NEWTON_PAIR >
void PairMorseOpt::eval() void PairMorseOpt::eval()
{ {
typedef struct { double x,y,z; } vec3_t; typedef struct { double x,y,z; } vec3_t;
@ -50,9 +50,7 @@ void PairMorseOpt::eval()
} fast_alpha_t; } fast_alpha_t;
int i,j,ii,jj,inum,jnum,itype,jtype; int i,j,ii,jj,inum,jnum,itype,jtype;
double evdwl = 0.0;
eng_vdwl = 0.0;
if (VFLAG) for (i = 0; i < 6; i++) virial[i] = 0.0;
double** __restrict__ x = atom->x; double** __restrict__ x = atom->x;
double** __restrict__ f = atom->f; double** __restrict__ f = atom->f;
@ -119,35 +117,23 @@ void PairMorseOpt::eval()
double r = sqrt(rsq); double r = sqrt(rsq);
double dr = r - a.r0; double dr = r - a.r0;
double dexp = exp(-a.alpha * dr); double dexp = exp(-a.alpha * dr);
double fforce = a.morse1 * (dexp*dexp - dexp) / r; double fpair = a.morse1 * (dexp*dexp - dexp) / r;
if (EFLAG) {
double phi = a.d0 * (dexp*dexp - 2.0*dexp) - a.offset; tmpfx += delx*fpair;
if (NEWTON_PAIR || j < nlocal) { tmpfy += dely*fpair;
eng_vdwl += phi; tmpfz += delz*fpair;
} else {
eng_vdwl += 0.5*phi;
}
}
tmpfx += delx*fforce;
tmpfy += dely*fforce;
tmpfz += delz*fforce;
if (NEWTON_PAIR || j < nlocal) { if (NEWTON_PAIR || j < nlocal) {
ff[j].x -= delx*fforce; ff[j].x -= delx*fpair;
ff[j].y -= dely*fforce; ff[j].y -= dely*fpair;
ff[j].z -= delz*fforce; ff[j].z -= delz*fpair;
}
if (VFLAG == 1) {
if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5;
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
} }
if (EFLAG) evdwl = a.d0 * (dexp*dexp - 2.0*dexp) - a.offset;
if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR,
evdwl,0.0,fpair,delx,dely,delz);
} }
} else { } else {
factor_lj = special_lj[j/nall]; factor_lj = special_lj[j/nall];
j = j % nall; j = j % nall;
@ -164,46 +150,36 @@ void PairMorseOpt::eval()
double r = sqrt(rsq); double r = sqrt(rsq);
double dr = r - a.r0; double dr = r - a.r0;
double dexp = exp(-a.alpha * dr); double dexp = exp(-a.alpha * dr);
double fforce = factor_lj * a.morse1 * (dexp*dexp - dexp) / r; double fpair = factor_lj * a.morse1 * (dexp*dexp - dexp) / r;
if (EFLAG) {
double phi = a.d0 * (dexp*dexp - 2.0*dexp) - a.offset; tmpfx += delx*fpair;
if (NEWTON_PAIR || j < nlocal) { tmpfy += dely*fpair;
eng_vdwl += factor_lj*phi; tmpfz += delz*fpair;
} else {
eng_vdwl += 0.5*factor_lj*phi;
}
}
tmpfx += delx*fforce;
tmpfy += dely*fforce;
tmpfz += delz*fforce;
if (NEWTON_PAIR || j < nlocal) { if (NEWTON_PAIR || j < nlocal) {
ff[j].x -= delx*fforce; ff[j].x -= delx*fpair;
ff[j].y -= dely*fforce; ff[j].y -= dely*fpair;
ff[j].z -= delz*fforce; ff[j].z -= delz*fpair;
}
if (EFLAG) {
evdwl = a.d0 * (dexp*dexp - 2.0*dexp) - a.offset;
evdwl *= factor_lj;
} }
if (VFLAG == 1) { if (EVFLAG) ev_tally(i,j,nlocal,NEWTON_PAIR,
if (NEWTON_PAIR == 0 && j >= nlocal) fforce *= 0.5; evdwl,0.0,fpair,delx,dely,delz);
virial[0] += delx*delx*fforce;
virial[1] += dely*dely*fforce;
virial[2] += delz*delz*fforce;
virial[3] += delx*dely*fforce;
virial[4] += delx*delz*fforce;
virial[5] += dely*delz*fforce;
}
} }
} }
} }
ff[i].x += tmpfx; ff[i].x += tmpfx;
ff[i].y += tmpfy; ff[i].y += tmpfy;
ff[i].z += tmpfz; ff[i].z += tmpfz;
} }
if (VFLAG == 2) virial_compute();
free(fast_alpha); fast_alpha = 0; free(fast_alpha); fast_alpha = 0;
if (vflag_fdotr) virial_compute();
} }
} }

View File

@ -96,9 +96,8 @@ void ComputeAcklandAtom::init_list(int id, NeighList *ptr)
void ComputeAcklandAtom::compute_peratom() void ComputeAcklandAtom::compute_peratom()
{ {
int i,j,ii,jj,k,n,inum,jnum; int i,j,ii,jj,k,n,inum,jnum;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq,value; double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *ilist,*jlist,*numneigh,**firstneigh; int *ilist,*jlist,*numneigh,**firstneigh;
double pairs[66];
int chi[8]; int chi[8];
// grow structure array if necessary // grow structure array if necessary
@ -125,7 +124,6 @@ void ComputeAcklandAtom::compute_peratom()
double **x = atom->x; double **x = atom->x;
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = atom->nlocal + atom->nghost;
double cutsq = force->pair->cutforce * force->pair->cutforce; double cutsq = force->pair->cutforce * force->pair->cutforce;
@ -270,7 +268,7 @@ void ComputeAcklandAtom::compute_peratom()
else else
structure[i] = HCP; structure[i] = HCP;
} // end loop over all particles } else structure[i] = 0.0;
} }
} }

View File

@ -442,12 +442,17 @@ void PairBuckCoul::read_restart_settings(FILE *fp)
void PairBuckCoul::compute(int eflag, int vflag) void PairBuckCoul::compute(int eflag, int vflag)
{ {
double evdwl,ecoul,fpair;
evdwl = ecoul = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x, *x0 = x[0]; double **x = atom->x, *x0 = x[0];
double **f = atom->f, *f0 = f[0], *fi = f0; double **f = atom->f, *f0 = f[0], *fi = f0;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -457,13 +462,10 @@ void PairBuckCoul::compute(int eflag, int vflag)
int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni; int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni;
double qi, qri, *cutsqi, *cut_bucksqi, double qi, qri, *cutsqi, *cut_bucksqi,
*buck1i, *buck2i, *buckai, *buckci, *rhoinvi, *offseti; *buck1i, *buck2i, *buckai, *buckci, *rhoinvi, *offseti;
double r, rsq, r2inv, force_coul, force_buck, fforce, factor; double r, rsq, r2inv, force_coul, force_buck;
double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2; double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2;
vector xi, d; vector xi, d;
eng_vdwl = eng_coul = 0.0; // reset energy&virial
if (vflag) memset(virial, 0, sizeof(shape));
ineighn = (ineigh = list->ilist)+list->inum; ineighn = (ineigh = list->ilist)+list->inum;
for (; ineigh<ineighn; ++ineigh) { // loop over my atoms for (; ineigh<ineighn; ++ineigh) { // loop over my atoms
@ -489,8 +491,6 @@ void PairBuckCoul::compute(int eflag, int vflag)
r2inv = 1.0/rsq; r2inv = 1.0/rsq;
r = sqrt(rsq); r = sqrt(rsq);
factor = newton_pair || j<nlocal ? 1.0 : 0.5;
if (order1 && (rsq < cut_coulsq)) { // coulombic if (order1 && (rsq < cut_coulsq)) { // coulombic
if (!ncoultablebits || rsq <= tabinnersq) { // series real space if (!ncoultablebits || rsq <= tabinnersq) { // series real space
register double x = g_ewald*r; register double x = g_ewald*r;
@ -498,13 +498,13 @@ void PairBuckCoul::compute(int eflag, int vflag)
if (ni < 0) { if (ni < 0) {
s *= g_ewald*exp(-x*x); s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s; force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s;
if (eflag) eng_coul += factor*t; if (eflag) ecoul = t;
} }
else { // special case else { // special case
register double f = s*(1.0-special_coul[ni])/r; register double f = s*(1.0-special_coul[ni])/r;
s *= g_ewald*exp(-x*x); s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-f; force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-f;
if (eflag) eng_coul += factor*(t-f); if (eflag) ecoul = t-f;
} }
} // table real space } // table real space
else { else {
@ -513,16 +513,16 @@ void PairBuckCoul::compute(int eflag, int vflag)
register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j]; register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j];
if (ni < 0) { if (ni < 0) {
force_coul = qiqj*(ftable[k]+f*dftable[k]); force_coul = qiqj*(ftable[k]+f*dftable[k]);
if (eflag) eng_coul += factor*qiqj*(etable[k]+f*detable[k]); if (eflag) ecoul = qiqj*(etable[k]+f*detable[k]);
} }
else { // special case else { // special case
t = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]); t = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]);
force_coul = qiqj*(ftable[k]+f*dftable[k]-t); force_coul = qiqj*(ftable[k]+f*dftable[k]-t);
if (eflag) eng_coul += factor*qiqj*(etable[k]+f*detable[k]-t); if (eflag) ecoul = qiqj*(etable[k]+f*detable[k]-t);
} }
} }
} }
else force_coul = 0.0; else force_coul = ecoul = 0.0;
if (rsq < cut_bucksqi[typej]) { // buckingham if (rsq < cut_bucksqi[typej]) { // buckingham
register double rn = r2inv*r2inv*r2inv, register double rn = r2inv*r2inv*r2inv,
@ -533,77 +533,63 @@ void PairBuckCoul::compute(int eflag, int vflag)
if (ni < 0) { if (ni < 0) {
force_buck = force_buck =
r*expr*buck1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq; r*expr*buck1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq;
if (eflag) eng_vdwl += if (eflag) evdwl = expr*buckai[typej]-g6*((a2+1.0)*a2+0.5)*x2;
factor*(expr*buckai[typej]-g6*((a2+1.0)*a2+0.5)*x2);
} }
else { // special case else { // special case
register double f = special_lj[ni], t = rn*(1.0-f); register double f = special_lj[ni], t = rn*(1.0-f);
force_buck = f*r*expr*buck1i[typej]- force_buck = f*r*expr*buck1i[typej]-
g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*buck2i[typej]; g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*buck2i[typej];
if (eflag) eng_vdwl += factor*( if (eflag) evdwl = f*expr*buckai[typej] -
f*expr*buckai[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*buckci[typej]); g6*((a2+1.0)*a2+0.5)*x2+t*buckci[typej];
} }
} }
else { // cut else { // cut
if (ni < 0) { if (ni < 0) {
force_buck = r*expr*buck1i[typej]-rn*buck2i[typej]; force_buck = r*expr*buck1i[typej]-rn*buck2i[typej];
if (eflag) eng_vdwl += factor*( if (eflag) evdwl = expr*buckai[typej] -
expr*buckai[typej]-rn*buckci[typej]-offseti[typej]); rn*buckci[typej]-offseti[typej];
} }
else { // special case else { // special case
register double f = special_lj[ni]; register double f = special_lj[ni];
force_buck = f*(r*expr*buck1i[typej]-rn*buck2i[typej]); force_buck = f*(r*expr*buck1i[typej]-rn*buck2i[typej]);
if (eflag) eng_vdwl += f*factor*( if (eflag)
expr*buckai[typej]-rn*buckci[typej]-offseti[typej]); evdwl = f*(expr*buckai[typej]-rn*buckci[typej]-offseti[typej]);
} }
} }
} }
else force_buck = 0.0; else force_buck = evdwl = 0.0;
fforce = (force_coul+force_buck)*r2inv; // force and virial fpair = (force_coul+force_buck)*r2inv;
if (vflag==1) {
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
register double f = d[0]*fforce, *fj = f0+(j+(j<<1));
fi[0] += f; fj[0] -= f;
virial[0] += f*d[0]; virial[3] += f*d[1];
fi[1] += f = d[1]*fforce; fj[1] -= f;
virial[1] += f*d[1]; virial[5] += f*d[2];
fi[2] += f = d[2]*fforce; fj[2] -= f;
virial[2] += f*d[2]; virial[4] += f*d[0];
}
else {
register double f = d[0]*fforce;
fi[0] += f; virial[0] += (f *= 0.5)*d[0]; virial[3] += f*d[1];
fi[1] += f = d[1]*fforce; virial[1] += 0.5*f*d[1];
fi[2] += f = d[2]*fforce; virial[2] += (f *= 0.5)*d[2];
virial[4] += f*d[0]; virial[5] += f*d[1];
}
}
else if (newton_pair || j < nlocal) {
register double *fj = f0+(j+(j<<1)), f; register double *fj = f0+(j+(j<<1)), f;
fi[0] += f = d[0]*fforce; fj[0] -= f; fi[0] += f = d[0]*fpair; fj[0] -= f;
fi[1] += f = d[1]*fforce; fj[1] -= f; fi[1] += f = d[1]*fpair; fj[1] -= f;
fi[2] += f = d[2]*fforce; fj[2] -= f; fi[2] += f = d[2]*fpair; fj[2] -= f;
} }
else { else {
fi[0] += d[0]*fforce; fi[0] += d[0]*fpair;
fi[1] += d[1]*fforce; fi[1] += d[1]*fpair;
fi[2] += d[2]*fforce; fi[2] += d[2]*fpair;
} }
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,ecoul,fpair,d[0],d[1],d[2]);
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void PairBuckCoul::compute_inner() void PairBuckCoul::compute_inner()
{ {
double r, rsq, r2inv, force_coul, force_buck, fforce; double r, rsq, r2inv, force_coul, force_buck, fpair;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *x0 = atom->x[0], *f0 = atom->f[0], *fi = f0, *q = atom->q; double *x0 = atom->x[0], *f0 = atom->f[0], *fi = f0, *q = atom->q;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
@ -619,7 +605,7 @@ void PairBuckCoul::compute_inner()
int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni; int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni;
int i, j, order1 = (ewald_order|(ewald_off^-1))&(1<<1); int i, j, order1 = (ewald_order|(ewald_off^-1))&(1<<1);
double qri, *cut_bucksqi, *buck1i, *buck2i, *rhoinvi, *offseti; double qri, *cut_bucksqi, *buck1i, *buck2i, *rhoinvi;
vector xi, d; vector xi, d;
ineighn = (ineigh = listinner->ilist)+listinner->inum; ineighn = (ineigh = listinner->ilist)+listinner->inum;
@ -628,7 +614,6 @@ void PairBuckCoul::compute_inner()
i = *ineigh; fi = f0+3*i; i = *ineigh; fi = f0+3*i;
qri = qqrd2e*q[i]; qri = qqrd2e*q[i];
memcpy(xi, x0+(i+(i<<1)), sizeof(vector)); memcpy(xi, x0+(i+(i<<1)), sizeof(vector));
offseti = offset[typei = type[i]];
cut_bucksqi = cut_bucksq[typei]; cut_bucksqi = cut_bucksq[typei];
buck1i = buck1[typei]; buck2i = buck2[typei]; rhoinvi = rhoinv[typei]; buck1i = buck1[typei]; buck2i = buck2[typei]; rhoinvi = rhoinv[typei];
jneighn = (jneigh = listinner->firstneigh[i])+listinner->numneigh[i]; jneighn = (jneigh = listinner->firstneigh[i])+listinner->numneigh[i];
@ -659,23 +644,23 @@ void PairBuckCoul::compute_inner()
} }
else force_buck = 0.0; else force_buck = 0.0;
fforce = (force_coul + force_buck) * r2inv; fpair = (force_coul + force_buck) * r2inv;
if (rsq > cut_out_on_sq) { // switching if (rsq > cut_out_on_sq) { // switching
register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
fforce *= 1.0 + rsw*rsw*(2.0*rsw-3.0); fpair *= 1.0 + rsw*rsw*(2.0*rsw-3.0);
} }
if (newton_pair || j < nlocal) { // force update if (newton_pair || j < nlocal) { // force update
register double *fj = f0+(j+(j<<1)), f; register double *fj = f0+(j+(j<<1)), f;
fi[0] += f = d[0]*fforce; fj[0] -= f; fi[0] += f = d[0]*fpair; fj[0] -= f;
fi[1] += f = d[1]*fforce; fj[1] -= f; fi[1] += f = d[1]*fpair; fj[1] -= f;
fi[2] += f = d[2]*fforce; fj[2] -= f; fi[2] += f = d[2]*fpair; fj[2] -= f;
} }
else { else {
fi[0] += d[0]*fforce; fi[0] += d[0]*fpair;
fi[1] += d[1]*fforce; fi[1] += d[1]*fpair;
fi[2] += d[2]*fforce; fi[2] += d[2]*fpair;
} }
} }
} }
@ -685,11 +670,11 @@ void PairBuckCoul::compute_inner()
void PairBuckCoul::compute_middle() void PairBuckCoul::compute_middle()
{ {
double r, rsq, r2inv, force_coul, force_buck, fforce; double r, rsq, r2inv, force_coul, force_buck, fpair;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *x0 = atom->x[0], *f0 = atom->f[0], *fi = f0, *q = atom->q; double *x0 = atom->x[0], *f0 = atom->f[0], *fi = f0, *q = atom->q;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
@ -710,7 +695,7 @@ void PairBuckCoul::compute_middle()
int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni; int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni;
int i, j, order1 = (ewald_order|(ewald_off^-1))&(1<<1); int i, j, order1 = (ewald_order|(ewald_off^-1))&(1<<1);
double qri, *cut_bucksqi, *buck1i, *buck2i, *rhoinvi, *offseti; double qri, *cut_bucksqi, *buck1i, *buck2i, *rhoinvi;
vector xi, d; vector xi, d;
ineighn = (ineigh = listmiddle->ilist)+listmiddle->inum; ineighn = (ineigh = listmiddle->ilist)+listmiddle->inum;
@ -719,7 +704,6 @@ void PairBuckCoul::compute_middle()
i = *ineigh; fi = f0+3*i; i = *ineigh; fi = f0+3*i;
qri = qqrd2e*q[i]; qri = qqrd2e*q[i];
memcpy(xi, x0+(i+(i<<1)), sizeof(vector)); memcpy(xi, x0+(i+(i<<1)), sizeof(vector));
offseti = offset[typei = type[i]];
cut_bucksqi = cut_bucksq[typei]; cut_bucksqi = cut_bucksq[typei];
buck1i = buck1[typei]; buck2i = buck2[typei]; rhoinvi = rhoinv[typei]; buck1i = buck1[typei]; buck2i = buck2[typei]; rhoinvi = rhoinv[typei];
jneighn = (jneigh = listmiddle->firstneigh[i])+listmiddle->numneigh[i]; jneighn = (jneigh = listmiddle->firstneigh[i])+listmiddle->numneigh[i];
@ -751,27 +735,27 @@ void PairBuckCoul::compute_middle()
} }
else force_buck = 0.0; else force_buck = 0.0;
fforce = (force_coul + force_buck) * r2inv; fpair = (force_coul + force_buck) * r2inv;
if (rsq < cut_in_on_sq) { // switching if (rsq < cut_in_on_sq) { // switching
register double rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff; register double rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff;
fforce *= rsw*rsw*(3.0 - 2.0*rsw); fpair *= rsw*rsw*(3.0 - 2.0*rsw);
} }
if (rsq > cut_out_on_sq) { if (rsq > cut_out_on_sq) {
register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
fforce *= 1.0 + rsw*rsw*(2.0*rsw-3.0); fpair *= 1.0 + rsw*rsw*(2.0*rsw-3.0);
} }
if (newton_pair || j < nlocal) { // force update if (newton_pair || j < nlocal) { // force update
register double *fj = f0+(j+(j<<1)), f; register double *fj = f0+(j+(j<<1)), f;
fi[0] += f = d[0]*fforce; fj[0] -= f; fi[0] += f = d[0]*fpair; fj[0] -= f;
fi[1] += f = d[1]*fforce; fj[1] -= f; fi[1] += f = d[1]*fpair; fj[1] -= f;
fi[2] += f = d[2]*fforce; fj[2] -= f; fi[2] += f = d[2]*fpair; fj[2] -= f;
} }
else { else {
fi[0] += d[0]*fforce; fi[0] += d[0]*fpair;
fi[1] += d[1]*fforce; fi[1] += d[1]*fpair;
fi[2] += d[2]*fforce; fi[2] += d[2]*fpair;
} }
} }
} }
@ -781,12 +765,17 @@ void PairBuckCoul::compute_middle()
void PairBuckCoul::compute_outer(int eflag, int vflag) void PairBuckCoul::compute_outer(int eflag, int vflag)
{ {
double evdwl,ecoul,fpair;
evdwl = ecoul = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x, *x0 = x[0]; double **x = atom->x, *x0 = x[0];
double **f = atom->f, *f0 = f[0], *fi = f0; double **f = atom->f, *f0 = f[0], *fi = f0;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -796,7 +785,7 @@ void PairBuckCoul::compute_outer(int eflag, int vflag)
int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni, respa_flag; int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni, respa_flag;
double qi, qri, *cutsqi, *cut_bucksqi, double qi, qri, *cutsqi, *cut_bucksqi,
*buck1i, *buck2i, *buckai, *buckci, *rhoinvi, *offseti; *buck1i, *buck2i, *buckai, *buckci, *rhoinvi, *offseti;
double r, rsq, r2inv, force_coul, force_buck, fforce, factor; double r, rsq, r2inv, force_coul, force_buck;
double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2; double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2;
double respa_buck, respa_coul, frespa; double respa_buck, respa_coul, frespa;
vector xi, d; vector xi, d;
@ -808,9 +797,6 @@ void PairBuckCoul::compute_outer(int eflag, int vflag)
double cut_in_off_sq = cut_in_off*cut_in_off; double cut_in_off_sq = cut_in_off*cut_in_off;
double cut_in_on_sq = cut_in_on*cut_in_on; double cut_in_on_sq = cut_in_on*cut_in_on;
eng_vdwl = eng_coul = 0.0; // reset energy&virial
if (vflag) memset(virial, 0, sizeof(shape));
ineighn = (ineigh = listouter->ilist)+listouter->inum; ineighn = (ineigh = listouter->ilist)+listouter->inum;
for (; ineigh<ineighn; ++ineigh) { // loop over my atoms for (; ineigh<ineighn; ++ineigh) { // loop over my atoms
@ -836,8 +822,6 @@ void PairBuckCoul::compute_outer(int eflag, int vflag)
r2inv = 1.0/rsq; r2inv = 1.0/rsq;
r = sqrt(rsq); r = sqrt(rsq);
factor = newton_pair || j<nlocal ? 1.0 : 0.5;
if ((respa_flag = (rsq>cut_in_off_sq)&&(rsq<cut_in_on_sq))) { if ((respa_flag = (rsq>cut_in_off_sq)&&(rsq<cut_in_on_sq))) {
register double rsw = (r-cut_in_off)/cut_in_diff; register double rsw = (r-cut_in_off)/cut_in_diff;
frespa = rsw*rsw*(3.0-2.0*rsw); frespa = rsw*rsw*(3.0-2.0*rsw);
@ -852,12 +836,12 @@ void PairBuckCoul::compute_outer(int eflag, int vflag)
if (ni < 0) { if (ni < 0) {
s *= g_ewald*exp(-x*x); s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s; force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s;
if (eflag) eng_coul += factor*t; if (eflag) ecoul = t;
} }
else { // correct for special else { // correct for special
r = s*(1.0-special_coul[ni])/r; s *= g_ewald*exp(-x*x); r = s*(1.0-special_coul[ni])/r; s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-r; force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-r;
if (eflag) eng_coul += factor*(t-r); if (eflag) ecoul = t-r;
} }
} // table real space } // table real space
else { else {
@ -869,16 +853,16 @@ void PairBuckCoul::compute_outer(int eflag, int vflag)
register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j]; register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j];
if (ni < 0) { if (ni < 0) {
force_coul = qiqj*(ftable[k]+f*dftable[k]); force_coul = qiqj*(ftable[k]+f*dftable[k]);
if (eflag) eng_coul += factor*qiqj*(etable[k]+f*detable[k]); if (eflag) ecoul = qiqj*(etable[k]+f*detable[k]);
} }
else { // correct for special else { // correct for special
t = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]); t = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]);
force_coul = qiqj*(ftable[k]+f*dftable[k]-t); force_coul = qiqj*(ftable[k]+f*dftable[k]-t);
if (eflag) eng_coul += factor*qiqj*(etable[k]+f*detable[k]-t); if (eflag) ecoul = qiqj*(etable[k]+f*detable[k]-t);
} }
} }
} }
else force_coul = respa_coul = 0.0; else force_coul = respa_coul = ecoul = 0.0;
if (rsq < cut_bucksqi[typej]) { // buckingham if (rsq < cut_bucksqi[typej]) { // buckingham
register double rn = r2inv*r2inv*r2inv, register double rn = r2inv*r2inv*r2inv,
@ -892,60 +876,51 @@ void PairBuckCoul::compute_outer(int eflag, int vflag)
if (ni < 0) { if (ni < 0) {
force_buck = force_buck =
r*expr*buck1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq; r*expr*buck1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq;
if (eflag) eng_vdwl += if (eflag) evdwl = expr*buckai[typej]-g6*((a2+1.0)*a2+0.5)*x2;
factor*(expr*buckai[typej]-g6*((a2+1.0)*a2+0.5)*x2);
} }
else { // correct for special else { // correct for special
register double f = special_lj[ni], t = rn*(1.0-f); register double f = special_lj[ni], t = rn*(1.0-f);
force_buck = f*r*expr*buck1i[typej]- force_buck = f*r*expr*buck1i[typej]-
g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*buck2i[typej]; g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*buck2i[typej];
if (eflag) eng_vdwl += factor*( if (eflag) evdwl = f*expr*buckai[typej] -
f*expr*buckai[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*buckci[typej]); g6*((a2+1.0)*a2+0.5)*x2+t*buckci[typej];
} }
} }
else { // cut form else { // cut form
if (ni < 0) { if (ni < 0) {
force_buck = r*expr*buck1i[typej]-rn*buck2i[typej]; force_buck = r*expr*buck1i[typej]-rn*buck2i[typej];
if (eflag) eng_vdwl += factor*( if (eflag)
expr*buckai[typej]-rn*buckci[typej]-offseti[typej]); evdwl = expr*buckai[typej]-rn*buckci[typej]-offseti[typej];
} }
else { // correct for special else { // correct for special
register double f = special_lj[ni]; register double f = special_lj[ni];
force_buck = f*(r*expr*buck1i[typej]-rn*buck2i[typej]); force_buck = f*(r*expr*buck1i[typej]-rn*buck2i[typej]);
if (eflag) eng_vdwl += f*factor*( if (eflag)
expr*buckai[typej]-rn*buckci[typej]-offseti[typej]); evdwl = f*(expr*buckai[typej]-rn*buckci[typej]-offseti[typej]);
} }
} }
} }
else force_buck = respa_buck = 0.0; else force_buck = respa_buck = evdwl = 0.0;
fpair = (force_coul+force_buck)*r2inv;
frespa = fpair-(respa_coul+respa_buck)*r2inv;
fforce = (force_coul+force_buck)*r2inv; // force and virial
frespa = fforce-(respa_coul+respa_buck)*r2inv;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
register double *fj = f0+(j+(j<<1)), f; register double *fj = f0+(j+(j<<1)), f;
fi[0] += f = d[0]*frespa; fj[0] -= f; fi[0] += f = d[0]*frespa; fj[0] -= f;
fi[1] += f = d[1]*frespa; fj[1] -= f; fi[1] += f = d[1]*frespa; fj[1] -= f;
fi[2] += f = d[2]*frespa; fj[2] -= f; fi[2] += f = d[2]*frespa; fj[2] -= f;
if (vflag==1) {
virial[0] += (f = d[0]*fforce)*d[0]; virial[3] += f*d[1];
virial[1] += (f = d[1]*fforce)*d[1]; virial[5] += f*d[2];
virial[2] += (f = d[2]*fforce)*d[2]; virial[4] += f*d[0];
}
} }
else { else {
fi[0] += d[0]*frespa; fi[0] += d[0]*frespa;
fi[1] += d[1]*frespa; fi[1] += d[1]*frespa;
fi[2] += d[2]*frespa; fi[2] += d[2]*frespa;
if (vflag==1) {
register double f;
virial[0] += (f = 0.5*d[0]*fforce)*d[0]; virial[3] += f*d[1];
virial[1] += (f = 0.5*d[1]*fforce)*d[1]; virial[5] += f*d[2];
virial[2] += (f = 0.5*d[2]*fforce)*d[2]; virial[4] += f*d[0];
}
} }
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,ecoul,fpair,d[0],d[1],d[2]);
} }
} }
if (vflag == 2) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -446,12 +446,17 @@ void PairLJCoul::read_restart_settings(FILE *fp)
void PairLJCoul::compute(int eflag, int vflag) void PairLJCoul::compute(int eflag, int vflag)
{ {
double evdwl,ecoul,fpair;
evdwl = ecoul = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = vflag_fdotr = 0;
double **x = atom->x, *x0 = x[0]; double **x = atom->x, *x0 = x[0];
double **f = atom->f, *f0 = f[0], *fi = f0; double **f = atom->f, *f0 = f[0], *fi = f0;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -460,12 +465,10 @@ void PairLJCoul::compute(int eflag, int vflag)
int i, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6); int i, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6);
int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni; int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni;
double qi, qri, *cutsqi, *cut_ljsqi, *lj1i, *lj2i, *lj3i, *lj4i, *offseti; double qi, qri, *cutsqi, *cut_ljsqi, *lj1i, *lj2i, *lj3i, *lj4i, *offseti;
double rsq, r2inv, force_coul, force_lj, fforce, factor; double rsq, r2inv, force_coul, force_lj;
double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2; double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2;
vector xi, d; vector xi, d;
eng_vdwl = eng_coul = 0.0; // reset energy&virial
if (vflag) memset(virial, 0, sizeof(shape));
ineighn = (ineigh = list->ilist)+list->inum; ineighn = (ineigh = list->ilist)+list->inum;
for (; ineigh<ineighn; ++ineigh) { // loop over my atoms for (; ineigh<ineighn; ++ineigh) { // loop over my atoms
@ -489,8 +492,6 @@ void PairLJCoul::compute(int eflag, int vflag)
if ((rsq = vec_dot(d, d)) >= cutsqi[typej = type[j]]) continue; if ((rsq = vec_dot(d, d)) >= cutsqi[typej = type[j]]) continue;
r2inv = 1.0/rsq; r2inv = 1.0/rsq;
factor = newton_pair || j<nlocal ? 1.0 : 0.5;
if (order1 && (rsq < cut_coulsq)) { // coulombic if (order1 && (rsq < cut_coulsq)) { // coulombic
if (!ncoultablebits || rsq <= tabinnersq) { // series real space if (!ncoultablebits || rsq <= tabinnersq) { // series real space
register double r = sqrt(rsq), x = g_ewald*r; register double r = sqrt(rsq), x = g_ewald*r;
@ -498,12 +499,12 @@ void PairLJCoul::compute(int eflag, int vflag)
if (ni < 0) { if (ni < 0) {
s *= g_ewald*exp(-x*x); s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s; force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s;
if (eflag) eng_coul += factor*t; if (eflag) ecoul = t;
} }
else { // special case else { // special case
r = s*(1.0-special_coul[ni])/r; s *= g_ewald*exp(-x*x); r = s*(1.0-special_coul[ni])/r; s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-r; force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-r;
if (eflag) eng_coul += factor*(t-r); if (eflag) ecoul = t-r;
} }
} // table real space } // table real space
else { else {
@ -512,16 +513,16 @@ void PairLJCoul::compute(int eflag, int vflag)
register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j]; register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j];
if (ni < 0) { if (ni < 0) {
force_coul = qiqj*(ftable[k]+f*dftable[k]); force_coul = qiqj*(ftable[k]+f*dftable[k]);
if (eflag) eng_coul += factor*qiqj*(etable[k]+f*detable[k]); if (eflag) ecoul = qiqj*(etable[k]+f*detable[k]);
} }
else { // special case else { // special case
t = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]); t = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]);
force_coul = qiqj*(ftable[k]+f*dftable[k]-t); force_coul = qiqj*(ftable[k]+f*dftable[k]-t);
if (eflag) eng_coul += factor*qiqj*(etable[k]+f*detable[k]-t); if (eflag) ecoul = qiqj*(etable[k]+f*detable[k]-t);
} }
} }
} }
else force_coul = 0.0; else force_coul = ecoul = 0.0;
if (rsq < cut_ljsqi[typej]) { // lj if (rsq < cut_ljsqi[typej]) { // lj
if (order6) { // long-range lj if (order6) { // long-range lj
@ -531,78 +532,64 @@ void PairLJCoul::compute(int eflag, int vflag)
if (ni < 0) { if (ni < 0) {
force_lj = force_lj =
(rn*=rn)*lj1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq; (rn*=rn)*lj1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq;
if (eflag) eng_vdwl += if (eflag)
factor*(rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2); evdwl = rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2;
} }
else { // special case else { // special case
register double f = special_lj[ni], t = rn*(1.0-f); register double f = special_lj[ni], t = rn*(1.0-f);
force_lj = f*(rn *= rn)*lj1i[typej]- force_lj = f*(rn *= rn)*lj1i[typej]-
g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*lj2i[typej]; g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*lj2i[typej];
if (eflag) eng_vdwl += factor*( if (eflag)
f*rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[typej]); evdwl = f*rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[typej];
} }
} }
else { // cut lj else { // cut lj
register double rn = r2inv*r2inv*r2inv; register double rn = r2inv*r2inv*r2inv;
if (ni < 0) { if (ni < 0) {
force_lj = rn*(rn*lj1i[typej]-lj2i[typej]); force_lj = rn*(rn*lj1i[typej]-lj2i[typej]);
if (eflag) eng_vdwl += factor*( if (eflag) evdwl = rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej];
rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej]);
} }
else { // special case else { // special case
register double f = special_lj[ni]; register double f = special_lj[ni];
force_lj = f*rn*(rn*lj1i[typej]-lj2i[typej]); force_lj = f*rn*(rn*lj1i[typej]-lj2i[typej]);
if (eflag) eng_vdwl += f*factor*( if (eflag)
rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej]); evdwl = f * (rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej]);
} }
} }
} }
else force_lj = 0.0; else force_lj = evdwl = 0.0;
fforce = (force_coul+force_lj)*r2inv; // force and virial fpair = (force_coul+force_lj)*r2inv;
if (vflag==1) {
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
register double f = d[0]*fforce, *fj = f0+(j+(j<<1));
fi[0] += f; fj[0] -= f;
virial[0] += f*d[0]; virial[3] += f*d[1];
fi[1] += f = d[1]*fforce; fj[1] -= f;
virial[1] += f*d[1]; virial[5] += f*d[2];
fi[2] += f = d[2]*fforce; fj[2] -= f;
virial[2] += f*d[2]; virial[4] += f*d[0];
}
else {
register double f = d[0]*fforce;
fi[0] += f; virial[0] += (f *= 0.5)*d[0]; virial[3] += f*d[1];
fi[1] += f = d[1]*fforce; virial[1] += 0.5*f*d[1];
fi[2] += f = d[2]*fforce; virial[2] += (f *= 0.5)*d[2];
virial[4] += f*d[0]; virial[5] += f*d[1];
}
}
else if (newton_pair || j < nlocal) {
register double *fj = f0+(j+(j<<1)), f; register double *fj = f0+(j+(j<<1)), f;
fi[0] += f = d[0]*fforce; fj[0] -= f; fi[0] += f = d[0]*fpair; fj[0] -= f;
fi[1] += f = d[1]*fforce; fj[1] -= f; fi[1] += f = d[1]*fpair; fj[1] -= f;
fi[2] += f = d[2]*fforce; fj[2] -= f; fi[2] += f = d[2]*fpair; fj[2] -= f;
} }
else { else {
fi[0] += d[0]*fforce; fi[0] += d[0]*fpair;
fi[1] += d[1]*fforce; fi[1] += d[1]*fpair;
fi[2] += d[2]*fforce; fi[2] += d[2]*fpair;
} }
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,ecoul,fpair,d[0],d[1],d[2]);
} }
} }
if (vflag == 2) virial_compute();
if (vflag_fdotr) virial_compute();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void PairLJCoul::compute_inner() void PairLJCoul::compute_inner()
{ {
double rsq, r2inv, force_coul, force_lj, fforce; double rsq, r2inv, force_coul, force_lj, fpair;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *x0 = atom->x[0], *f0 = atom->f[0], *fi = f0, *q = atom->q; double *x0 = atom->x[0], *f0 = atom->f[0], *fi = f0, *q = atom->q;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
@ -618,7 +605,7 @@ void PairLJCoul::compute_inner()
int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni; int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni;
int i, j, order1 = (ewald_order|(ewald_off^-1))&(1<<1); int i, j, order1 = (ewald_order|(ewald_off^-1))&(1<<1);
double qri, *cut_ljsqi, *lj1i, *lj2i, *offseti; double qri, *cut_ljsqi, *lj1i, *lj2i;
vector xi, d; vector xi, d;
ineighn = (ineigh = list->ilist)+list->inum; ineighn = (ineigh = list->ilist)+list->inum;
@ -627,7 +614,6 @@ void PairLJCoul::compute_inner()
i = *ineigh; fi = f0+3*i; i = *ineigh; fi = f0+3*i;
qri = qqrd2e*q[i]; qri = qqrd2e*q[i];
memcpy(xi, x0+(i+(i<<1)), sizeof(vector)); memcpy(xi, x0+(i+(i<<1)), sizeof(vector));
offseti = offset[typei = type[i]];
cut_ljsqi = cut_ljsq[typei]; cut_ljsqi = cut_ljsq[typei];
lj1i = lj1[typei]; lj2i = lj2[typei]; lj1i = lj1[typei]; lj2i = lj2[typei];
jneighn = (jneigh = list->firstneigh[i])+list->numneigh[i]; jneighn = (jneigh = list->firstneigh[i])+list->numneigh[i];
@ -656,23 +642,23 @@ void PairLJCoul::compute_inner()
} }
else force_lj = 0.0; else force_lj = 0.0;
fforce = (force_coul + force_lj) * r2inv; fpair = (force_coul + force_lj) * r2inv;
if (rsq > cut_out_on_sq) { // switching if (rsq > cut_out_on_sq) { // switching
register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
fforce *= 1.0 + rsw*rsw*(2.0*rsw-3.0); fpair *= 1.0 + rsw*rsw*(2.0*rsw-3.0);
} }
if (newton_pair || j < nlocal) { // force update if (newton_pair || j < nlocal) { // force update
register double *fj = f0+(j+(j<<1)), f; register double *fj = f0+(j+(j<<1)), f;
fi[0] += f = d[0]*fforce; fj[0] -= f; fi[0] += f = d[0]*fpair; fj[0] -= f;
fi[1] += f = d[1]*fforce; fj[1] -= f; fi[1] += f = d[1]*fpair; fj[1] -= f;
fi[2] += f = d[2]*fforce; fj[2] -= f; fi[2] += f = d[2]*fpair; fj[2] -= f;
} }
else { else {
fi[0] += d[0]*fforce; fi[0] += d[0]*fpair;
fi[1] += d[1]*fforce; fi[1] += d[1]*fpair;
fi[2] += d[2]*fforce; fi[2] += d[2]*fpair;
} }
} }
} }
@ -682,11 +668,11 @@ void PairLJCoul::compute_inner()
void PairLJCoul::compute_middle() void PairLJCoul::compute_middle()
{ {
double rsq, r2inv, force_coul, force_lj, fforce; double rsq, r2inv, force_coul, force_lj, fpair;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *x0 = atom->x[0], *f0 = atom->f[0], *fi = f0, *q = atom->q; double *x0 = atom->x[0], *f0 = atom->f[0], *fi = f0, *q = atom->q;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
@ -707,7 +693,7 @@ void PairLJCoul::compute_middle()
int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni; int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni;
int i, j, order1 = (ewald_order|(ewald_off^-1))&(1<<1); int i, j, order1 = (ewald_order|(ewald_off^-1))&(1<<1);
double qri, *cut_ljsqi, *lj1i, *lj2i, *offseti; double qri, *cut_ljsqi, *lj1i, *lj2i;
vector xi, d; vector xi, d;
ineighn = (ineigh = list->ilist)+list->inum; ineighn = (ineigh = list->ilist)+list->inum;
@ -716,7 +702,6 @@ void PairLJCoul::compute_middle()
i = *ineigh; fi = f0+3*i; i = *ineigh; fi = f0+3*i;
qri = qqrd2e*q[i]; qri = qqrd2e*q[i];
memcpy(xi, x0+(i+(i<<1)), sizeof(vector)); memcpy(xi, x0+(i+(i<<1)), sizeof(vector));
offseti = offset[typei = type[i]];
cut_ljsqi = cut_ljsq[typei]; cut_ljsqi = cut_ljsq[typei];
lj1i = lj1[typei]; lj2i = lj2[typei]; lj1i = lj1[typei]; lj2i = lj2[typei];
jneighn = (jneigh = list->firstneigh[i])+list->numneigh[i]; jneighn = (jneigh = list->firstneigh[i])+list->numneigh[i];
@ -746,27 +731,27 @@ void PairLJCoul::compute_middle()
} }
else force_lj = 0.0; else force_lj = 0.0;
fforce = (force_coul + force_lj) * r2inv; fpair = (force_coul + force_lj) * r2inv;
if (rsq < cut_in_on_sq) { // switching if (rsq < cut_in_on_sq) { // switching
register double rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff; register double rsw = (sqrt(rsq) - cut_in_off)/cut_in_diff;
fforce *= rsw*rsw*(3.0 - 2.0*rsw); fpair *= rsw*rsw*(3.0 - 2.0*rsw);
} }
if (rsq > cut_out_on_sq) { if (rsq > cut_out_on_sq) {
register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff; register double rsw = (sqrt(rsq) - cut_out_on)/cut_out_diff;
fforce *= 1.0 + rsw*rsw*(2.0*rsw-3.0); fpair *= 1.0 + rsw*rsw*(2.0*rsw-3.0);
} }
if (newton_pair || j < nlocal) { // force update if (newton_pair || j < nlocal) { // force update
register double *fj = f0+(j+(j<<1)), f; register double *fj = f0+(j+(j<<1)), f;
fi[0] += f = d[0]*fforce; fj[0] -= f; fi[0] += f = d[0]*fpair; fj[0] -= f;
fi[1] += f = d[1]*fforce; fj[1] -= f; fi[1] += f = d[1]*fpair; fj[1] -= f;
fi[2] += f = d[2]*fforce; fj[2] -= f; fi[2] += f = d[2]*fpair; fj[2] -= f;
} }
else { else {
fi[0] += d[0]*fforce; fi[0] += d[0]*fpair;
fi[1] += d[1]*fforce; fi[1] += d[1]*fpair;
fi[2] += d[2]*fforce; fi[2] += d[2]*fpair;
} }
} }
} }
@ -776,12 +761,17 @@ void PairLJCoul::compute_middle()
void PairLJCoul::compute_outer(int eflag, int vflag) void PairLJCoul::compute_outer(int eflag, int vflag)
{ {
double evdwl,ecoul,fpair;
evdwl = ecoul = 0.0;
if (eflag || vflag) ev_setup(eflag,vflag);
else evflag = 0;
double **x = atom->x, *x0 = x[0]; double **x = atom->x, *x0 = x[0];
double **f = atom->f, *f0 = f[0], *fi = f0; double **f = atom->f, *f0 = f[0], *fi = f0;
double *q = atom->q; double *q = atom->q;
int *type = atom->type; int *type = atom->type;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = nlocal + atom->nghost;
double *special_coul = force->special_coul; double *special_coul = force->special_coul;
double *special_lj = force->special_lj; double *special_lj = force->special_lj;
int newton_pair = force->newton_pair; int newton_pair = force->newton_pair;
@ -790,7 +780,7 @@ void PairLJCoul::compute_outer(int eflag, int vflag)
int i, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6); int i, j, order1 = ewald_order&(1<<1), order6 = ewald_order&(1<<6);
int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni, respa_flag; int *ineigh, *ineighn, *jneigh, *jneighn, typei, typej, ni, respa_flag;
double qi, qri, *cutsqi, *cut_ljsqi, *lj1i, *lj2i, *lj3i, *lj4i, *offseti; double qi, qri, *cutsqi, *cut_ljsqi, *lj1i, *lj2i, *lj3i, *lj4i, *offseti;
double rsq, r2inv, force_coul, force_lj, fforce, factor; double rsq, r2inv, force_coul, force_lj;
double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2; double g2 = g_ewald*g_ewald, g6 = g2*g2*g2, g8 = g6*g2;
double respa_lj, respa_coul, frespa; double respa_lj, respa_coul, frespa;
vector xi, d; vector xi, d;
@ -802,9 +792,6 @@ void PairLJCoul::compute_outer(int eflag, int vflag)
double cut_in_off_sq = cut_in_off*cut_in_off; double cut_in_off_sq = cut_in_off*cut_in_off;
double cut_in_on_sq = cut_in_on*cut_in_on; double cut_in_on_sq = cut_in_on*cut_in_on;
eng_vdwl = eng_coul = 0.0; // reset energy&virial
if (vflag) memset(virial, 0, sizeof(shape));
ineighn = (ineigh = list->ilist)+list->inum; ineighn = (ineigh = list->ilist)+list->inum;
for (; ineigh<ineighn; ++ineigh) { // loop over my atoms for (; ineigh<ineighn; ++ineigh) { // loop over my atoms
@ -828,8 +815,6 @@ void PairLJCoul::compute_outer(int eflag, int vflag)
if ((rsq = vec_dot(d, d)) >= cutsqi[typej = type[j]]) continue; if ((rsq = vec_dot(d, d)) >= cutsqi[typej = type[j]]) continue;
r2inv = 1.0/rsq; r2inv = 1.0/rsq;
factor = newton_pair || j<nlocal ? 1.0 : 0.5;
if ((respa_flag = (rsq>cut_in_off_sq)&&(rsq<cut_in_on_sq))) { if ((respa_flag = (rsq>cut_in_off_sq)&&(rsq<cut_in_on_sq))) {
register double rsw = (sqrt(rsq)-cut_in_off)/cut_in_diff; register double rsw = (sqrt(rsq)-cut_in_off)/cut_in_diff;
frespa = rsw*rsw*(3.0-2.0*rsw); frespa = rsw*rsw*(3.0-2.0*rsw);
@ -844,12 +829,12 @@ void PairLJCoul::compute_outer(int eflag, int vflag)
if (ni < 0) { if (ni < 0) {
s *= g_ewald*exp(-x*x); s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s; force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s;
if (eflag) eng_coul += factor*t; if (eflag) ecoul = t;
} }
else { // correct for special else { // correct for special
r = s*(1.0-special_coul[ni])/r; s *= g_ewald*exp(-x*x); r = s*(1.0-special_coul[ni])/r; s *= g_ewald*exp(-x*x);
force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-r; force_coul = (t *= ((((t*A5+A4)*t+A3)*t+A2)*t+A1)*s/x)+EWALD_F*s-r;
if (eflag) eng_coul += factor*(t-r); if (eflag) ecoul = t-r;
} }
} // table real space } // table real space
else { else {
@ -861,16 +846,16 @@ void PairLJCoul::compute_outer(int eflag, int vflag)
register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j]; register double f = (rsq-rtable[k])*drtable[k], qiqj = qi*q[j];
if (ni < 0) { if (ni < 0) {
force_coul = qiqj*(ftable[k]+f*dftable[k]); force_coul = qiqj*(ftable[k]+f*dftable[k]);
if (eflag) eng_coul += factor*qiqj*(etable[k]+f*detable[k]); if (eflag) ecoul = qiqj*(etable[k]+f*detable[k]);
} }
else { // correct for special else { // correct for special
t = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]); t = (1.0-special_coul[ni])*(ctable[k]+f*dctable[k]);
force_coul = qiqj*(ftable[k]+f*dftable[k]-t); force_coul = qiqj*(ftable[k]+f*dftable[k]-t);
if (eflag) eng_coul += factor*qiqj*(etable[k]+f*detable[k]-t); if (eflag) ecoul = qiqj*(etable[k]+f*detable[k]-t);
} }
} }
} }
else force_coul = respa_coul = 0.0; else force_coul = respa_coul = ecoul = 0.0;
if (rsq < cut_ljsqi[typej]) { // lennard-jones if (rsq < cut_ljsqi[typej]) { // lennard-jones
register double rn = r2inv*r2inv*r2inv; register double rn = r2inv*r2inv*r2inv;
@ -883,60 +868,50 @@ void PairLJCoul::compute_outer(int eflag, int vflag)
if (ni < 0) { if (ni < 0) {
force_lj = force_lj =
(rn*=rn)*lj1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq; (rn*=rn)*lj1i[typej]-g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq;
if (eflag) eng_vdwl += if (eflag) evdwl = rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2;
factor*(rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2);
} }
else { // correct for special else { // correct for special
register double f = special_lj[ni], t = rn*(1.0-f); register double f = special_lj[ni], t = rn*(1.0-f);
force_lj = f*(rn *= rn)*lj1i[typej]- force_lj = f*(rn *= rn)*lj1i[typej]-
g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*lj2i[typej]; g8*(((6.0*a2+6.0)*a2+3.0)*a2+1.0)*x2*rsq+t*lj2i[typej];
if (eflag) eng_vdwl += factor*( if (eflag)
f*rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[typej]); evdwl = f*rn*lj3i[typej]-g6*((a2+1.0)*a2+0.5)*x2+t*lj4i[typej];
} }
} }
else { // cut form else { // cut form
if (ni < 0) { if (ni < 0) {
force_lj = rn*(rn*lj1i[typej]-lj2i[typej]); force_lj = rn*(rn*lj1i[typej]-lj2i[typej]);
if (eflag) eng_vdwl += factor*( if (eflag) evdwl = rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej];
rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej]);
} }
else { // correct for special else { // correct for special
register double f = special_lj[ni]; register double f = special_lj[ni];
force_lj = f*rn*(rn*lj1i[typej]-lj2i[typej]); force_lj = f*rn*(rn*lj1i[typej]-lj2i[typej]);
if (eflag) eng_vdwl += f*factor*( if (eflag)
rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej]); evdwl = f*(rn*(rn*lj3i[typej]-lj4i[typej])-offseti[typej]);
} }
} }
} }
else force_lj = respa_lj = 0.0; else force_lj = respa_lj = evdwl = 0.0;
fpair = (force_coul+force_lj)*r2inv;
frespa = fpair-(respa_coul+respa_lj)*r2inv;
fforce = (force_coul+force_lj)*r2inv; // force and virial
frespa = fforce-(respa_coul+respa_lj)*r2inv;
if (newton_pair || j < nlocal) { if (newton_pair || j < nlocal) {
register double *fj = f0+(j+(j<<1)), f; register double *fj = f0+(j+(j<<1)), f;
fi[0] += f = d[0]*frespa; fj[0] -= f; fi[0] += f = d[0]*frespa; fj[0] -= f;
fi[1] += f = d[1]*frespa; fj[1] -= f; fi[1] += f = d[1]*frespa; fj[1] -= f;
fi[2] += f = d[2]*frespa; fj[2] -= f; fi[2] += f = d[2]*frespa; fj[2] -= f;
if (vflag==1) {
virial[0] += (f = d[0]*fforce)*d[0]; virial[3] += f*d[1];
virial[1] += (f = d[1]*fforce)*d[1]; virial[5] += f*d[2];
virial[2] += (f = d[2]*fforce)*d[2]; virial[4] += f*d[0];
}
} }
else { else {
fi[0] += d[0]*frespa; fi[0] += d[0]*frespa;
fi[1] += d[1]*frespa; fi[1] += d[1]*frespa;
fi[2] += d[2]*frespa; fi[2] += d[2]*frespa;
if (vflag==1) {
register double f;
virial[0] += (f = 0.5*d[0]*fforce)*d[0]; virial[3] += f*d[1];
virial[1] += (f = 0.5*d[1]*fforce)*d[1]; virial[5] += f*d[2];
virial[2] += (f = 0.5*d[2]*fforce)*d[2]; virial[4] += f*d[0];
}
} }
if (evflag) ev_tally(i,j,nlocal,newton_pair,
evdwl,ecoul,fpair,d[0],d[1],d[2]);
} }
} }
if (vflag == 2) virial_compute();
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -23,12 +23,12 @@ class Angle : protected Pointers {
public: public:
int allocated; int allocated;
int *setflag; int *setflag;
double energy; double energy; // accumulated energies
double virial[6]; double virial[6]; // accumlated virial
double PI; double *eatom,**vatom; // accumulated per-atom energy/virial
Angle(class LAMMPS *); Angle(class LAMMPS *);
virtual ~Angle() {} virtual ~Angle();
virtual void init(); virtual void init();
virtual void compute(int, int) = 0; virtual void compute(int, int) = 0;
virtual void settings(int, char **) {} virtual void settings(int, char **) {}
@ -37,7 +37,19 @@ class Angle : protected Pointers {
virtual void write_restart(FILE *) = 0; virtual void write_restart(FILE *) = 0;
virtual void read_restart(FILE *) = 0; virtual void read_restart(FILE *) = 0;
virtual double single(int, int, int, int) = 0; virtual double single(int, int, int, int) = 0;
virtual double memory_usage() {return 0.0;} virtual double memory_usage();
protected:
double PI,THIRD;
int evflag;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
int maxeatom,maxvatom;
void ev_setup(int, int);
void ev_tally(int, int, int, int, int, double, double *, double *,
double, double, double, double, double, double);
}; };
} }

View File

@ -23,12 +23,12 @@ class Bond : protected Pointers {
public: public:
int allocated; int allocated;
int *setflag; int *setflag;
double energy; double energy; // accumulated energies
double eng_vdwl; double virial[6]; // accumlated virial
double virial[6]; double *eatom,**vatom; // accumulated per-atom energy/virial
Bond(class LAMMPS *); Bond(class LAMMPS *);
virtual ~Bond() {} virtual ~Bond();
virtual void init(); virtual void init();
virtual void init_style() {} virtual void init_style() {}
@ -38,8 +38,17 @@ class Bond : protected Pointers {
virtual double equilibrium_distance(int) = 0; virtual double equilibrium_distance(int) = 0;
virtual void write_restart(FILE *) = 0; virtual void write_restart(FILE *) = 0;
virtual void read_restart(FILE *) = 0; virtual void read_restart(FILE *) = 0;
virtual void single(int, double, int, int, int, double &, double &) = 0; virtual void single(int, double, int, int, double &) = 0;
virtual double memory_usage() {return 0.0;} virtual double memory_usage();
protected:
int evflag;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
int maxeatom,maxvatom;
void ev_setup(int, int);
void ev_tally(int, int, int, int, double, double, double, double, double);
}; };
} }

View File

@ -32,7 +32,7 @@ class BondHybrid : public Bond {
double equilibrium_distance(int); double equilibrium_distance(int);
void write_restart(FILE *); void write_restart(FILE *);
void read_restart(FILE *); void read_restart(FILE *);
void single(int, double, int, int, int, double &, double &); void single(int, double, int, int, double &);
double memory_usage(); double memory_usage();
private: private:

View File

@ -52,6 +52,7 @@ Compute::Compute(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
scalar_flag = vector_flag = peratom_flag = 0; scalar_flag = vector_flag = peratom_flag = 0;
tempflag = pressflag = peflag = 0; tempflag = pressflag = peflag = 0;
pressatomflag = peatomflag = 0;
timeflag = 0; timeflag = 0;
invoked = 0; invoked = 0;
npre = 0; npre = 0;

View File

@ -39,7 +39,9 @@ class Compute : protected Pointers {
// must have both compute_scalar, compute_vector // must have both compute_scalar, compute_vector
int pressflag; // 1 if Compute can be used as pressure (uses virial) int pressflag; // 1 if Compute can be used as pressure (uses virial)
// must have both compute_scalar, compute_vector // must have both compute_scalar, compute_vector
int pressatomflag; // 1 if Compute calculates per-atom virial
int peflag; // 1 if Compute calculates PE (uses Force energies) int peflag; // 1 if Compute calculates PE (uses Force energies)
int peatomflag; // 1 if Compute calculates per-atom PE
int timeflag; // 1 if Compute stores list of timesteps it's called on int timeflag; // 1 if Compute stores list of timesteps it's called on
int ntime; // # of entries in time list int ntime; // # of entries in time list

View File

@ -31,7 +31,6 @@ ComputeAttributeAtom::ComputeAttributeAtom(LAMMPS *lmp, int narg, char **arg) :
peratom_flag = 1; peratom_flag = 1;
size_peratom = 0; size_peratom = 0;
allocate = 1;
if (strcmp(arg[3],"x") == 0) which = X; if (strcmp(arg[3],"x") == 0) which = X;
else if (strcmp(arg[3],"y") == 0) which = Y; else if (strcmp(arg[3],"y") == 0) which = Y;
@ -49,15 +48,12 @@ ComputeAttributeAtom::ComputeAttributeAtom(LAMMPS *lmp, int narg, char **arg) :
else if (strcmp(arg[3],"xyz") == 0) { else if (strcmp(arg[3],"xyz") == 0) {
which = XYZ; which = XYZ;
size_peratom = 3; size_peratom = 3;
allocate = 0;
} else if (strcmp(arg[3],"v") == 0) { } else if (strcmp(arg[3],"v") == 0) {
which = V; which = V;
size_peratom = 3; size_peratom = 3;
allocate = 0;
} else if (strcmp(arg[3],"f") == 0) { } else if (strcmp(arg[3],"f") == 0) {
which = F; which = F;
size_peratom = 3; size_peratom = 3;
allocate = 0;
} else error->all("Illegal compute attribute/atom command"); } else error->all("Illegal compute attribute/atom command");
nmax = 0; nmax = 0;
@ -69,10 +65,8 @@ ComputeAttributeAtom::ComputeAttributeAtom(LAMMPS *lmp, int narg, char **arg) :
ComputeAttributeAtom::~ComputeAttributeAtom() ComputeAttributeAtom::~ComputeAttributeAtom()
{ {
if (allocate) { memory->sfree(s_attribute);
memory->sfree(s_attribute); memory->destroy_2d_double_array(v_attribute);
memory->destroy_2d_double_array(v_attribute);
}
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -81,19 +75,21 @@ void ComputeAttributeAtom::compute_peratom()
{ {
// grow attribute array if necessary // grow attribute array if necessary
if (allocate && atom->nlocal > nmax) { if (atom->nlocal > nmax) {
if (size_peratom == 0) { if (size_peratom == 0) {
memory->sfree(s_attribute); memory->sfree(s_attribute);
nmax = atom->nmax; nmax = atom->nmax;
s_attribute = (double *) s_attribute = (double *)
memory->smalloc(nmax*sizeof(double), memory->smalloc(nmax*sizeof(double),
"compute/attribute/atom:s_attribute"); "compute/attribute/atom:s_attribute");
scalar_atom = s_attribute;
} else { } else {
memory->destroy_2d_double_array(v_attribute); memory->destroy_2d_double_array(v_attribute);
nmax = atom->nmax; nmax = atom->nmax;
v_attribute = v_attribute =
memory->create_2d_double_array(nmax,size_peratom, memory->create_2d_double_array(nmax,size_peratom,
"compute/attribute/atom:v_attribute"); "compute/attribute/atom:v_attribute");
vector_atom = v_attribute;
} }
} }
@ -166,14 +162,40 @@ void ComputeAttributeAtom::compute_peratom()
if (mask[i] & groupbit) s_attribute[i] = f[i][2]; if (mask[i] & groupbit) s_attribute[i] = f[i][2];
else s_attribute[i] = 0.0; else s_attribute[i] = 0.0;
} else if (which == XYZ) v_attribute = x; } else if (which == XYZ) {
else if (which == V) v_attribute = v; for (int i = 0; i < nlocal; i++)
else if (which == F) v_attribute = f; if (mask[i] & groupbit) {
v_attribute[i][0] = x[i][0];
// set appropriate compute ptr to local array v_attribute[i][1] = x[i][1];
v_attribute[i][2] = x[i][2];
if (size_peratom == 0) scalar_atom = s_attribute; } else {
else vector_atom = v_attribute; v_attribute[i][0] = 0.0;
v_attribute[i][1] = 0.0;
v_attribute[i][2] = 0.0;
}
} else if (which == V) {
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
v_attribute[i][0] = v[i][0];
v_attribute[i][1] = v[i][1];
v_attribute[i][2] = v[i][2];
} else {
v_attribute[i][0] = 0.0;
v_attribute[i][1] = 0.0;
v_attribute[i][2] = 0.0;
}
} else if (which == F) {
for (int i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
v_attribute[i][0] = f[i][0];
v_attribute[i][1] = f[i][1];
v_attribute[i][2] = f[i][2];
} else {
v_attribute[i][0] = 0.0;
v_attribute[i][1] = 0.0;
v_attribute[i][2] = 0.0;
}
}
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -183,9 +205,7 @@ void ComputeAttributeAtom::compute_peratom()
double ComputeAttributeAtom::memory_usage() double ComputeAttributeAtom::memory_usage()
{ {
double bytes = 0.0; double bytes = 0.0;
if (allocate) { if (size_peratom == 0) bytes = nmax * sizeof(double);
if (size_peratom == 0) bytes = nmax * sizeof(double); else bytes = size_peratom * nmax * sizeof(double);
else bytes = size_peratom * nmax * sizeof(double);
}
return bytes; return bytes;
} }

View File

@ -113,7 +113,6 @@ void ComputeCentroAtom::compute_peratom()
double **x = atom->x; double **x = atom->x;
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = atom->nlocal + atom->nghost;
double cutsq = force->pair->cutforce * force->pair->cutforce; double cutsq = force->pair->cutforce * force->pair->cutforce;

View File

@ -112,7 +112,6 @@ void ComputeCoordAtom::compute_peratom()
double **x = atom->x; double **x = atom->x;
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal;
int nall = atom->nlocal + atom->nghost; int nall = atom->nlocal + atom->nghost;
double cutsq = cutoff*cutoff; double cutsq = cutoff*cutoff;

View File

@ -74,12 +74,8 @@ double ComputePE::compute_scalar()
invoked = 1; invoked = 1;
double one = 0.0; double one = 0.0;
if (pairflag) { if (pairflag && force->pair)
if (force->pair) one += force->pair->eng_vdwl + force->pair->eng_coul; one += force->pair->eng_vdwl + force->pair->eng_coul;
if (force->bond) one += force->bond->eng_vdwl;
if (force->dihedral)
one += force->dihedral->eng_vdwl + force->dihedral->eng_coul;
}
if (atom->molecular) { if (atom->molecular) {
if (bondflag && force->bond) one += force->bond->energy; if (bondflag && force->bond) one += force->bond->energy;

View File

@ -35,9 +35,15 @@ using namespace LAMMPS_NS;
ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg) Compute(lmp, narg, arg)
{ {
if (narg != 4) error->all("Illegal compute pressure command"); if (narg < 4) error->all("Illegal compute pressure command");
if (igroup) error->all("Compute pressure must use group all"); if (igroup) error->all("Compute pressure must use group all");
scalar_flag = vector_flag = 1;
size_vector = 6;
extensive = 0;
pressflag = 1;
timeflag = 1;
// store temperature ID used by pressure computation // store temperature ID used by pressure computation
// insure it is valid for temperature computation // insure it is valid for temperature computation
@ -53,13 +59,32 @@ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) :
if (modify->compute[icompute]->tempflag == 0) if (modify->compute[icompute]->tempflag == 0)
error->all("Compute pressure temp ID does not compute temperature"); error->all("Compute pressure temp ID does not compute temperature");
// settings // process optional args
scalar_flag = vector_flag = 1; if (narg == 4) {
size_vector = 6; keflag = 1;
extensive = 0; pairflag = 1;
pressflag = 1; bondflag = angleflag = dihedralflag = improperflag = 1;
timeflag = 1; fixflag = kspaceflag = 1;
} else {
keflag = 0;
pairflag = 0;
bondflag = angleflag = dihedralflag = improperflag = 0;
fixflag = kspaceflag = 0;
int iarg = 4;
while (iarg < narg) {
if (strcmp(arg[iarg],"ke") == 0) keflag = 1;
else if (strcmp(arg[iarg],"pair") == 0) pairflag = 1;
else if (strcmp(arg[iarg],"bond") == 0) bondflag = 1;
else if (strcmp(arg[iarg],"angle") == 0) angleflag = 1;
else if (strcmp(arg[iarg],"dihedral") == 0) dihedralflag = 1;
else if (strcmp(arg[iarg],"improper") == 0) improperflag = 1;
else if (strcmp(arg[iarg],"fix") == 0) fixflag = 1;
else if (strcmp(arg[iarg],"kspace") == 0) kspaceflag = 1;
else error->all("Illegal compute stress/atom command");
iarg++;
}
}
vector = new double[6]; vector = new double[6];
nvirial = 0; nvirial = 0;
@ -95,34 +120,35 @@ void ComputePressure::init()
nvirial = 0; nvirial = 0;
vptr = NULL; vptr = NULL;
if (force->pair) nvirial++; if (pairflag && force->pair) nvirial++;
if (atom->molecular && force->bond) nvirial++; if (bondflag && atom->molecular && force->bond) nvirial++;
if (atom->molecular && force->angle) nvirial++; if (angleflag && atom->molecular && force->angle) nvirial++;
if (atom->molecular && force->dihedral) nvirial++; if (dihedralflag && atom->molecular && force->dihedral) nvirial++;
if (atom->molecular && force->improper) nvirial++; if (improperflag && atom->molecular && force->improper) nvirial++;
for (int i = 0; i < modify->nfix; i++) if (fixflag)
if (modify->fix[i]->virial_flag) nvirial++; for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->virial_flag) nvirial++;
if (nvirial) { if (nvirial) {
vptr = new double*[nvirial]; vptr = new double*[nvirial];
nvirial = 0; nvirial = 0;
if (force->pair) vptr[nvirial++] = force->pair->virial; if (pairflag && force->pair) vptr[nvirial++] = force->pair->virial;
if (force->bond) vptr[nvirial++] = force->bond->virial; if (bondflag && force->bond) vptr[nvirial++] = force->bond->virial;
if (force->angle) vptr[nvirial++] = force->angle->virial; if (angleflag && force->angle) vptr[nvirial++] = force->angle->virial;
if (force->dihedral) vptr[nvirial++] = force->dihedral->virial; if (dihedralflag && force->dihedral)
if (force->improper) vptr[nvirial++] = force->improper->virial; vptr[nvirial++] = force->dihedral->virial;
for (int i = 0; i < modify->nfix; i++) if (improperflag && force->improper)
if (modify->fix[i]->virial_flag) vptr[nvirial++] = force->improper->virial;
vptr[nvirial++] = modify->fix[i]->virial; if (fixflag)
for (int i = 0; i < modify->nfix; i++)
if (modify->fix[i]->virial_flag)
vptr[nvirial++] = modify->fix[i]->virial;
} }
// flag Kspace contribution separately, since not summed across procs // flag Kspace contribution separately, since not summed across procs
kspaceflag = 0; if (kspaceflag && force->kspace) kspace_virial = force->kspace->virial;
if (force->kspace) { else kspace_virial = NULL;
kspaceflag = 1;
kspace_virial = force->kspace->virial;
}
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -135,13 +161,19 @@ double ComputePressure::compute_scalar()
if (dimension == 3) { if (dimension == 3) {
inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd);
virial_compute(3,3); virial_compute(3,3);
scalar = (temperature->dof * boltz * temperature->scalar + if (keflag)
virial[0] + virial[1] + virial[2]) / 3.0 * inv_volume * nktv2p; scalar = (temperature->dof * boltz * temperature->scalar +
virial[0] + virial[1] + virial[2]) / 3.0 * inv_volume * nktv2p;
else
scalar = (virial[0] + virial[1] + virial[2]) / 3.0 * inv_volume * nktv2p;
} else { } else {
inv_volume = 1.0 / (domain->xprd * domain->yprd); inv_volume = 1.0 / (domain->xprd * domain->yprd);
virial_compute(2,2); virial_compute(2,2);
scalar = (temperature->dof * boltz * temperature->scalar + if (keflag)
virial[0] + virial[1]) / 2.0 * inv_volume * nktv2p; scalar = (temperature->dof * boltz * temperature->scalar +
virial[0] + virial[1]) / 2.0 * inv_volume * nktv2p;
else
scalar = (virial[0] + virial[1]) / 2.0 * inv_volume * nktv2p;
} }
return scalar; return scalar;
@ -157,16 +189,26 @@ void ComputePressure::compute_vector()
if (dimension == 3) { if (dimension == 3) {
inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd);
virial_compute(6,3); virial_compute(6,3);
double *ke_tensor = temperature->vector; if (keflag) {
for (int i = 0; i < 6; i++) double *ke_tensor = temperature->vector;
vector[i] = (ke_tensor[i] + virial[i]) * inv_volume * nktv2p; for (int i = 0; i < 6; i++)
vector[i] = (ke_tensor[i] + virial[i]) * inv_volume * nktv2p;
} else
for (int i = 0; i < 6; i++)
vector[i] = virial[i] * inv_volume * nktv2p;
} else { } else {
inv_volume = 1.0 / (domain->xprd * domain->yprd); inv_volume = 1.0 / (domain->xprd * domain->yprd);
virial_compute(4,2); virial_compute(4,2);
double *ke_tensor = temperature->vector; if (keflag) {
vector[0] = (ke_tensor[0] + virial[0]) * inv_volume * nktv2p; double *ke_tensor = temperature->vector;
vector[1] = (ke_tensor[1] + virial[1]) * inv_volume * nktv2p; vector[0] = (ke_tensor[0] + virial[0]) * inv_volume * nktv2p;
vector[3] = (ke_tensor[3] + virial[3]) * inv_volume * nktv2p; vector[1] = (ke_tensor[1] + virial[1]) * inv_volume * nktv2p;
vector[3] = (ke_tensor[3] + virial[3]) * inv_volume * nktv2p;
} else {
vector[0] = virial[0] * inv_volume * nktv2p;
vector[1] = virial[1] * inv_volume * nktv2p;
vector[3] = virial[3] * inv_volume * nktv2p;
}
} }
} }
@ -193,7 +235,7 @@ void ComputePressure::virial_compute(int n, int ndiag)
// KSpace virial contribution is already summed across procs // KSpace virial contribution is already summed across procs
if (force->kspace) if (kspace_virial)
for (i = 0; i < n; i++) virial[i] += kspace_virial[i]; for (i = 0; i < n; i++) virial[i] += kspace_virial[i];
// LJ long-range tail correction // LJ long-range tail correction

View File

@ -30,10 +30,11 @@ class ComputePressure : public Compute {
double boltz,nktv2p,inv_volume; double boltz,nktv2p,inv_volume;
int nvirial,dimension; int nvirial,dimension;
double **vptr; double **vptr;
int kspaceflag;
double *kspace_virial; double *kspace_virial;
Compute *temperature; Compute *temperature;
double virial[6]; double virial[6];
int keflag,pairflag,bondflag,angleflag,dihedralflag,improperflag;
int fixflag,kspaceflag;
void virial_compute(int, int); void virial_compute(int, int);
}; };

View File

@ -11,60 +11,54 @@
See the README file in the top-level LAMMPS directory. See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#include "stdlib.h"
#include "string.h" #include "string.h"
#include "compute_stress_atom.h" #include "compute_stress_atom.h"
#include "atom.h" #include "atom.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "modify.h"
#include "comm.h" #include "comm.h"
#include "update.h"
#include "force.h" #include "force.h"
#include "bond.h"
#include "pair.h" #include "pair.h"
#include "domain.h" #include "bond.h"
#include "angle.h"
#include "dihedral.h"
#include "improper.h"
#include "memory.h" #include "memory.h"
#include "error.h" #include "error.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
ComputeStressAtom::ComputeStressAtom(LAMMPS *lmp, int narg, char **arg) : ComputeStressAtom::ComputeStressAtom(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg) Compute(lmp, narg, arg)
{ {
if (narg < 3) error->all("Illegal compute stress/atom command"); if (narg < 3) error->all("Illegal compute stress/atom command");
peratom_flag = 1; peratom_flag = 1;
size_peratom = 6; size_peratom = 6;
pressatomflag = 1;
timeflag = 1;
comm_reverse = 6; comm_reverse = 6;
// process args if (narg == 3) {
keflag = 1;
kerequest = pairrequest = bondrequest = 1; pairflag = 1;
bondflag = angleflag = dihedralflag = improperflag = 1;
int iarg = 3; } else {
while (iarg < narg) { keflag = 0;
if (strcmp(arg[iarg],"ke") == 0) { pairflag = 0;
if (iarg+2 > narg) error->all("Illegal compute ebond/atom command"); bondflag = angleflag = dihedralflag = improperflag = 0;
if (strcmp(arg[iarg+1],"yes") == 0) kerequest = 1; int iarg = 3;
else if (strcmp(arg[iarg+1],"no") == 0) kerequest = 0; while (iarg < narg) {
iarg += 2; if (strcmp(arg[iarg],"ke") == 0) keflag = 1;
} else if (strcmp(arg[iarg],"pair") == 0) { else if (strcmp(arg[iarg],"pair") == 0) pairflag = 1;
if (iarg+2 > narg) error->all("Illegal compute ebond/atom command"); else if (strcmp(arg[iarg],"bond") == 0) bondflag = 1;
if (strcmp(arg[iarg+1],"yes") == 0) pairrequest = 1; else if (strcmp(arg[iarg],"angle") == 0) angleflag = 1;
else if (strcmp(arg[iarg+1],"no") == 0) pairrequest = 0; else if (strcmp(arg[iarg],"dihedral") == 0) dihedralflag = 1;
iarg += 2; else if (strcmp(arg[iarg],"improper") == 0) improperflag = 1;
} else if (strcmp(arg[iarg],"bond") == 0) { else error->all("Illegal compute stress/atom command");
if (iarg+2 > narg) error->all("Illegal compute ebond/atom command"); iarg++;
if (strcmp(arg[iarg+1],"yes") == 0) bondrequest = 1; }
else if (strcmp(arg[iarg+1],"no") == 0) bondrequest = 0;
iarg += 2;
} else error->all("Illegal compute ebond/atom command");
} }
nmax = 0; nmax = 0;
@ -80,50 +74,13 @@ ComputeStressAtom::~ComputeStressAtom()
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
void ComputeStressAtom::init()
{
if (pairrequest) {
if (force->pair == NULL || force->pair->single_enable == 0)
error->all("Pair style does not support computing per-atom stress");
pairflag = 1;
// need an occasional half neighbor list
int irequest = neighbor->request((void *) this);
neighbor->requests[irequest]->pair = 0;
neighbor->requests[irequest]->compute = 1;
neighbor->requests[irequest]->occasional = 1;
} else pairflag = 0;
if (bondrequest && force->bond) bondflag = 1;
else bondflag = 0;
int count = 0;
for (int i = 0; i < modify->ncompute; i++)
if (strcmp(modify->compute[i]->style,"stress/atom") == 0) count++;
if (count > 1 && comm->me == 0)
error->warning("More than one compute stress/atom");
}
/* ---------------------------------------------------------------------- */
void ComputeStressAtom::init_list(int id, NeighList *ptr)
{
list = ptr;
}
/* ---------------------------------------------------------------------- */
void ComputeStressAtom::compute_peratom() void ComputeStressAtom::compute_peratom()
{ {
int i,j,ii,jj,n,i1,i2,inum,jnum,itype,jtype,iflag,jflag; int i,j;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq,eng;
double factor_coul,factor_lj,fforce,rmass;
int *ilist,*jlist,*numneigh,**firstneigh;
Pair::One one;
// grow stress array if necessary invoked = 1;
// grow local stress array if necessary
if (atom->nmax > nmax) { if (atom->nmax > nmax) {
memory->destroy_2d_double_array(stress); memory->destroy_2d_double_array(stress);
@ -133,199 +90,115 @@ void ComputeStressAtom::compute_peratom()
vector_atom = stress; vector_atom = stress;
} }
// clear stress array // npair includes ghosts if either newton flag is set
// n includes ghosts only if newton flag is set // b/c some bonds/dihedrals call pair::ev_tally with pairwise info
// nbond includes ghosts if newton_bond is set
// ntotal includes ghosts if either newton flag is set
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
int npair = nlocal;
int nbond = nlocal;
int ntotal = nlocal;
if (force->newton) npair += atom->nghost;
if (force->newton_bond) nbond += atom->nghost;
if (force->newton) ntotal += atom->nghost;
if (force->newton) n = nlocal + atom->nghost; // clear local stress array
else n = nlocal;
for (i = 0; i < n; i++) { for (i = 0; i < ntotal; i++)
stress[i][0] = 0.0; for (j = 0; j < 6; j++)
stress[i][1] = 0.0; stress[i][j] = 0.0;
stress[i][2] = 0.0;
stress[i][3] = 0.0; // add in per-atom contributions from each force
stress[i][4] = 0.0;
stress[i][5] = 0.0; if (pairflag && force->pair) {
double **vatom = force->pair->vatom;
for (i = 0; i < npair; i++)
for (j = 0; j < 6; j++)
stress[i][j] += vatom[i][j];
} }
// compute pairwise stress for atoms via pair->single() if (bondflag && force->bond) {
// if neither atom is in compute group, skip that pair double **vatom = force->bond->vatom;
// only add stress to atoms in group for (i = 0; i < nbond; i++)
for (j = 0; j < 6; j++)
if (pairflag) { stress[i][j] += vatom[i][j];
// invoke half neighbor list (will copy or build if necessary)
neighbor->build_one(list->index);
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
double *special_coul = force->special_coul;
double *special_lj = force->special_lj;
double **cutsq = force->pair->cutsq;
int newton_pair = force->newton_pair;
double **x = atom->x;
int *mask = atom->mask;
int *type = atom->type;
int nall = nlocal + atom->nghost;
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
itype = type[i];
iflag = mask[i] & groupbit;
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
jflag = mask[j] & groupbit;
if (iflag == 0 && jflag == 0) continue;
if (j < nall) factor_coul = factor_lj = 1.0;
else {
factor_coul = special_coul[j/nall];
factor_lj = special_lj[j/nall];
j %= nall;
}
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
jtype = type[j];
if (rsq < cutsq[itype][jtype]) {
force->pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,0,one);
fforce = one.fforce;
if (iflag) {
stress[i][0] -= delx*delx*fforce;
stress[i][1] -= dely*dely*fforce;
stress[i][2] -= delz*delz*fforce;
stress[i][3] -= delx*dely*fforce;
stress[i][4] -= delx*delz*fforce;
stress[i][5] -= dely*delz*fforce;
}
if (jflag && (newton_pair || j < nlocal)) {
stress[j][0] -= delx*delx*fforce;
stress[j][1] -= dely*dely*fforce;
stress[j][2] -= delz*delz*fforce;
stress[j][3] -= delx*dely*fforce;
stress[j][4] -= delx*delz*fforce;
stress[j][5] -= dely*delz*fforce;
}
}
}
}
} }
// compute bond stress for atoms via bond->single() if (angleflag && force->angle) {
// if neither atom is in compute group, skip that bond double **vatom = force->angle->vatom;
// only add stress to atoms in group for (i = 0; i < nbond; i++)
for (j = 0; j < 6; j++)
if (bondflag) { stress[i][j] += vatom[i][j];
double **x = atom->x;
int *mask = atom->mask;
int **bondlist = neighbor->bondlist;
int nbondlist = neighbor->nbondlist;
int newton_bond = force->newton_bond;
int type;
for (n = 0; n < nbondlist; n++) {
i1 = bondlist[n][0];
i2 = bondlist[n][1];
type = bondlist[n][2];
iflag = mask[i1] & groupbit;
jflag = mask[i2] & groupbit;
if (iflag == 0 && jflag == 0) continue;
delx = x[i1][0] - x[i2][0];
dely = x[i1][1] - x[i2][1];
delz = x[i1][2] - x[i2][2];
domain->minimum_image(delx,dely,delz);
rsq = delx*delx + dely*dely + delz*delz;
force->bond->single(type,rsq,i1,i2,0,fforce,eng);
if (iflag) {
stress[i1][0] -= delx*delx*fforce;
stress[i1][1] -= dely*dely*fforce;
stress[i1][2] -= delz*delz*fforce;
stress[i1][3] -= delx*dely*fforce;
stress[i1][4] -= delx*delz*fforce;
stress[i1][5] -= dely*delz*fforce;
}
if (jflag && (newton_bond || i2 < nlocal)) {
stress[i2][0] -= delx*delx*fforce;
stress[i2][1] -= dely*dely*fforce;
stress[i2][2] -= delz*delz*fforce;
stress[i2][3] -= delx*dely*fforce;
stress[i2][4] -= delx*delz*fforce;
stress[i2][5] -= dely*delz*fforce;
}
}
} }
// communicate stress between neighbor procs if (dihedralflag && force->dihedral) {
double **vatom = force->dihedral->vatom;
for (i = 0; i < nbond; i++)
for (j = 0; j < 6; j++)
stress[i][j] += vatom[i][j];
}
if (improperflag && force->improper) {
double **vatom = force->improper->vatom;
for (i = 0; i < nbond; i++)
for (j = 0; j < 6; j++)
stress[i][j] += vatom[i][j];
}
// communicate ghost energy between neighbor procs
if (force->newton) comm->reverse_comm_compute(this); if (force->newton) comm->reverse_comm_compute(this);
// remove double counting // zero virial of atoms not in group
// only do this after comm since ghost contributions must be included
for (i = 0; i < nlocal; i++) { int *mask = atom->mask;
stress[i][0] *= 0.5;
stress[i][1] *= 0.5; for (i = 0; i < nlocal; i++)
stress[i][2] *= 0.5; if (!(mask[i] & groupbit)) {
stress[i][3] *= 0.5; stress[i][0] = 0.0;
stress[i][4] *= 0.5; stress[i][1] = 0.0;
stress[i][5] *= 0.5; stress[i][2] = 0.0;
} stress[i][3] = 0.0;
stress[i][4] = 0.0;
stress[i][5] = 0.0;
}
// include kinetic energy term for each atom in group // include kinetic energy term for each atom in group
// mvv2e converts mv^2 to energy // mvv2e converts mv^2 to energy
if (kerequest) { if (keflag) {
double **v = atom->v; double **v = atom->v;
double *mass = atom->mass; double *mass = atom->mass;
int *mask = atom->mask;
int *type = atom->type; int *type = atom->type;
double mvv2e = force->mvv2e; double mvv2e = force->mvv2e;
double rmass;
for (i = 0; i < nlocal; i++) {
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) { if (mask[i] & groupbit) {
rmass = mvv2e * mass[type[i]]; rmass = mvv2e * mass[type[i]];
stress[i][0] -= rmass*v[i][0]*v[i][0]; stress[i][0] += rmass*v[i][0]*v[i][0];
stress[i][1] -= rmass*v[i][1]*v[i][1]; stress[i][1] += rmass*v[i][1]*v[i][1];
stress[i][2] -= rmass*v[i][2]*v[i][2]; stress[i][2] += rmass*v[i][2]*v[i][2];
stress[i][3] -= rmass*v[i][0]*v[i][1]; stress[i][3] += rmass*v[i][0]*v[i][1];
stress[i][4] -= rmass*v[i][0]*v[i][2]; stress[i][4] += rmass*v[i][0]*v[i][2];
stress[i][5] -= rmass*v[i][1]*v[i][2]; stress[i][5] += rmass*v[i][1]*v[i][2];
} }
}
// convert to pressure units (actually stress/volume = -pressure)
double nktv2p = -force->nktv2p;
for (i = 0; i < nlocal; i++)
if (mask[i] & groupbit) {
stress[i][0] *= nktv2p;
stress[i][1] *= nktv2p;
stress[i][2] *= nktv2p;
stress[i][3] *= nktv2p;
stress[i][4] *= nktv2p;
stress[i][5] *= nktv2p;
} }
}
// convert to pressure units (actually stress/volume = pressure)
double nktv2p = force->nktv2p;
for (i = 0; i < nlocal; i++) {
stress[i][0] *= nktv2p;
stress[i][1] *= nktv2p;
stress[i][2] *= nktv2p;
stress[i][3] *= nktv2p;
stress[i][4] *= nktv2p;
stress[i][5] *= nktv2p;
}
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */

View File

@ -19,22 +19,18 @@
namespace LAMMPS_NS { namespace LAMMPS_NS {
class ComputeStressAtom : public Compute { class ComputeStressAtom : public Compute {
public: public:
ComputeStressAtom(class LAMMPS *, int, char **); ComputeStressAtom(class LAMMPS *, int, char **);
~ComputeStressAtom(); ~ComputeStressAtom();
void init(); void init() {}
void init_list(int, class NeighList *);
void compute_peratom(); void compute_peratom();
int pack_reverse_comm(int, int, double *); int pack_reverse_comm(int, int, double *);
void unpack_reverse_comm(int, int *, double *); void unpack_reverse_comm(int, int *, double *);
double memory_usage(); double memory_usage();
private: private:
int pairrequest,bondrequest,kerequest; int keflag,pairflag,bondflag,angleflag,dihedralflag,improperflag;
int pairflag,bondflag;
int nmax; int nmax;
class NeighList *list;
double **stress; double **stress;
}; };

View File

@ -114,6 +114,7 @@ double ComputeSum::compute_scalar()
compute[icompute]->compute_peratom(); compute[icompute]->compute_peratom();
// compute scalar quantity by summing over atom scalars // compute scalar quantity by summing over atom scalars
// only include atoms in group
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
@ -145,6 +146,7 @@ void ComputeSum::compute_vector()
compute[icompute]->compute_peratom(); compute[icompute]->compute_peratom();
// compute vector quantity by summing over atom vectors // compute vector quantity by summing over atom vectors
// only include atoms in group
int *mask = atom->mask; int *mask = atom->mask;
int nlocal = atom->nlocal; int nlocal = atom->nlocal;

View File

@ -23,22 +23,33 @@ class Dihedral : protected Pointers {
public: public:
int allocated; int allocated;
int *setflag; int *setflag;
double energy; double energy; // accumulated energy
double eng_vdwl,eng_coul; double virial[6]; // accumlated virial
double virial[6]; double *eatom,**vatom; // accumulated per-atom energy/virial
double PI;
Dihedral(class LAMMPS *); Dihedral(class LAMMPS *);
virtual ~Dihedral() {} virtual ~Dihedral();
virtual void init(); virtual void init();
virtual void init_style() {} virtual void init_style() {}
virtual void compute(int, int) = 0; virtual void compute(int, int) = 0;
virtual void settings(int, char **) {} virtual void settings(int, char **) {}
virtual void coeff(int, int, char **) = 0; virtual void coeff(int, int, char **) = 0;
virtual void write_restart(FILE *) = 0; virtual void write_restart(FILE *) = 0;
virtual void read_restart(FILE *) = 0; virtual void read_restart(FILE *) = 0;
virtual double memory_usage() {return 0.0;} virtual double memory_usage();
protected:
double PI;
int evflag;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
int maxeatom,maxvatom;
void ev_setup(int, int);
void ev_tally(int, int, int, int, int, int, double,
double *, double *, double *, double, double, double,
double, double, double, double, double, double);
}; };
} }

View File

@ -78,12 +78,23 @@ FixAveAtom::FixAveAtom(LAMMPS *lmp, int narg, char **arg) :
vector[i][m] = 0.0; vector[i][m] = 0.0;
// nvalid = next step on which end_of_step does something // nvalid = next step on which end_of_step does something
// can be this timestep if multiple of peratom_freq and nrepeat = 1
// else backup from next multiple of peratom_freq
irepeat = 0; irepeat = 0;
nvalid = (update->ntimestep/peratom_freq)*peratom_freq + peratom_freq; nvalid = (update->ntimestep/peratom_freq)*peratom_freq + peratom_freq;
nvalid -= (nrepeat-1)*nevery; if (nvalid-peratom_freq == update->ntimestep && nrepeat == 1)
if (nvalid <= update->ntimestep) nvalid = update->ntimestep;
error->all("Fix ave/atom cannot be started on this timestep"); else
nvalid -= (nrepeat-1)*nevery;
if (nvalid < update->ntimestep) nvalid += peratom_freq;
// must set timestep for all computes that store invocation times
// since don't know a priori which are invoked by this fix
// once in end_of_step() can just set timestep for ones actually invoked
for (int i = 0; i < modify->ncompute; i++)
if (modify->compute[i]->timeflag) modify->compute[i]->add_step(nvalid);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -156,6 +167,7 @@ void FixAveAtom::end_of_step()
// accumulate results of compute to local copy // accumulate results of compute to local copy
modify->clearstep_compute();
for (i = 0; i < ncompute; i++) compute[i]->compute_peratom(); for (i = 0; i < ncompute; i++) compute[i]->compute_peratom();
int *mask = atom->mask; int *mask = atom->mask;
@ -172,26 +184,30 @@ void FixAveAtom::end_of_step()
vector[i][m] += compute_vector[i][m]; vector[i][m] += compute_vector[i][m];
} }
// done if irepeat < nrepeat
// else reset irepeat and nvalid
irepeat++; irepeat++;
nvalid += nevery; if (irepeat < nrepeat) {
nvalid += nevery;
// divide by nrepeat if final step modify->addstep_compute(nvalid);
// reset irepeat and nvalid return;
if (irepeat == nrepeat) {
double repeat = nrepeat;
if (size_peratom == 0)
for (i = 0; i < nlocal; i++)
scalar[i] /= repeat;
else
for (i = 0; i < nlocal; i++)
for (m = 0; m < size_peratom; m++)
vector[i][m] /= repeat;
irepeat = 0;
nvalid = update->ntimestep+peratom_freq - (nrepeat-1)*nevery;
} }
irepeat = 0;
nvalid = update->ntimestep+peratom_freq - (nrepeat-1)*nevery;
modify->addstep_compute(nvalid);
// average the final result for the Nfreq timestep
double repeat = nrepeat;
if (size_peratom == 0)
for (i = 0; i < nlocal; i++)
scalar[i] /= repeat;
else
for (i = 0; i < nlocal; i++)
for (m = 0; m < size_peratom; m++)
vector[i][m] /= repeat;
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -238,6 +238,14 @@ FixAveSpatial::FixAveSpatial(LAMMPS *lmp, int narg, char **arg) :
else else
nvalid -= (nrepeat-1)*nevery; nvalid -= (nrepeat-1)*nevery;
if (nvalid < update->ntimestep) nvalid += nfreq; if (nvalid < update->ntimestep) nvalid += nfreq;
// must set timestep for all computes that store invocation times
// since don't know a priori which are invoked by this fix
// once in end_of_step() can just set timestep for ones actually invoked
if (which == COMPUTE)
for (int i = 0; i < modify->ncompute; i++)
if (modify->compute[i]->timeflag) modify->compute[i]->add_step(nvalid);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -492,6 +500,7 @@ void FixAveSpatial::end_of_step()
// COMPUTE adds its scalar or vector quantity to values // COMPUTE adds its scalar or vector quantity to values
} else if (which == COMPUTE) { } else if (which == COMPUTE) {
modify->clearstep_compute();
for (i = 0; i < ncompute; i++) compute[i]->compute_peratom(); for (i = 0; i < ncompute; i++) compute[i]->compute_peratom();
double *scalar = compute[ncompute-1]->scalar_atom; double *scalar = compute[ncompute-1]->scalar_atom;
double **vector = compute[ncompute-1]->vector_atom; double **vector = compute[ncompute-1]->vector_atom;
@ -558,10 +567,18 @@ void FixAveSpatial::end_of_step()
} }
// done if irepeat < nrepeat // done if irepeat < nrepeat
// else reset irepeat and nvalid
irepeat++; irepeat++;
nvalid += nevery; if (irepeat < nrepeat) {
if (irepeat < nrepeat) return; nvalid += nevery;
if (which == COMPUTE) modify->addstep_compute(nvalid);
return;
}
irepeat = 0;
nvalid = update->ntimestep+nfreq - (nrepeat-1)*nevery;
if (which == COMPUTE) modify->addstep_compute(nvalid);
// time average across samples // time average across samples
// if density, also normalize by volume // if density, also normalize by volume
@ -593,11 +610,6 @@ void FixAveSpatial::end_of_step()
values_sum[m][0] *= count_sum[m] / layer_volume; values_sum[m][0] *= count_sum[m] / layer_volume;
} }
// reset irepeat and nvalid
irepeat = 0;
nvalid = update->ntimestep+nfreq - (nrepeat-1)*nevery;
// if ave = ONE, only single Nfreq timestep value is needed // if ave = ONE, only single Nfreq timestep value is needed
// if ave = RUNNING, combine with all previous Nfreq timestep values // if ave = RUNNING, combine with all previous Nfreq timestep values
// if ave = WINDOW, comine with nwindow most recent Nfreq timestep values // if ave = WINDOW, comine with nwindow most recent Nfreq timestep values

View File

@ -321,6 +321,8 @@ void FixShake::init()
for (i = 1; i <= atom->nangletypes; i++) { for (i = 1; i <= atom->nangletypes; i++) {
if (angle_flag[i] == 0) continue; if (angle_flag[i] == 0) continue;
if (force->angle == NULL)
error->all("Angle potential must be defined for SHAKE");
// scan all atoms for a SHAKE angle cluster // scan all atoms for a SHAKE angle cluster
// extract bond types for the 2 bonds in the cluster // extract bond types for the 2 bonds in the cluster

View File

@ -23,19 +23,32 @@ class Improper : protected Pointers {
public: public:
int allocated; int allocated;
int *setflag; int *setflag;
double energy; double energy; // accumulated energies
double virial[6]; double virial[6]; // accumlated virial
double PI; double *eatom,**vatom; // accumulated per-atom energy/virial
Improper(class LAMMPS *); Improper(class LAMMPS *);
virtual ~Improper() {} virtual ~Improper();
virtual void init(); virtual void init();
virtual void compute(int, int) = 0; virtual void compute(int, int) = 0;
virtual void settings(int, char **) {} virtual void settings(int, char **) {}
virtual void coeff(int, int, char **) = 0; virtual void coeff(int, int, char **) = 0;
virtual void write_restart(FILE *) = 0; virtual void write_restart(FILE *) = 0;
virtual void read_restart(FILE *) = 0; virtual void read_restart(FILE *) = 0;
virtual double memory_usage() {return 0.0;} virtual double memory_usage();
protected:
double PI;
int evflag;
int eflag_either,eflag_global,eflag_atom;
int vflag_either,vflag_global,vflag_atom;
int maxeatom,maxvatom;
void ev_setup(int, int);
void ev_tally(int, int, int, int, int, int, double,
double *, double *, double *, double, double, double,
double, double, double, double, double, double);
}; };
} }

View File

@ -13,6 +13,7 @@
#include "stdlib.h" #include "stdlib.h"
#include "integrate.h" #include "integrate.h"
#include "modify.h"
#include "compute.h" #include "compute.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -21,33 +22,99 @@ using namespace LAMMPS_NS;
Integrate::Integrate(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) Integrate::Integrate(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
{ {
elist = vlist = NULL; elist_global = elist_atom = NULL;
vlist_global = vlist_atom = NULL;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
Integrate::~Integrate() Integrate::~Integrate()
{ {
delete [] elist; delete [] elist_global;
delete [] vlist; delete [] elist_atom;
delete [] vlist_global;
delete [] vlist_atom;
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
set eflag if a pe compute is called this timestep setup lists of computes for global and per-atom PE and pressure
set vflag if a pressure compute is called this timestep ------------------------------------------------------------------------- */
void Integrate::ev_setup()
{
delete [] elist_global;
delete [] elist_atom;
delete [] vlist_global;
delete [] vlist_atom;
elist_global = elist_atom = NULL;
vlist_global = vlist_atom = NULL;
nelist_global = nelist_atom = 0;
nvlist_global = nvlist_atom = 0;
for (int i = 0; i < modify->ncompute; i++) {
if (modify->compute[i]->peflag) nelist_global++;
if (modify->compute[i]->peatomflag) nelist_atom++;
if (modify->compute[i]->pressflag) nvlist_global++;
if (modify->compute[i]->pressatomflag) nvlist_atom++;
}
if (nelist_global) elist_global = new Compute*[nelist_global];
if (nelist_atom) elist_atom = new Compute*[nelist_atom];
if (nvlist_global) vlist_global = new Compute*[nvlist_global];
if (nvlist_atom) vlist_atom = new Compute*[nvlist_atom];
nelist_global = nelist_atom = 0;
nvlist_global = nvlist_atom = 0;
for (int i = 0; i < modify->ncompute; i++) {
if (modify->compute[i]->peflag)
elist_global[nelist_global++] = modify->compute[i];
if (modify->compute[i]->peatomflag)
elist_atom[nelist_atom++] = modify->compute[i];
if (modify->compute[i]->pressflag)
vlist_global[nvlist_global++] = modify->compute[i];
if (modify->compute[i]->pressatomflag)
vlist_atom[nvlist_atom++] = modify->compute[i];
}
}
/* ----------------------------------------------------------------------
set eflag,vflag for current iteration with ntimestep
eflag = 0 = no energy computation
eflag = 1 = global energy only
eflag = 2 = per-atom energy only
eflag = 3 = both global and per-atom energy
vflag = 0 = no virial computation (pressure)
vflag = 1 = global virial with pair portion via sum of pairwise interactions
vflag = 2 = global virial with pair portion via F dot r including ghosts
vflag = 4 = per-atom virial only
vflag = 5 or 6 = both global and per-atom virial
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void Integrate::ev_set(int ntimestep) void Integrate::ev_set(int ntimestep)
{ {
int i; int i;
eflag = 0; int eflag_global = 0;
for (i = 0; i < nelist; i++) for (i = 0; i < nelist_global; i++)
if (elist[i]->match_step(ntimestep)) break; if (elist_global[i]->match_step(ntimestep)) break;
if (i < nelist) eflag = 1; if (i < nelist_global) eflag_global = 1;
vflag = 0; int eflag_atom = 0;
for (i = 0; i < nvlist; i++) for (i = 0; i < nelist_atom; i++)
if (vlist[i]->match_step(ntimestep)) break; if (elist_atom[i]->match_step(ntimestep)) break;
if (i < nvlist) vflag = virial_style; if (i < nelist_atom) eflag_atom = 2;
eflag = eflag_global + eflag_atom;
int vflag_global = 0;
for (i = 0; i < nvlist_global; i++)
if (vlist_global[i]->match_step(ntimestep)) break;
if (i < nvlist_global) vflag_global = virial_style;
int vflag_atom = 0;
for (i = 0; i < nvlist_atom; i++)
if (vlist_atom[i]->match_step(ntimestep)) break;
if (i < nvlist_atom) vflag_atom = 4;
vflag = vflag_global + vflag_atom;
} }

View File

@ -33,10 +33,14 @@ class Integrate : protected Pointers {
int eflag,vflag; // flags for energy/virial computation int eflag,vflag; // flags for energy/virial computation
int virial_style; // compute virial explicitly or implicitly int virial_style; // compute virial explicitly or implicitly
int nelist,nvlist; // # of PE,virial coputes for eflag,vflag int nelist_global,nelist_atom; // # of PE,virial computes to check
class Compute **elist; // list of Computes to check int nvlist_global,nvlist_atom;
class Compute **vlist; class Compute **elist_global; // list of PE,virial Computes
class Compute **elist_atom;
class Compute **vlist_global;
class Compute **vlist_atom;
void ev_setup();
void ev_set(int); void ev_set(int);
}; };

View File

@ -14,6 +14,8 @@
#include "stdlib.h" #include "stdlib.h"
#include "string.h" #include "string.h"
#include "min.h" #include "min.h"
#include "modify.h"
#include "compute.h"
#include "error.h" #include "error.h"
using namespace LAMMPS_NS; using namespace LAMMPS_NS;
@ -29,6 +31,18 @@ Min::Min(LAMMPS *lmp) : Pointers(lmp)
dmin = 1.0e-5; dmin = 1.0e-5;
dmax = 0.1; dmax = 0.1;
lineiter = 10; lineiter = 10;
elist_atom = NULL;
vlist_global = vlist_atom = NULL;
}
/* ---------------------------------------------------------------------- */
Min::~Min()
{
delete [] elist_atom;
delete [] vlist_global;
delete [] vlist_atom;
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -60,3 +74,79 @@ void Min::modify_params(int narg, char **arg)
} else error->all("Illegal min_modify command"); } else error->all("Illegal min_modify command");
} }
} }
/* ----------------------------------------------------------------------
setup lists of computes for global and per-atom PE and pressure
------------------------------------------------------------------------- */
void Min::ev_setup()
{
delete [] elist_atom;
delete [] vlist_global;
delete [] vlist_atom;
elist_atom = NULL;
vlist_global = vlist_atom = NULL;
nelist_atom = 0;
nvlist_global = nvlist_atom = 0;
for (int i = 0; i < modify->ncompute; i++) {
if (modify->compute[i]->peatomflag) nelist_atom++;
if (modify->compute[i]->pressflag) nvlist_global++;
if (modify->compute[i]->pressatomflag) nvlist_atom++;
}
if (nelist_atom) elist_atom = new Compute*[nelist_atom];
if (nvlist_global) vlist_global = new Compute*[nvlist_global];
if (nvlist_atom) vlist_atom = new Compute*[nvlist_atom];
nelist_atom = 0;
nvlist_global = nvlist_atom = 0;
for (int i = 0; i < modify->ncompute; i++) {
if (modify->compute[i]->peatomflag)
elist_atom[nelist_atom++] = modify->compute[i];
if (modify->compute[i]->pressflag)
vlist_global[nvlist_global++] = modify->compute[i];
if (modify->compute[i]->pressatomflag)
vlist_atom[nvlist_atom++] = modify->compute[i];
}
}
/* ----------------------------------------------------------------------
set eflag,vflag for current iteration with ntimestep
always set eflag_global = 1, since need energy every iteration
eflag = 0 = no energy computation
eflag = 1 = global energy only
eflag = 2 = per-atom energy only
eflag = 3 = both global and per-atom energy
vflag = 0 = no virial computation (pressure)
vflag = 1 = global virial with pair portion via sum of pairwise interactions
vflag = 2 = global virial with pair portion via F dot r including ghosts
vflag = 4 = per-atom virial only
vflag = 5 or 6 = both global and per-atom virial
------------------------------------------------------------------------- */
void Min::ev_set(int ntimestep)
{
int i;
int eflag_global = 1;
int eflag_atom = 0;
for (i = 0; i < nelist_atom; i++)
if (elist_atom[i]->match_step(ntimestep)) break;
if (i < nelist_atom) eflag_atom = 2;
eflag = eflag_global + eflag_atom;
int vflag_global = 0;
for (i = 0; i < nvlist_global; i++)
if (vlist_global[i]->match_step(ntimestep)) break;
if (i < nvlist_global) vflag_global = virial_style;
int vflag_atom = 0;
for (i = 0; i < nvlist_atom; i++)
if (vlist_atom[i]->match_step(ntimestep)) break;
if (i < nvlist_atom) vflag_atom = 4;
vflag = vflag_global + vflag_atom;
}

View File

@ -27,12 +27,25 @@ class Min : protected Pointers {
int linestyle,lineiter; int linestyle,lineiter;
Min(class LAMMPS *); Min(class LAMMPS *);
virtual ~Min() {} virtual ~Min();
virtual void init() = 0; virtual void init() = 0;
virtual void run() = 0; virtual void run() = 0;
virtual double memory_usage() {return 0.0;} virtual double memory_usage() {return 0.0;}
void modify_params(int, char **); void modify_params(int, char **);
protected:
int eflag,vflag; // flags for energy/virial computation
int virial_style; // compute virial explicitly or implicitly
int nelist_atom; // # of PE,virial computes to check
int nvlist_global,nvlist_atom;
class Compute **elist_atom; // list of PE,virial Computes
class Compute **vlist_global;
class Compute **vlist_atom;
void ev_setup();
void ev_set(int);
}; };
} }

View File

@ -57,17 +57,7 @@ using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
MinCG::MinCG(LAMMPS *lmp) : Min(lmp) MinCG::MinCG(LAMMPS *lmp) : Min(lmp) {}
{
vlist = NULL;
}
/* ---------------------------------------------------------------------- */
MinCG::~MinCG()
{
delete [] vlist;
}
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -96,20 +86,9 @@ void MinCG::init()
if (force->newton_pair) virial_style = 2; if (force->newton_pair) virial_style = 2;
else virial_style = 1; else virial_style = 1;
// vlist = list of computes for pressure // setup lists of computes for global and per-atom PE and pressure
delete [] vlist; ev_setup();
vlist = NULL;
nvlist = 0;
for (int i = 0; i < modify->ncompute; i++)
if (modify->compute[i]->pressflag) nvlist++;
if (nvlist) vlist = new Compute*[nvlist];
nvlist = 0;
for (int i = 0; i < modify->ncompute; i++)
if (modify->compute[i]->pressflag) vlist[nvlist++] = modify->compute[i];
// set flags for what arrays to clear in force_clear() // set flags for what arrays to clear in force_clear()
// need to clear torques if array exists // need to clear torques if array exists
@ -256,7 +235,7 @@ void MinCG::setup()
// compute all forces // compute all forces
ev_set(update->ntimestep); ev_set(update->ntimestep);
force_clear(vflag); force_clear();
if (force->pair) force->pair->compute(eflag,vflag); if (force->pair) force->pair->compute(eflag,vflag);
@ -409,7 +388,7 @@ void MinCG::eng_force(int *pndof, double **px, double **ph, double *peng)
} }
ev_set(update->ntimestep); ev_set(update->ntimestep);
force_clear(vflag); force_clear();
timer->stamp(); timer->stamp();
@ -454,28 +433,12 @@ void MinCG::eng_force(int *pndof, double **px, double **ph, double *peng)
*peng = ecurrent; *peng = ecurrent;
} }
/* ----------------------------------------------------------------------
eflag is always set, since minimizer needs potential energy
set vflag if a pressure compute is called this timestep
------------------------------------------------------------------------- */
void MinCG::ev_set(int ntimestep)
{
int i;
eflag = 1;
vflag = 0;
for (i = 0; i < nvlist; i++)
if (vlist[i]->match_step(ntimestep)) break;
if (i < nvlist) vflag = virial_style;
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
clear force on own & ghost atoms clear force on own & ghost atoms
setup and clear other arrays as needed setup and clear other arrays as needed
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void MinCG::force_clear(int vflag) void MinCG::force_clear()
{ {
int i; int i;

View File

@ -21,24 +21,16 @@ namespace LAMMPS_NS {
class MinCG : public Min { class MinCG : public Min {
public: public:
MinCG(class LAMMPS *); MinCG(class LAMMPS *);
virtual ~MinCG(); virtual ~MinCG() {}
void init(); void init();
void run(); void run();
virtual void iterate(int); virtual void iterate(int);
protected: protected:
int eflag,vflag; // flags for energy/virial computation
int virial_style; // compute virial explicitly or implicitly
int pairflag,torqueflag; int pairflag,torqueflag;
int neigh_every,neigh_delay,neigh_dist_check; // copies of reneigh criteria int neigh_every,neigh_delay,neigh_dist_check; // copies of reneigh criteria
int triclinic; // 0 if domain is orthog, 1 if triclinic int triclinic; // 0 if domain is orthog, 1 if triclinic
int nvlist; // # of PE,virial coputes for eflag,vflag
class Compute **vlist; // list of Computes to check
int maxpair; // copies of Update quantities
double **f_pair;
class FixMinimize *fix_minimize; // fix that stores gradient vecs class FixMinimize *fix_minimize; // fix that stores gradient vecs
class Compute *pe_compute; // compute for potential energy class Compute *pe_compute; // compute for potential energy
double ecurrent; // current potential energy double ecurrent; // current potential energy
@ -59,8 +51,7 @@ class MinCG : public Min {
void setup(); void setup();
void setup_vectors(); void setup_vectors();
void eng_force(int *, double **, double **, double *); void eng_force(int *, double **, double **, double *);
void ev_set(int); void force_clear();
void force_clear(int);
}; };
} }

View File

@ -56,8 +56,6 @@ void Neighbor::granular_nsq_no_newton(NeighList *list)
int *numneigh = list->numneigh; int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh; int **firstneigh = list->firstneigh;
int **pages = list->pages; int **pages = list->pages;
int nstencil = list->nstencil;
int *stencil = list->stencil;
FixShearHistory *fix_history = list->fix_history; FixShearHistory *fix_history = list->fix_history;
if (fix_history) { if (fix_history) {
@ -190,8 +188,6 @@ void Neighbor::granular_nsq_newton(NeighList *list)
int *numneigh = list->numneigh; int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh; int **firstneigh = list->firstneigh;
int **pages = list->pages; int **pages = list->pages;
int nstencil = list->nstencil;
int *stencil = list->stencil;
int inum = 0; int inum = 0;
int npage = 0; int npage = 0;

View File

@ -142,7 +142,6 @@ void Neighbor::half_bin_newton(NeighList *list)
int *numneigh = list->numneigh; int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh; int **firstneigh = list->firstneigh;
int **pages = list->pages; int **pages = list->pages;
int skip = list->skip;
int nstencil = list->nstencil; int nstencil = list->nstencil;
int *stencil = list->stencil; int *stencil = list->stencil;

View File

@ -42,8 +42,6 @@ void Neighbor::half_nsq_no_newton(NeighList *list)
int *numneigh = list->numneigh; int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh; int **firstneigh = list->firstneigh;
int **pages = list->pages; int **pages = list->pages;
int nstencil = list->nstencil;
int *stencil = list->stencil;
int inum = 0; int inum = 0;
int npage = 0; int npage = 0;
@ -121,8 +119,6 @@ void Neighbor::half_nsq_newton(NeighList *list)
int *numneigh = list->numneigh; int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh; int **firstneigh = list->firstneigh;
int **pages = list->pages; int **pages = list->pages;
int nstencil = list->nstencil;
int *stencil = list->stencil;
int inum = 0; int inum = 0;
int npage = 0; int npage = 0;

Some files were not shown because too many files have changed in this diff Show More