--- /home/sjplimp/oldlammps/doc/dihedral_style.txt 2005-11-09 15:08:07.000000000 -0700
+++ /home/sjplimp/lammps/doc/dihedral_style.txt 2005-12-07 10:07:23.000000000 -0700
@@ -44,7 +44,7 @@
torsions that contain the j-k bond in an i-j-k-l torsion. :l
Some force fields let {n} be positive or negative which corresponds to
-{d} = 1 or -1. :ule,l
+{d} = 1 or -1 for the harmonic style. :ule,l
A style of {none} means dihedral forces are not computed, even if
dihedrals are defined.
--- /home/sjplimp/oldlammps/doc/dihedral_coeff.txt 2005-11-09 15:08:07.000000000 -0700
+++ /home/sjplimp/lammps/doc/dihedral_coeff.txt 2005-12-07 10:07:23.000000000 -0700
@@ -66,12 +66,12 @@
For style {charmm}, specify 4 coefficients:
K (energy)
-n (1,2,3,4,6)
-d (0 or 180 degrees)
+n (integer >= 0)
+d (integer value of degrees)
weighting factor (0.0 to 1.0) :ul
The weighting factor is applied to pairwise interaction between the
-1st and 4th atoms in the dihedral.
+1st and 4th atoms in the dihedral.
:line
@@ -151,7 +151,7 @@
K (energy)
d (+1 or -1)
-n (1,2,3,4,6) :ul
+n (integer >= 0) :ul
:line
--- /home/sjplimp/oldlammps/doc/dihedral_style.html 2005-11-09 15:08:07.000000000 -0700
+++ /home/sjplimp/lammps/doc/dihedral_style.html 2005-12-07 10:07:29.000000000 -0700
@@ -47,7 +47,7 @@
torsions that contain the j-k bond in an i-j-k-l torsion.
Some force fields let n be positive or negative which corresponds to
-d = 1 or -1.
+d = 1 or -1 for the harmonic style.
A style of none means dihedral forces are not computed, even if
dihedrals are defined.
--- /home/sjplimp/oldlammps/doc/dihedral_coeff.html 2005-11-09 15:08:07.000000000 -0700
+++ /home/sjplimp/lammps/doc/dihedral_coeff.html 2005-12-07 10:07:29.000000000 -0700
@@ -69,12 +69,12 @@
For style charmm, specify 4 coefficients:
- K (energy)
-
- n (1,2,3,4,6)
-
- d (0 or 180 degrees)
+
- n (integer >= 0)
+
- d (integer value of degrees)
- weighting factor (0.0 to 1.0)
The weighting factor is applied to pairwise interaction between the
-1st and 4th atoms in the dihedral.
+1st and 4th atoms in the dihedral.
@@ -154,7 +154,7 @@
- K (energy)
- d (+1 or -1)
-
- n (1,2,3,4,6)
+
- n (integer >= 0)
--- /home/sjplimp/oldlammps/src/MOLECULE/dihedral_charmm.cpp 2005-11-09 15:08:07.000000000 -0700
+++ /home/sjplimp/lammps/src/MOLECULE/dihedral_charmm.cpp 2005-12-07 10:10:35.000000000 -0700
@@ -46,7 +46,9 @@
memory->sfree(setflag);
memory->sfree(k);
memory->sfree(multiplicity);
- memory->sfree(sign);
+ memory->sfree(shift);
+ memory->sfree(cos_shift);
+ memory->sfree(sin_shift);
memory->sfree(weight);
}
}
@@ -55,15 +57,14 @@
void DihedralCharmm::compute(int eflag, int vflag)
{
- int m,n,i1,i2,i3,i4,type,factor;
+ int i,m,n,i1,i2,i3,i4,type,factor;
double rfactor;
double vb1x,vb1y,vb1z,vb2x,vb2y;
- double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z,sb1;
- double sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
- double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
- double c2mag,sc1,sc2,s1,s12,c,p,pd,rc2,a,a11,a22;
- double a33,a12,a13,a23,sx1,sx2,sx12,sy1,sy2,sy12;
- double sz1,sz2,sz12,s2;
+ double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z;
+ 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,dfx,dfy,dfz,dgx,dgy,dgz;
+ double dhx,dhy,dhz,dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;
+ double c,s,p,sx1,sx2,sx12,sy1,sy2,sy12,sz1,sz2,sz12,s2;
int itype,jtype;
double delx,dely,delz,rsq,r2inv,r6inv;
double fforce,forcecoul,forcelj,phicoul,philj;
@@ -125,49 +126,26 @@
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(&vb3x,&vb3y,&vb3z);
+
+ ax = vb1y*vb2zm - vb1z*vb2ym;
+ ay = vb1z*vb2xm - vb1x*vb2zm;
+ az = vb1x*vb2ym - vb1y*vb2xm;
+ bx = vb3y*vb2zm - vb3z*vb2ym;
+ by = vb3z*vb2xm - vb3x*vb2zm;
+ bz = vb3x*vb2ym - vb3y*vb2xm;
+
+ rasq = ax*ax + ay*ay + az*az;
+ rbsq = bx*bx + by*by + bz*bz;
+ rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm;
+ rg = sqrt(rgsq);
+
+ rginv = 1.0/rg;
+ ra2inv = 1.0/rasq;
+ rb2inv = 1.0/rbsq;
+ rabinv = sqrt(ra2inv*rb2inv);
- // c0 calculation
-
- sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
- sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
- sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
-
- rb1 = sqrt(sb1);
- rb3 = sqrt(sb3);
-
- c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
-
- // 1st and 2nd angle
-
- b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
- b1mag = sqrt(b1mag2);
- b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
- b2mag = sqrt(b2mag2);
- b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
- b3mag = sqrt(b3mag2);
-
- ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
- r12c1 = 1.0 / (b1mag*b2mag);
- c1mag = ctmp * r12c1;
-
- ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
- r12c2 = 1.0 / (b2mag*b3mag);
- c2mag = ctmp * r12c2;
-
- // cos and sin of 2 angles and final c
-
- sc1 = sqrt(1.0 - c1mag*c1mag);
- if (sc1 < SMALL) sc1 = SMALL;
- sc1 = 1.0/sc1;
-
- sc2 = sqrt(1.0 - c2mag*c2mag);
- if (sc2 < SMALL) sc2 = SMALL;
- sc2 = 1.0/sc2;
-
- s1 = sc1 * sc1;
- s2 = sc2 * sc2;
- s12 = sc1 * sc2;
- c = (c0 + c1mag*c2mag) * s12;
+ c = (ax*bx + ay*by + az*bz)*rabinv;
+ s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z);
// error check
@@ -191,68 +169,58 @@
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
-
- // force & energy
- // p = 1 + cos(n*phi) for d = 1
- // p = 1 - cos(n*phi) for d = -1
- // pd = dp/dc / 2
-
+
m = multiplicity[type];
-
- if (m == 2) {
- p = 2.0*c*c;
- pd = 2.0*c;
- } else if (m == 3) {
- rc2 = c*c;
- p = (4.0*rc2-3.0)*c + 1.0;
- pd = 6.0*rc2 - 1.5;
- } else if (m == 4) {
- rc2 = c*c;
- p = 8.0*(rc2-1)*rc2 + 2.0;
- pd = (16.0*rc2-8.0)*c;
- } else if (m == 6) {
- rc2 = c*c;
- p = ((32.0*rc2-48.0)*rc2 + 18.0)*rc2;
- pd = (96.0*(rc2-1.0)*rc2 + 18.0)*c;
- } else if (m == 1) {
- p = c + 1.0;
- pd = 0.5;
- } else if (m == 5) {
- rc2 = c*c;
- p = ((16.0*rc2-20.0)*rc2 + 5.0)*c + 1.0;
- pd = (40.0*rc2-30.0)*rc2 + 2.5;
- } else if (m == 0) {
- p = 2.0;
- pd = 0.0;
- }
+ p = 1.0;
+ df1 = 0.0;
- if (sign[type] == 180) {
- p = 2.0 - p;
- pd = -pd;
+ for (i = 0; i < m; i++) {
+ ddf1 = p*c - df1*s;
+ df1 = p*s + df1*c;
+ p = ddf1;
}
- if (eflag) energy += rfactor * k[type] * p;
-
- a = 2.0 * k[type] * pd;
- c = c * a;
- s12 = s12 * a;
- a11 = (-c*sb1*s1);
- a22 = sb2*(2.0*c0*s12 - c*(s1+s2));
- a33 = (-c*sb3*s2);
- a12 = r12c1*(c1mag*c*s1 + c2mag*s12);
- a13 = rb1*rb3*s12;
- a23 = r12c2*(-c2mag*c*s2 - c1mag*s12);
-
- sx1 = a11*vb1x + a12*vb2x + a13*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;
- sy12 = a13*vb1y + a23*vb2y + a33*vb3y;
- sz1 = a11*vb1z + a12*vb2z + a13*vb3z;
- sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
- sz12 = a13*vb1z + a23*vb2z + a33*vb3z;
+ p = p*cos_shift[type] + df1*sin_shift[type];
+ df1 = df1*cos_shift[type] - ddf1*sin_shift[type];
+ df1 *= -m;
+ p += 1.0;
+
+ if (m == 0) {
+ p = 1.0 + cos_shift[type];
+ df1 = 0.0;
+ }
+ if (eflag) energy += rfactor * k[type] * p;
+
+ fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm;
+ hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm;
+ fga = fg*ra2inv*rginv;
+ hgb = hg*rb2inv*rginv;
+ gaa = -ra2inv*rg;
+ gbb = rb2inv*rg;
+
+ dtfx = gaa*ax;
+ dtfy = gaa*ay;
+ dtfz = gaa*az;
+ dtgx = fga*ax - hgb*bx;
+ dtgy = fga*ay - hgb*by;
+ dtgz = fga*az - hgb*bz;
+ dthx = gbb*bx;
+ dthy = gbb*by;
+ dthz = gbb*bz;
+
+ df = k[type] * df1;
+
+ sx1 = df*dtfx;
+ sy1 = df*dtfy;
+ sz1 = df*dtfz;
+ sx2 = -df*dtgx;
+ sy2 = -df*dtgy;
+ sz2 = -df*dtgz;
+ sx12 = df*dthx;
+ sy12 = df*dthy;
+ sz12 = df*dthz;
+
// apply force to each of 4 atoms
if (newton_bond || i1 < nlocal) {
@@ -350,9 +318,14 @@
int n = atom->ndihedraltypes;
k = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:k");
- multiplicity = (int *) memory->smalloc((n+1)*sizeof(double),
- "dihedral:multiplicity");
- sign = (int *) memory->smalloc((n+1)*sizeof(double),"dihedral:sign");
+ multiplicity = (int *)
+ memory->smalloc((n+1)*sizeof(double),"dihedral:multiplicity");
+ shift = (int *)
+ memory->smalloc((n+1)*sizeof(double),"dihedral:shift");
+ cos_shift = (double *)
+ memory->smalloc((n+1)*sizeof(double),"dihedral:cos_shift");
+ sin_shift = (double *)
+ memory->smalloc((n+1)*sizeof(double),"dihedral:sin_shift");
weight = (double *) memory->smalloc((n+1)*sizeof(double),"dihedral:weight");
setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag");
@@ -371,23 +344,29 @@
int ilo,ihi;
force->bounds(arg[0],atom->ndihedraltypes,ilo,ihi);
-
+
+ // require integer values of shift for backwards compatibility
+ // arbitrary phase angle shift could be allowed, but would break
+ // backwards compatibility and is probably not needed
+
double k_one = atof(arg[1]);
int multiplicity_one = atoi(arg[2]);
- int sign_one = atoi(arg[3]);
+ int shift_one = atoi(arg[3]);
double weight_one = atof(arg[4]);
- if (multiplicity_one < 1 || multiplicity_one > 6)
- error->all("Incorrect args for dihedral coefficients");
- if (sign_one != 0 && sign_one != 180)
- error->all("Incorrect args for dihedral coefficients");
+ if (multiplicity_one < 0)
+ error->all("Incorrect multiplicity arg for dihedral coefficients");
if (weight_one < 0.0 || weight_one > 1.0)
- error->all("Incorrect args for dihedral coefficients");
+ error->all("Incorrect weight arg for dihedral coefficients");
+ double PI = 4.0*atan(1.0);
+
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
- sign[i] = sign_one;
+ shift[i] = shift_one;
+ cos_shift[i] = cos(PI*shift_one/180.0);
+ sin_shift[i] = sin(PI*shift_one/180.0);
multiplicity[i] = multiplicity_one;
weight[i] = weight_one;
setflag[i] = 1;
@@ -440,7 +419,7 @@
{
fwrite(&k[1],sizeof(double),atom->ndihedraltypes,fp);
fwrite(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp);
- fwrite(&sign[1],sizeof(int),atom->ndihedraltypes,fp);
+ fwrite(&shift[1],sizeof(int),atom->ndihedraltypes,fp);
fwrite(&weight[1],sizeof(double),atom->ndihedraltypes,fp);
}
@@ -455,13 +434,18 @@
if (comm->me == 0) {
fread(&k[1],sizeof(double),atom->ndihedraltypes,fp);
fread(&multiplicity[1],sizeof(int),atom->ndihedraltypes,fp);
- fread(&sign[1],sizeof(int),atom->ndihedraltypes,fp);
+ fread(&shift[1],sizeof(int),atom->ndihedraltypes,fp);
fread(&weight[1],sizeof(double),atom->ndihedraltypes,fp);
}
MPI_Bcast(&k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
MPI_Bcast(&multiplicity[1],atom->ndihedraltypes,MPI_INT,0,world);
- MPI_Bcast(&sign[1],atom->ndihedraltypes,MPI_INT,0,world);
+ MPI_Bcast(&shift[1],atom->ndihedraltypes,MPI_INT,0,world);
MPI_Bcast(&weight[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
- for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1;
+ double PI = 4.0*atan(1.0);
+ for (int i = 1; i <= atom->ndihedraltypes; i++) {
+ setflag[i] = 1;
+ cos_shift[i] = cos(PI*shift[i]/180.0);
+ sin_shift[i] = sin(PI*shift[i]/180.0);
+ }
}
--- /home/sjplimp/oldlammps/src/MOLECULE/dihedral_charmm.h 2005-11-09 15:08:07.000000000 -0700
+++ /home/sjplimp/lammps/src/MOLECULE/dihedral_charmm.h 2005-12-07 10:10:35.000000000 -0700
@@ -28,8 +28,8 @@
void read_restart(FILE *);
private:
- double *k,*weight;
- int *multiplicity,*sign;
+ double *k,*weight,*cos_shift,*sin_shift;
+ int *multiplicity,*shift;
double **lj14_1,**lj14_2,**lj14_3,**lj14_4;
void allocate();
--- /home/sjplimp/oldlammps/src/MOLECULE/dihedral_harmonic.cpp 2005-11-09 15:08:07.000000000 -0700
+++ /home/sjplimp/lammps/src/MOLECULE/dihedral_harmonic.cpp 2005-12-07 10:10:35.000000000 -0700
@@ -11,6 +11,10 @@
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
+/* ----------------------------------------------------------------------
+ Contributing author: Paul Crozier (SNL)
+------------------------------------------------------------------------- */
+
// harmonic dihedral potential
#include "mpi.h"
@@ -18,9 +22,9 @@
#include "string.h"
#include "dihedral_harmonic.h"
#include "atom.h"
+#include "comm.h"
#include "neighbor.h"
#include "domain.h"
-#include "comm.h"
#include "force.h"
#include "update.h"
#include "memory.h"
@@ -40,6 +44,8 @@
memory->sfree(k);
memory->sfree(sign);
memory->sfree(multiplicity);
+ memory->sfree(cos_shift);
+ memory->sfree(sin_shift);
}
}
@@ -47,15 +53,14 @@
void DihedralHarmonic::compute(int eflag, int vflag)
{
- int m,n,i1,i2,i3,i4,type,factor;
+ int i,m,n,i1,i2,i3,i4,type,factor;
double rfactor;
double vb1x,vb1y,vb1z,vb2x,vb2y;
- double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z,sb1;
- double sb2,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
- double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
- double c2mag,sc1,sc2,s1,s12,c,p,pd,rc2,a,a11,a22;
- double a33,a12,a13,a23,sx1,sx2,sx12,sy1,sy2,sy12;
- double sz1,sz2,sz12,s2;
+ double vb2z,vb2xm,vb2ym,vb2zm,vb3x,vb3y,vb3z;
+ 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,dfx,dfy,dfz,dgx,dgy,dgz;
+ double dhx,dhy,dhz,dtfx,dtfy,dtfz,dtgx,dtgy,dtgz,dthx,dthy,dthz;
+ double c,s,p,sx1,sx2,sx12,sy1,sy2,sy12,sz1,sz2,sz12,s2;
energy = 0.0;
if (vflag) for (n = 0; n < 6; n++) virial[n] = 0.0;
@@ -110,49 +115,26 @@
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
domain->minimum_image(&vb3x,&vb3y,&vb3z);
+
+ ax = vb1y*vb2zm - vb1z*vb2ym;
+ ay = vb1z*vb2xm - vb1x*vb2zm;
+ az = vb1x*vb2ym - vb1y*vb2xm;
+ bx = vb3y*vb2zm - vb3z*vb2ym;
+ by = vb3z*vb2xm - vb3x*vb2zm;
+ bz = vb3x*vb2ym - vb3y*vb2xm;
+
+ rasq = ax*ax + ay*ay + az*az;
+ rbsq = bx*bx + by*by + bz*bz;
+ rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm;
+ rg = sqrt(rgsq);
+
+ rginv = 1.0/rg;
+ ra2inv = 1.0/rasq;
+ rb2inv = 1.0/rbsq;
+ rabinv = sqrt(ra2inv*rb2inv);
- // c0 calculation
-
- sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
- sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
- sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
-
- rb1 = sqrt(sb1);
- rb3 = sqrt(sb3);
-
- c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
-
- // 1st and 2nd angle
-
- b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
- b1mag = sqrt(b1mag2);
- b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
- b2mag = sqrt(b2mag2);
- b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
- b3mag = sqrt(b3mag2);
-
- ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
- r12c1 = 1.0 / (b1mag*b2mag);
- c1mag = ctmp * r12c1;
-
- ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
- r12c2 = 1.0 / (b2mag*b3mag);
- c2mag = ctmp * r12c2;
-
- // cos and sin of 2 angles and final c
-
- sc1 = sqrt(1.0 - c1mag*c1mag);
- if (sc1 < SMALL) sc1 = SMALL;
- sc1 = 1.0/sc1;
-
- sc2 = sqrt(1.0 - c2mag*c2mag);
- if (sc2 < SMALL) sc2 = SMALL;
- sc2 = 1.0/sc2;
-
- s1 = sc1 * sc1;
- s2 = sc2 * sc2;
- s12 = sc1 * sc2;
- c = (c0 + c1mag*c2mag) * s12;
+ c = (ax*bx + ay*by + az*bz)*rabinv;
+ s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z);
// error check
@@ -176,68 +158,58 @@
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
-
- // force & energy
- // p = 1 + cos(n*phi) for d = 1
- // p = 1 - cos(n*phi) for d = -1
- // pd = dp/dc / 2
-
+
m = multiplicity[type];
-
- if (m == 2) {
- p = 2.0*c*c;
- pd = 2.0*c;
- } else if (m == 3) {
- rc2 = c*c;
- p = (4.0*rc2-3.0)*c + 1.0;
- pd = 6.0*rc2 - 1.5;
- } else if (m == 4) {
- rc2 = c*c;
- p = 8.0*(rc2-1)*rc2 + 2.0;
- pd = (16.0*rc2-8.0)*c;
- } else if (m == 6) {
- rc2 = c*c;
- p = ((32.0*rc2-48.0)*rc2 + 18.0)*rc2;
- pd = (96.0*(rc2-1.0)*rc2 + 18.0)*c;
- } else if (m == 1) {
- p = c + 1.0;
- pd = 0.5;
- } else if (m == 5) {
- rc2 = c*c;
- p = ((16.0*rc2-20.0)*rc2 + 5.0)*c + 1.0;
- pd = (40.0*rc2-30.0)*rc2 + 2.5;
- } else if (m == 0) {
- p = 2.0;
- pd = 0.0;
- }
+ p = 1.0;
+ df1 = 0.0;
- if (sign[type] == -1) {
- p = 2.0 - p;
- pd = -pd;
+ for (i = 0; i < m; i++) {
+ ddf1 = p*c - df1*s;
+ df1 = p*s + df1*c;
+ p = ddf1;
}
- if (eflag) energy += rfactor * k[type] * p;
-
- a = 2.0 * k[type] * pd;
- c = c * a;
- s12 = s12 * a;
- a11 = (-c*sb1*s1);
- a22 = sb2*(2.0*c0*s12 - c*(s1+s2));
- a33 = (-c*sb3*s2);
- a12 = r12c1*(c1mag*c*s1 + c2mag*s12);
- a13 = rb1*rb3*s12;
- a23 = r12c2*(-c2mag*c*s2 - c1mag*s12);
-
- sx1 = a11*vb1x + a12*vb2x + a13*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;
- sy12 = a13*vb1y + a23*vb2y + a33*vb3y;
- sz1 = a11*vb1z + a12*vb2z + a13*vb3z;
- sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
- sz12 = a13*vb1z + a23*vb2z + a33*vb3z;
+ p = p*cos_shift[type] + df1*sin_shift[type];
+ df1 = df1*cos_shift[type] - ddf1*sin_shift[type];
+ df1 *= -m;
+ p += 1.0;
+
+ if (m == 0) {
+ p = 1.0 + cos_shift[type];
+ df1 = 0.0;
+ }
+ if (eflag) energy += rfactor * k[type] * p;
+
+ fg = vb1x*vb2xm + vb1y*vb2ym + vb1z*vb2zm;
+ hg = vb3x*vb2xm + vb3y*vb2ym + vb3z*vb2zm;
+ fga = fg*ra2inv*rginv;
+ hgb = hg*rb2inv*rginv;
+ gaa = -ra2inv*rg;
+ gbb = rb2inv*rg;
+
+ dtfx = gaa*ax;
+ dtfy = gaa*ay;
+ dtfz = gaa*az;
+ dtgx = fga*ax - hgb*bx;
+ dtgy = fga*ay - hgb*by;
+ dtgz = fga*az - hgb*bz;
+ dthx = gbb*bx;
+ dthy = gbb*by;
+ dthz = gbb*bz;
+
+ df = k[type] * df1;
+
+ sx1 = df*dtfx;
+ sy1 = df*dtfy;
+ sz1 = df*dtfz;
+ sx2 = -df*dtgx;
+ sy2 = -df*dtgy;
+ sz2 = -df*dtgz;
+ sx12 = df*dthx;
+ sy12 = df*dthy;
+ sz12 = df*dthz;
+
// apply force to each of 4 atoms
if (newton_bond || i1 < nlocal) {
@@ -288,6 +260,10 @@
sign = (int *) memory->smalloc((n+1)*sizeof(double),"dihedral:sign");
multiplicity = (int *)
memory->smalloc((n+1)*sizeof(double),"dihedral:multiplicity");
+ cos_shift = (double *)
+ memory->smalloc((n+1)*sizeof(double),"dihedral:cos_shift");
+ sin_shift = (double *)
+ memory->smalloc((n+1)*sizeof(double),"dihedral:sin_shift");
setflag = (int *) memory->smalloc((n+1)*sizeof(int),"dihedral:setflag");
for (int i = 1; i < n; i++) setflag[i] = 0;
@@ -310,15 +286,26 @@
int sign_one = atoi(arg[2]);
int multiplicity_one = atoi(arg[3]);
+ // require sign = +/- 1 for backwards compatibility
+ // arbitrary phase angle shift could be allowed, but would break
+ // backwards compatibility and is probably not needed
+
if (sign_one != -1 && sign_one != 1)
- error->all("Incorrect args for dihedral coefficients");
- if (multiplicity_one < 0 || multiplicity_one > 6)
- error->all("Incorrect args for dihedral coefficients");
-
+ error->all("Incorrect sign arg for dihedral coefficients");
+ if (multiplicity_one < 0)
+ error->all("Incorrect multiplicity arg for dihedral coefficients");
+
int count = 0;
for (int i = ilo; i <= ihi; i++) {
k[i] = k_one;
sign[i] = sign_one;
+ if (sign[i] == 1) {
+ cos_shift[i] = 1;
+ sin_shift[i] = 0;
+ } else {
+ cos_shift[i] = -1;
+ sin_shift[i] = 0;
+ }
multiplicity[i] = multiplicity_one;
setflag[i] = 1;
count++;
@@ -354,6 +341,15 @@
MPI_Bcast(&k[1],atom->ndihedraltypes,MPI_DOUBLE,0,world);
MPI_Bcast(&sign[1],atom->ndihedraltypes,MPI_INT,0,world);
MPI_Bcast(&multiplicity[1],atom->ndihedraltypes,MPI_INT,0,world);
-
- for (int i = 1; i <= atom->ndihedraltypes; i++) setflag[i] = 1;
+
+ for (int i = 1; i <= atom->ndihedraltypes; i++) {
+ setflag[i] = 1;
+ if (sign[i] == 1) {
+ cos_shift[i] = 1;
+ sin_shift[i] = 0;
+ } else {
+ cos_shift[i] = -1;
+ sin_shift[i] = 0;
+ }
+ }
}
--- /home/sjplimp/oldlammps/src/MOLECULE/dihedral_harmonic.h 2005-11-09 15:08:07.000000000 -0700
+++ /home/sjplimp/lammps/src/MOLECULE/dihedral_harmonic.h 2005-12-07 10:10:35.000000000 -0700
@@ -27,7 +27,7 @@
void read_restart(FILE *);
private:
- double *k;
+ double *k,*cos_shift,*sin_shift;
int *sign,*multiplicity;
void allocate();