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

This commit is contained in:
sjplimp 2009-02-06 21:25:44 +00:00
parent d04d8d340f
commit c256d71951
2 changed files with 239 additions and 571 deletions

View File

@ -176,16 +176,16 @@ void PairREAX::compute(int eflag, int vflag)
// LAMMPS eVDWL energy does not include the Coulomb energy in ReaxFF
evdwl = evdwl - reax_energy_pieces[11];
evdwl = evdwl - reax_energy_pieces[11];
// LAMMPS eCOUL energy includes the Coulomb energy and
// charge equilibation energy
ecoul = reax_energy_pieces[11] + energy_charge_equilibration;
eng_vdwl += evdwl;
eng_coul += ecoul;
}
// LAMMPS eCOUL energy includes the Coulomb energy and
// charge equilibation energy
ecoul = reax_energy_pieces[11] + energy_charge_equilibration;
eng_vdwl += evdwl;
eng_coul += ecoul;
}
int nval, ntor, nhb, nbonall, nbon, na, na_local, nvpair;
int reaxsize[8];
@ -265,267 +265,6 @@ void PairREAX::write_reax_positions()
/* ---------------------------------------------------------------------- */
void PairREAX::write_reax_vlist()
{
double **x = atom->x;
int *type = atom->type;
int *tag = atom->tag;
int nlocal, nghost;
nlocal = atom->nlocal;
nghost = atom->nghost;
int inum, jnum;
int *ilist;
int *jlist;
int *numneigh, **firstneigh;
double xitmp, yitmp, zitmp;
double xjtmp, yjtmp, zjtmp;
int itype, jtype, itag, jtag;
int ii, jj, i, j, iii, jjj;
int nvpair, nvlself, nvpairmax;
int nbond;
double delr2;
double delx, dely, delz;
double rtmp[3];
nvpairmax = ReaxParams::nneighmax * ReaxParams::nat;
nvpair = 0;
nvlself =0;
nbond = 0;
inum = list->inum;
ilist = list->ilist;
numneigh = list->numneigh;
firstneigh = list->firstneigh;
for (ii = 0; ii < inum; ii++)
{
i = ilist[ii]; // the local index for the ii th atom having neighbors
xitmp = x[i][0];
yitmp = x[i][1];
zitmp = x[i][2];
itype = type[i];
itag = tag[i];
jlist = firstneigh[i];
jnum = numneigh[i];
for (jj = 0; jj < jnum; jj++)
{
j = jlist[jj];
xjtmp = x[j][0];
yjtmp = x[j][1];
zjtmp = x[j][2];
jtype = type[j];
jtag = tag[j];
delx = xitmp - xjtmp;
dely = yitmp - yjtmp;
delz = zitmp - zjtmp;
delr2 = delx*delx+dely*dely+delz*delz;
if (delr2 <= rcutvsq)
{
// Avoid the double check for the vpairs
if (i < j)
{
// Index for the FORTRAN array
iii = i+1;
jjj = j+1;
}
else
{
iii = j+1;
jjj = i+1;
}
if (nvpair >= nvpairmax)
{
break;
}
FORTRAN(cbkpairs, CBKPAIRS).nvl1[nvpair] = iii;
FORTRAN(cbkpairs, CBKPAIRS).nvl2[nvpair] = jjj;
FORTRAN(cbknvlbo, CBKNVLBO).nvlbo[nvpair] = 0;
if (delr2 <= rcutbsq)
{
FORTRAN(cbknvlbo, CBKNVLBO).nvlbo[nvpair] = 1;
nbond++;
}
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 0;
// Midpoint check
if (Lmidpoint)
{
/* {
if (jjj <= nlocal)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
else
{
rtmp[0] = 0.5*(xitmp + xjtmp);
rtmp[1] = 0.5*(yitmp + yjtmp);
rtmp[2] = 0.5*(zitmp + zjtmp);
if (sub_check_strict(rtmp))
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] =1;
}
}
}*/
}
else
{
if (i < nlocal)
{
if (j < nlocal)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
else if (itag < jtag)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
else if (itag == jtag)
{
if (delz > SMALL)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
else if (fabs(delz) < SMALL)
{
if (dely > SMALL)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
else if (fabs(dely) < SMALL)
{
if (delx > SMALL)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
}
}
}
}
}
nvpair++;
}
}
}
for (int i = nlocal; i < nlocal + nghost; i++)
{
xitmp = x[i][0];
yitmp = x[i][1];
zitmp = x[i][2];
itype = type[i];
itag = tag[i];
for (int j = i+1; j < nlocal + nghost; j++)
{
xjtmp = x[j][0];
yjtmp = x[j][1];
zjtmp = x[j][2];
jtype = type[j];
jtag = tag[j];
delx = xitmp - xjtmp;
dely = yitmp - yjtmp;
delz = zitmp - zjtmp;
delr2 = delx*delx+dely*dely+delz*delz;
// Don't need to check the double count since i < j in the ghost region
if (delr2 <= rcutvsq)
{
{
iii = i+1;
jjj = j+1;
}
if (nvpair >= nvpairmax)
{
break;
}
FORTRAN(cbkpairs, CBKPAIRS).nvl1[nvpair] = iii;
FORTRAN(cbkpairs, CBKPAIRS).nvl2[nvpair] = jjj;
FORTRAN(cbknvlbo, CBKNVLBO).nvlbo[nvpair] = 0;
if (delr2 <= rcutbsq)
{
FORTRAN(cbknvlbo, CBKNVLBO).nvlbo[nvpair] = 1;
nbond++;
}
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 0;
if (Lmidpoint)
{
/* if (jjj <= nlocal)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
else
{
rtmp[0] = 0.5*(xitmp + xjtmp);
rtmp[1] = 0.5*(yitmp + yjtmp);
rtmp[2] = 0.5*(zitmp + zjtmp);
if (sub_check_strict(rtmp))
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] =1;
}
}*/
}
else
{
if (i < nlocal)
{
if (j < nlocal)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
else if (itag < jtag)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
else if (itag == jtag)
{
if (delz > SMALL)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
else if (fabs(delz) < SMALL)
{
if (dely > SMALL)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
else if (fabs(dely) < SMALL)
{
if (delx > SMALL)
{
FORTRAN(cbknvlown, CBKNVLOWN).nvlown[nvpair] = 1;
}
}
}
}
}
}
nvpair++;
}
}
}
FORTRAN(cbkpairs, CBKPAIRS).nvpair = nvpair;
FORTRAN(cbkpairs, CBKPAIRS).nvlself = nvlself;
}
/*
void PairREAX::write_reax_vlist()
{
int ii, jj, i, j, iii, jjj;
@ -622,8 +361,8 @@ void PairREAX::write_reax_vlist()
}
}
}
nvpair++;
}
nvpair++;
}
}
@ -686,16 +425,15 @@ void PairREAX::write_reax_vlist()
}
}
}
nvpair++;
}
nvpair++;
}
}
FORTRAN(cbkpairs, CBKPAIRS).nvpair = nvpair;
FORTRAN(cbkpairs, CBKPAIRS).nvlself = nvlself;
}
*/
/* ---------------------------------------------------------------------- */
void PairREAX::read_reax_forces()
@ -788,16 +526,11 @@ void PairREAX::coeff(int narg, char **arg)
if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
error->all("Incorrect args for pair coefficients");
// Clear setflag since coeff() called once with I,J = * *
int n = atom->ntypes;
int n = atom->ntypes;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
// set setflag i,j for type pairs where both are mapped to elements
// set mass for i,i in atom class
int count = 0;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++) {
@ -966,8 +699,7 @@ void PairREAX::taper_setup()
double PairREAX::taper_E(const double &r, const double &r2)
{
double r3;
r3=r2*r;
double r3=r2*r;
return swc7*r3*r3*r+swc6*r3*r3+swc5*r3*r2+swc4*r2*r2+swc3*r3+swc2*r2+
swc1*r+swc0;
}
@ -976,8 +708,7 @@ double PairREAX::taper_E(const double &r, const double &r2)
double PairREAX::taper_F(const double &r, const double &r2)
{
double r3;
r3=r2*r;
double r3=r2*r;
return 7.0e0*swc7*r3*r3+6.0e0*swc6*r3*r2+5.0e0*swc5*r2*r2+
4.0e0*swc4*r3+3.0e0*swc3*r2+2.0e0*swc2*r+swc1;
}
@ -988,21 +719,6 @@ double PairREAX::taper_F(const double &r, const double &r2)
void PairREAX::compute_charge(double &energy_charge_equilibration)
{
double **x = atom->x;
int *type = atom->type;
int *tag = atom->tag;
double *q = atom->q;
int nlocal = atom->nlocal;
int nghost = atom->nghost;
int inum, jnum;
int *ilist;
int *jlist;
int *numneigh, **firstneigh;
double xitmp, yitmp, zitmp;
double xjtmp, yjtmp, zjtmp;
@ -1023,6 +739,19 @@ void PairREAX::compute_charge(double &energy_charge_equilibration)
double sw;
double rtmp[3];
double **x = atom->x;
double *q = atom->q;
int *type = atom->type;
int *tag = atom->tag;
int nlocal = atom->nlocal;
int nghost = atom->nghost;
int inum, jnum;
int *ilist;
int *jlist;
int *numneigh, **firstneigh;
node = comm -> me;
inum = list->inum;
ilist = list->ilist;
@ -1031,9 +760,7 @@ void PairREAX::compute_charge(double &energy_charge_equilibration)
int numneigh_total = 0;
for (ii =0; ii < inum; ii++)
{
numneigh_total += numneigh[ilist[ii]];
}
numneigh_total += numneigh[ilist[ii]];
arow_ptr = new int[nlocal+nghost+1];
ch = new double[nlocal+nghost+1];
@ -1043,146 +770,128 @@ void PairREAX::compute_charge(double &energy_charge_equilibration)
acol_ind = new int[maxmatentries];
nmatentries = 0;
// Construct a linear system for this processor
for (ii =0; ii<inum; ii++)
{
i = ilist[ii];
xitmp = x[i][0];
yitmp = x[i][1];
zitmp = x[i][2];
itype = type[i];
itag = tag[i];
jlist = firstneigh[i];
jnum = numneigh[i];
// build linear system
// Caution : index of i and ii
arow_ptr[i] = nmatentries;
aval[nmatentries] = 2.0*param_list[itype].params[1];
// Caution : index of i and ii
acol_ind[nmatentries] = i;
for (ii =0; ii<inum; ii++) {
i = ilist[ii];
xitmp = x[i][0];
yitmp = x[i][1];
zitmp = x[i][2];
itype = type[i];
itag = tag[i];
jlist = firstneigh[i];
jnum = numneigh[i];
arow_ptr[i] = nmatentries;
aval[nmatentries] = 2.0*param_list[itype].params[1];
acol_ind[nmatentries] = i;
nmatentries++;
aval[nmatentries] = 1.0;
acol_ind[nmatentries] = nlocal + nghost;
nmatentries++;
for (jj = 0; jj < jnum; jj++) {
j = jlist[jj];
xjtmp = x[j][0];
yjtmp = x[j][1];
zjtmp = x[j][2];
jtype = type[j];
jtag = tag[j];
delx = xitmp - xjtmp;
dely = yitmp - yjtmp;
delz = zitmp - zjtmp;
delr2 = delx*delx+dely*dely+delz*delz;
// ReaxFF uses half neigh list with newton off
// in charge equil, local-ghost pair should be stored only on one proc
// thus filtering is necessary when local-ghost pair is counted twice
nmatentries++;
aval[nmatentries] = 1.0;
acol_ind[nmatentries] = nlocal + nghost;
nmatentries++;
for (jj = 0; jj < jnum; jj++)
{
j = jlist[jj];
xjtmp = x[j][0];
yjtmp = x[j][1];
zjtmp = x[j][2];
jtype = type[j];
jtag = tag[j];
delx = xitmp - xjtmp;
dely = yitmp - yjtmp;
delz = zitmp - zjtmp;
delr2 = delx*delx+dely*dely+delz*delz;
// We did construct half neighbor list with no Newton flag for ReaxFF
// However, in Charge Equilibration, local-ghost pair should be stored only in one processor
// So, filtering is necessary when local-ghost pair is counted twice
neighbor->style;
if (j >= nlocal)
{
if (neighbor->style==0)
{
if (itag > jtag)
{
if ((itag+jtag) % 2 == 0) continue;
}
else if (itag < jtag)
{
if ((itag+jtag) % 2 == 1) continue;
}
else
if (j >= nlocal) {
if (neighbor->style==0)
{
if (itag > jtag)
{
if ((itag+jtag) % 2 == 0) continue;
}
else if (itag < jtag)
{
if ((itag+jtag) % 2 == 1) continue;
}
else
// if (itag == jtag)
{
if (zjtmp < zitmp) continue;
else if (zjtmp == zitmp && yjtmp < yitmp) continue;
else if (zjtmp == zitmp && yjtmp == yitmp && xjtmp < xitmp)
continue;
}
}
else if (neighbor->style==1)
{
if (zjtmp < zitmp) continue;
else if (zjtmp == zitmp && yjtmp < yitmp) continue;
else if (zjtmp == zitmp && yjtmp == yitmp && xjtmp < xitmp)
continue;
}
else
{
error->all("ReaxFF does not support multi style neiborlist");
}
}
// rcutvsq = cutmax*cutmax, in ReaxFF
if (delr2 <= rcutvsq)
{
gamt = sqrt(param_list[itype].params[2]*
param_list[jtype].params[2]);
delr_norm = sqrt(delr2);
sw = taper_E(delr_norm, delr2);
hulp1=(delr_norm*delr2+(1.0/(gamt*gamt*gamt)));
hulp2=sw*14.40/cbrt(hulp1);
aval[nmatentries] = hulp2;
acol_ind[nmatentries] = j;
nmatentries++;
}
{
if (zjtmp < zitmp) continue;
else if (zjtmp == zitmp && yjtmp < yitmp) continue;
else if (zjtmp == zitmp && yjtmp == yitmp && xjtmp < xitmp)
continue;
}
}
else if (neighbor->style==1)
{
if (zjtmp < zitmp) continue;
else if (zjtmp == zitmp && yjtmp < yitmp) continue;
else if (zjtmp == zitmp && yjtmp == yitmp && xjtmp < xitmp)
continue;
}
else
{
error->all("ReaxFF does not support multi style neiborlist");
}
}
// rcutvsq = cutmax*cutmax, in ReaxFF
if (delr2 <= rcutvsq)
{
gamt = sqrt(param_list[itype].params[2]*
param_list[jtype].params[2]);
delr_norm = sqrt(delr2);
sw = taper_E(delr_norm, delr2);
hulp1=(delr_norm*delr2+(1.0/(gamt*gamt*gamt)));
hulp2=sw*14.40/cbrt(hulp1);
aval[nmatentries] = hulp2;
acol_ind[nmatentries] = j;
nmatentries++;
}
}
}
// In this case, we don't use Midpoint method
// So, we don't need to consider ghost-ghost interactions
// But, need to fill the arow_ptr[] arrays for the ghost atoms
for (i = nlocal; i < nlocal+nghost; i++)
{
arow_ptr[i] = nmatentries;
}
for (i = nlocal; i < nlocal+nghost; i++)
arow_ptr[i] = nmatentries;
arow_ptr[nlocal+nghost] = nmatentries;
// Add rhs matentries to linear system
// add rhs matentries to linear system
for (ii =0; ii<inum; ii++)
{
i = ilist[ii];
itype = type[i];
elcvec[i] = -param_list[itype].params[0];
}
for (ii =0; ii<inum; ii++) {
i = ilist[ii];
itype = type[i];
elcvec[i] = -param_list[itype].params[0];
}
for (i = nlocal; i < nlocal+nghost; i++)
{
elcvec[i] = 0.0;
}
for (i = nlocal; i < nlocal+nghost; i++) elcvec[i] = 0.0;
// Assign current charges to charge vector
qsum = 0.0;
for (ii =0; ii<inum; ii++)
{
i = ilist[ii];
qi = q[i];
ch[i] = qi;
if (i<nlocal)
{
qsum += qi;
}
}
for (i = nlocal; i < nlocal+nghost; i++)
{
qi = q[i];
ch[i] = qi;
if (i<nlocal)
{
qsum += qi;
}
}
qsum = 0.0;
for (ii =0; ii<inum; ii++) {
i = ilist[ii];
qi = q[i];
ch[i] = qi;
if (i<nlocal) qsum += qi;
}
for (i = nlocal; i < nlocal+nghost; i++) {
qi = q[i];
ch[i] = qi;
if (i<nlocal) qsum += qi;
}
double qtot;
@ -1190,40 +899,39 @@ void PairREAX::compute_charge(double &energy_charge_equilibration)
elcvec[nlocal+nghost] = 0.0;
ch[nlocal+nghost] = chpot;
// Solve the linear system using CG sover
// solve the linear system using CG sover
charge_reax(nlocal, nghost, ch, aval, acol_ind, arow_ptr, elcvec);
// Calculate the charge equilibration energy
// calculate the charge equilibration energy
energy_charge_equilibration = 0;
// We already have the updated charge distributions for the current structure
for (ii = 0; ii < inum; ii++)
{
i = ilist[ii];
itype = type[i];
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
itype = type[i];
// 23.02 is the ReaxFF conversion from eV to kcal/mol
// Should really use constants.evfactor ~ 23.06, but
// that would break consistency with serial ReaxFF code.
qi = 23.02 * (param_list[itype].params[0]*ch[i]+
param_list[itype].params[1]*ch[i]*ch[i]);
energy_charge_equilibration += qi;
}
qi = 23.02 * (param_list[itype].params[0]*ch[i]+
param_list[itype].params[1]*ch[i]*ch[i]);
energy_charge_equilibration += qi;
}
// Copy charge vector back to particles from the calculated values
for (i = 0; i < nlocal+nghost; i++)
{
q[i] = ch[i];
}
for (i = 0; i < nlocal+nghost; i++) q[i] = ch[i];
chpot = ch[nlocal+nghost];
delete []aval;
delete []arow_ptr;
delete []elcvec;
delete []ch;
delete []acol_ind;
delete [] aval;
delete [] arow_ptr;
delete [] elcvec;
delete [] ch;
delete [] acol_ind;
}
/* ---------------------------------------------------------------------- */
@ -1277,97 +985,70 @@ void PairREAX::cg_solve(const int & nlocal, const int & nghost,
zero = 0.0;
maxiter = 100;
// For w1, need to zero
for (int i = 0; i < n; i++)
{
w[i] = 0;
}
for (int i = 0; i < n; i++) w[i] = 0;
// Construct r = b-Ax
// construct r = b-Ax
sparse_product(n, nlocal, nghost, aval, acol_ind, arow_ptr, x, r);
// We will not use BLAS library
for (int i=0; i<n; i++)
{
r[i] = b[i] - r[i];
w[i] = r[i];
}
for (int i=0; i<n; i++) {
r[i] = b[i] - r[i];
w[i] = r[i];
}
comm -> reverse_comm_pair(this);
comm -> comm_pair(this);
comm->reverse_comm_pair(this);
comm->comm_pair(this);
MPI_Allreduce(&w[n-1], &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
w[n-1] = sumtmp;
rho_old = one;
for (iter = 1; iter < maxiter; iter++)
{
rho = 0.0;
for (int i=0; i<nlocal; i++)
{
rho += w[i]*w[i];
}
for (iter = 1; iter < maxiter; iter++) {
rho = 0.0;
for (int i=0; i<nlocal; i++) rho += w[i]*w[i];
MPI_Allreduce(&rho, &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
rho = sumtmp + w[n-1]*w[n-1];
MPI_Allreduce(&rho, &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
rho = sumtmp + w[n-1]*w[n-1];
if (rho < precision) break;
if (rho < precision) break;
for (int i = 0; i<n; i++) p[i] = w[i];
for (int i = 0; i<n; i++)
{
p[i] = w[i];
}
if (iter > 1)
{
beta = rho/rho_old;
for (int i = 0; i<n; i++)
{
p[i] += beta*p_old[i];
}
}
sparse_product(n, nlocal, nghost, aval, acol_ind, arow_ptr, p, q);
gamma = 0.0;
for (int i=0; i<n; i++)
{
gamma += p[i]*q[i];
}
MPI_Allreduce(&gamma, &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
gamma = sumtmp;
alpha = rho/gamma;
for (int i=0; i<n; i++)
{
x[i] += alpha*p[i];
r[i] -= alpha*q[i];
w[i] = r[i];
}
comm -> reverse_comm_pair(this);
comm -> comm_pair(this);
MPI_Allreduce(&w[n-1], &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
w[n-1] = sumtmp;
for (int i=0; i<n; i++)
{
p_old[i] = p[i];
}
rho_old = rho;
if (iter > 1) {
beta = rho/rho_old;
for (int i = 0; i<n; i++) p[i] += beta*p_old[i];
}
sparse_product(n, nlocal, nghost, aval, acol_ind, arow_ptr, p, q);
gamma = 0.0;
for (int i=0; i<n; i++) gamma += p[i]*q[i];
MPI_Allreduce(&gamma, &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
gamma = sumtmp;
alpha = rho/gamma;
for (int i=0; i<n; i++) {
x[i] += alpha*p[i];
r[i] -= alpha*q[i];
w[i] = r[i];
}
comm->reverse_comm_pair(this);
comm->comm_pair(this);
MPI_Allreduce(&w[n-1], &sumtmp, 1, MPI_DOUBLE, MPI_SUM, world);
w[n-1] = sumtmp;
for (int i=0; i<n; i++) p_old[i] = p[i];
rho_old = rho;
}
delete []r;
delete []p;
delete []p_old;
delete []q;
delete [] r;
delete [] p;
delete [] p_old;
delete [] q;
}
/* ----------------------------------------------------------------------
@ -1379,34 +1060,33 @@ void PairREAX::sparse_product(const int & n, const int & nlocal,
double aval[], int acol_ind[], int arow_ptr[],
double x[], double r[])
{
int jj;
for (int i=0; i<n; i++)
{
r[i] = 0.0;
}
int i,j,jj;
// Loop over local particle matentries
for (int i=0; i<nlocal; i++)
{
// Diagonal terms
r[i]+=aval[arow_ptr[i]]*x[i];
// Loop over remaining matrix entries and transposes
for (int j=arow_ptr[i]+1; j<arow_ptr[i+1]; j++)
{
jj = acol_ind[j];
r[i] += aval[j]*x[jj];
r[jj] += aval[j]*x[i];
}
}
for (i=0; i<n; i++) r[i] = 0.0;
// Loop over ghost particle matentries
for (int i=nlocal; i<nlocal+nghost; i++)
{
for (int j=arow_ptr[i]; j<arow_ptr[i+1]; j++)
{
jj = acol_ind[j];
r[i] += aval[j]*x[jj];
r[jj] += aval[j]*x[i];
}
// loop over local particle matentries
for (i=0; i<nlocal; i++) {
// diagonal terms
r[i] += aval[arow_ptr[i]]*x[i];
// loop over remaining matrix entries and transposes
for (j=arow_ptr[i]+1; j<arow_ptr[i+1]; j++) {
jj = acol_ind[j];
r[i] += aval[j]*x[jj];
r[jj] += aval[j]*x[i];
}
}
// loop over ghost particle matentries
for (i=nlocal; i<nlocal+nghost; i++)
for (j=arow_ptr[i]; j<arow_ptr[i+1]; j++) {
jj = acol_ind[j];
r[i] += aval[j]*x[jj];
r[jj] += aval[j]*x[i];
}
}

View File

@ -35,31 +35,11 @@ class PairREAX : public Pair {
void unpack_reverse_comm(int, int *, double *);
private:
double cutmax; // max cutoff for all elements
void allocate();
void read_files(char *, char *);
void neigh_f2c(int, int *, int *, int **);
void neigh_c2f(int, int *, int *, int **);
// For ReaxFF Verlet list
double rcutvsq, rcutbsq;
double cutmax;
double rcutvsq,rcutbsq;
int iprune,ihb;
// For the midpoint method in REAX
bool Lmidpoint;
// Cutoff for hydrogen bond, Taper value for Coulomb interactions
double hbcut,swb;
void write_reax_positions(); // particle positions into reax fortran
void write_reax_vlist(); // Verlet neighbor lists into reax fortran
void read_reax_forces(); // forces in reax fortran into LAMMPS
void read_reax_atom_virial(); // virial stress per atom in reax fortran into LAMMPS
// For charge equilibration
double swa;
double swc0, swc1, swc2, swc3, swc4, swc5, swc6, swc7;
double precision;
@ -67,9 +47,18 @@ class PairREAX : public Pair {
ff_params* param_list;
int nentries;
double chpot;
// For communication of w[i] in CG solve
double *w;
void allocate();
void read_files(char *, char *);
void neigh_f2c(int, int *, int *, int **);
void neigh_c2f(int, int *, int *, int **);
void write_reax_positions();
void write_reax_vlist();
void read_reax_forces();
void read_reax_atom_virial();
void taper_setup();
double taper_E(const double &, const double &);
double taper_F(const double &, const double &);
@ -79,7 +68,6 @@ class PairREAX : public Pair {
int[], int[], double[], double[]);
void cg_solve(const int &, const int &, double[], int[],
int[], double[], double[]);
void charge_reax(const int &, const int &, double[],
double[], int[], int[], double[]);
};