/* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software. This software is distributed under the GNU General Public License. See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ #include "lmptype.h" #include "math.h" #include "stdlib.h" #include "string.h" #include "fix_replica.h" #include "atom.h" #include "update.h" #include "force.h" #include "pair.h" #include "neighbor.h" #include "neigh_request.h" #include "neigh_list.h" #include "comm.h" #include "domain.h" #include "lattice.h" #include "region.h" #include "group.h" #include "memory.h" #include "error.h" using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ FixReplica::FixReplica(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) { if (narg < 5) error->all("Illegal fix replica command"); nmax = 0; iregion = -1; idregion = NULL; int iarg = 3; while (iarg < narg) { if (strcmp(arg[iarg],"region") == 0) { if (iarg+2 > narg) error->all("Illegal fix replica command"); iregion = domain->find_region(arg[iarg+1]); if (iregion == -1) error->all("Region ID for fix replica does not exist"); int n = strlen(arg[iarg+1]) + 1; idregion = new char[n]; strcpy(idregion,arg[iarg+1]); iarg += 2; } else error->all("Illegal fix replica command"); } xlo = domain->regions[iregion]->extent_xlo; xhi = domain->regions[iregion]->extent_xhi; ylo = domain->regions[iregion]->extent_ylo; yhi = domain->regions[iregion]->extent_yhi; zlo = domain->regions[iregion]->extent_zlo; zhi = domain->regions[iregion]->extent_zhi; } /* ---------------------------------------------------------------------- */ FixReplica::~FixReplica() { delete [] idregion; } /* ---------------------------------------------------------------------- */ int FixReplica::setmask() { int mask = 0; mask |= POST_FORCE; return mask; } /* ---------------------------------------------------------------------- */ void FixReplica::init() { if (iregion >= 0) { iregion = domain->find_region(idregion); if (iregion == -1) error->all("Region ID for fix replica does not exist"); } } /* ---------------------------------------------------------------------- */ void FixReplica::post_force(int vflag) { int i,j,ii,jj,inum,jnum,itype,jtype; double xtmp,ytmp,ztmp,delx,dely,delz,evdwl,fpair; double rsq,r2inv,r6inv,forcelj,factor_lj,factor_coul,eng; int *ilist,*jlist,*numneigh,**firstneigh; int irequest = neighbor->request((void *) this); neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->fix = 1; neighbor->requests[irequest]->half = 0; neighbor->requests[irequest]->full = 1; if (force->pair == NULL) error->all("Delete_atoms requires a pair style be defined"); NeighList *list = neighbor->lists[irequest]; neighbor->build_one(irequest); double **x = atom->x; double **f = atom->f; int *type = atom->type; int *mask = atom->mask; int nlocal = atom->nlocal; double *special_lj = force->special_lj; double *special_coul = force->special_coul; int newton_pair = force->newton_pair; Pair *pair = force->pair; double **cutsq = force->pair->cutsq; inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; // loop over neighbors of my atoms for (ii = 0; ii < inum; ii++) { i = ilist[ii]; xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; itype = type[i]; jlist = firstneigh[i]; jnum = numneigh[i]; for (jj = 0; jj < jnum; jj++) { j = jlist[jj]; factor_lj = special_lj[sbmask(j)]; factor_coul = special_coul[sbmask(j)]; j &= NEIGHMASK; if ( mask[i] & groupbit && domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]) && mask[j] & groupbit && domain->regions[iregion]->match(x[j][0],x[j][1],x[j][2]) ) { delx = xtmp - x[j][0] + (xhi-xlo); 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]) { eng = pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fpair); f[i][0] += delx*fpair; f[i][1] += dely*fpair; f[i][2] += delz*fpair; } } } } }