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

This commit is contained in:
sjplimp 2015-01-30 22:22:27 +00:00
parent 8d657c5391
commit cef3a9da47
6 changed files with 252 additions and 210 deletions

View File

@ -75,6 +75,7 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
extended = orientflag = dorientflag = 0;
body = NULL;
xcmimage = NULL;
displace = NULL;
eflags = NULL;
orient = NULL;
@ -352,7 +353,8 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
} else if (strcmp(arg[iarg],"temp") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/nvt") != 0 && strcmp(style,"rigid/npt") != 0 &&
strcmp(style,"rigid/nvt/omp") != 0 && strcmp(style,"rigid/npt/omp") != 0)
strcmp(style,"rigid/nvt/omp") != 0 &&
strcmp(style,"rigid/npt/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
tstat_flag = 1;
t_start = force->numeric(FLERR,arg[iarg+1]);
@ -363,8 +365,9 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
} else if (strcmp(arg[iarg],"iso") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
strcmp(style,"rigid/npt/omp") != 0 && strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
strcmp(style,"rigid/npt/omp") != 0 &&
strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
pcouple = XYZ;
p_start[0] = p_start[1] = p_start[2] = force->numeric(FLERR,arg[iarg+1]);
p_stop[0] = p_stop[1] = p_stop[2] = force->numeric(FLERR,arg[iarg+2]);
@ -380,8 +383,9 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
} else if (strcmp(arg[iarg],"aniso") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
strcmp(style,"rigid/npt/omp") != 0 && strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
strcmp(style,"rigid/npt/omp") != 0 &&
strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
p_start[0] = p_start[1] = p_start[2] = force->numeric(FLERR,arg[iarg+1]);
p_stop[0] = p_stop[1] = p_stop[2] = force->numeric(FLERR,arg[iarg+2]);
p_period[0] = p_period[1] = p_period[2] =
@ -396,8 +400,9 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
} else if (strcmp(arg[iarg],"x") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
strcmp(style,"rigid/npt/omp") != 0 && strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
strcmp(style,"rigid/npt/omp") != 0 &&
strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
p_start[0] = force->numeric(FLERR,arg[iarg+1]);
p_stop[0] = force->numeric(FLERR,arg[iarg+2]);
p_period[0] = force->numeric(FLERR,arg[iarg+3]);
@ -407,8 +412,9 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
} else if (strcmp(arg[iarg],"y") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
strcmp(style,"rigid/npt/omp") != 0 && strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
strcmp(style,"rigid/npt/omp") != 0 &&
strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
p_start[1] = force->numeric(FLERR,arg[iarg+1]);
p_stop[1] = force->numeric(FLERR,arg[iarg+2]);
p_period[1] = force->numeric(FLERR,arg[iarg+3]);
@ -418,8 +424,9 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
} else if (strcmp(arg[iarg],"z") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
strcmp(style,"rigid/npt/omp") != 0 && strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
strcmp(style,"rigid/npt/omp") != 0 &&
strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
p_start[2] = force->numeric(FLERR,arg[iarg+1]);
p_stop[2] = force->numeric(FLERR,arg[iarg+2]);
p_period[2] = force->numeric(FLERR,arg[iarg+3]);
@ -456,7 +463,8 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
} else if (strcmp(arg[iarg],"tparam") == 0) {
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/nvt") != 0 && strcmp(style,"rigid/npt") != 0 &&
strcmp(style,"rigid/nvt/omp") != 0 && strcmp(style,"rigid/npt/omp") != 0)
strcmp(style,"rigid/nvt/omp") != 0 &&
strcmp(style,"rigid/npt/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
t_chain = force->inumeric(FLERR,arg[iarg+1]);
t_iter = force->inumeric(FLERR,arg[iarg+2]);
@ -466,7 +474,8 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
} else if (strcmp(arg[iarg],"pchain") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal fix rigid command");
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
strcmp(style,"rigid/npt/omp") != 0 && strcmp(style,"rigid/nph/omp") != 0)
strcmp(style,"rigid/npt/omp") != 0 &&
strcmp(style,"rigid/nph/omp") != 0)
error->all(FLERR,"Illegal fix rigid command");
p_chain = force->inumeric(FLERR,arg[iarg+1]);
iarg += 2;
@ -569,9 +578,10 @@ FixRigid::~FixRigid()
memory->destroy(mol2body);
memory->destroy(body2mol);
// delete locally stored arrays
// delete locally stored per-atom arrays
memory->destroy(body);
memory->destroy(xcmimage);
memory->destroy(displace);
memory->destroy(eflags);
memory->destroy(orient);
@ -675,6 +685,16 @@ void FixRigid::init()
else tfactor = 0.0;
}
/* ----------------------------------------------------------------------
invoke pre_neighbor() to insure body xcmimage flags are reset
needed if Verlet::setup::pbc() has remapped/migrated atoms for 2nd run
------------------------------------------------------------------------- */
void FixRigid::setup_pre_neighbor()
{
pre_neighbor();
}
/* ----------------------------------------------------------------------
compute initial fcm and torque on bodies, also initial virial
reset all particle velocities to be consistent with vcm and omega
@ -716,7 +736,6 @@ void FixRigid::setup(int vflag)
// torque = torque on each rigid body
imageint *image = atom->image;
double **x = atom->x;
double dx,dy,dz;
@ -729,7 +748,7 @@ void FixRigid::setup(int vflag)
if (body[i] < 0) continue;
ibody = body[i];
domain->unmap(x[i],image[i],unwrap);
domain->unmap(x[i],xcmimage[i],unwrap);
dx = unwrap[0] - xcm[ibody][0];
dy = unwrap[1] - xcm[ibody][1];
dz = unwrap[2] - xcm[ibody][2];
@ -780,6 +799,7 @@ void FixRigid::setup(int vflag)
for (ibody = 0; ibody < nbody; ibody++)
MathExtra::angmom_to_omega(angmom[ibody],ex_space[ibody],ey_space[ibody],
ez_space[ibody],inertia[ibody],omega[ibody]);
set_v();
// guesstimate virial as 2x the set_v contribution
@ -897,7 +917,6 @@ void FixRigid::final_integrate()
// sum over atoms to get force and torque on rigid body
imageint *image = atom->image;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
@ -916,7 +935,7 @@ void FixRigid::final_integrate()
sum[ibody][1] += f[i][1];
sum[ibody][2] += f[i][2];
domain->unmap(x[i],image[i],unwrap);
domain->unmap(x[i],xcmimage[i],unwrap);
dx = unwrap[0] - xcm[ibody][0];
dy = unwrap[1] - xcm[ibody][1];
dz = unwrap[2] - xcm[ibody][2];
@ -1005,72 +1024,54 @@ void FixRigid::final_integrate_respa(int ilevel, int iloop)
done during pre_neighbor so will be after call to pbc()
and after fix_deform::pre_exchange() may have flipped box
use domain->remap() in case xcm is far away from box
due to 1st definition of rigid body or due to box flip
if don't do this, then atoms of a body which drifts far away
from a triclinic box will be remapped back into box
with huge displacements when the box tilt changes via set_x()
adjust image flag of body and image flags of all atoms in body
due to first-time definition of rigid body in setup_bodies_static()
or due to box flip
also adjust imagebody = rigid body image flags, due to xcm remap
also reset body xcmimage flags of all atoms in bodies
xcmimage flags are relative to xcm so that body can be unwrapped
if don't do this, would need xcm to move with true image flags
then a body could end up very far away from box
set_xv() will then compute huge displacements every step to
reset coords of all body atoms to be back inside the box,
ditto for triclinic box flip, which causes numeric problems
------------------------------------------------------------------------- */
void FixRigid::pre_neighbor()
{
imageint original,oldimage,newimage;
for (int ibody = 0; ibody < nbody; ibody++) {
original = imagebody[ibody];
for (int ibody = 0; ibody < nbody; ibody++)
domain->remap(xcm[ibody],imagebody[ibody]);
image_shift();
}
if (original == imagebody[ibody]) remapflag[ibody][3] = 0;
else {
oldimage = original & IMGMASK;
newimage = imagebody[ibody] & IMGMASK;
remapflag[ibody][0] = newimage - oldimage;
oldimage = (original >> IMGBITS) & IMGMASK;
newimage = (imagebody[ibody] >> IMGBITS) & IMGMASK;
remapflag[ibody][1] = newimage - oldimage;
oldimage = original >> IMG2BITS;
newimage = imagebody[ibody] >> IMG2BITS;
remapflag[ibody][2] = newimage - oldimage;
remapflag[ibody][3] = 1;
}
}
/* ----------------------------------------------------------------------
reset body xcmimage flags of atoms in bodies
xcmimage flags are relative to xcm so that body can be unwrapped
xcmimage = true image flag - imagebody flag
------------------------------------------------------------------------- */
// adjust image flags of any atom in a rigid body whose xcm was remapped
// subtracting remapflag = new-old keeps ix,iy,iz near 0
// so body is always in central simulation box
void FixRigid::image_shift()
{
int ibody;
imageint tdim,bdim,xdim[3];
imageint *image = atom->image;
int nlocal = atom->nlocal;
int ibody;
imageint idim,otherdims;
for (int i = 0; i < nlocal; i++) {
if (body[i] == -1) continue;
if (remapflag[body[i]][3] == 0) continue;
if (body[i] < 0) continue;
ibody = body[i];
if (remapflag[ibody][0]) {
idim = image[i] & IMGMASK;
otherdims = image[i] ^ idim;
idim -= remapflag[ibody][0];
idim &= IMGMASK;
image[i] = otherdims | idim;
}
if (remapflag[ibody][1]) {
idim = (image[i] >> IMGBITS) & IMGMASK;
otherdims = image[i] ^ (idim << IMGBITS);
idim -= remapflag[ibody][1];
idim &= IMGMASK;
image[i] = otherdims | (idim << IMGBITS);
}
if (remapflag[ibody][2]) {
idim = image[i] >> IMG2BITS;
otherdims = image[i] ^ (idim << IMG2BITS);
idim -= remapflag[ibody][2];
idim &= IMGMASK;
image[i] = otherdims | (idim << IMG2BITS);
}
tdim = image[i] & IMGMASK;
bdim = imagebody[ibody] & IMGMASK;
xdim[0] = IMGMAX + tdim - bdim;
tdim = (image[i] >> IMGBITS) & IMGMASK;
bdim = (imagebody[ibody] >> IMGBITS) & IMGMASK;
xdim[1] = IMGMAX + tdim - bdim;
tdim = image[i] >> IMG2BITS;
bdim = imagebody[ibody] >> IMG2BITS;
xdim[2] = IMGMAX + tdim - bdim;
xcmimage[i] = (xdim[2] << IMG2BITS) | (xdim[1] << IMGBITS) | xdim[0];
}
}
@ -1191,7 +1192,6 @@ void FixRigid::set_xv()
double xy,xz,yz;
double ione[3],exone[3],eyone[3],ezone[3],vr[6],p[3][3];
imageint *image = atom->image;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
@ -1216,9 +1216,9 @@ void FixRigid::set_xv()
if (body[i] < 0) continue;
ibody = body[i];
xbox = (image[i] & IMGMASK) - IMGMAX;
ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (image[i] >> IMG2BITS) - IMGMAX;
xbox = (xcmimage[i] & IMGMASK) - IMGMAX;
ybox = (xcmimage[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (xcmimage[i] >> IMG2BITS) - IMGMAX;
// save old positions and velocities for virial
@ -1373,7 +1373,6 @@ void FixRigid::set_v()
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
imageint *image = atom->image;
int nlocal = atom->nlocal;
double xprd = domain->xprd;
@ -1422,9 +1421,9 @@ void FixRigid::set_v()
fc1 = massone*(v[i][1] - v1)/dtf - f[i][1];
fc2 = massone*(v[i][2] - v2)/dtf - f[i][2];
xbox = (image[i] & IMGMASK) - IMGMAX;
ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (image[i] >> IMG2BITS) - IMGMAX;
xbox = (xcmimage[i] & IMGMASK) - IMGMAX;
ybox = (xcmimage[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (xcmimage[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
x0 = x[i][0] + xbox*xprd;
@ -1585,11 +1584,19 @@ void FixRigid::setup_bodies_static()
}
}
// first-time setting of body xcmimage flags = true image flags
if (!staticflag) {
imageint *image = atom->image;
for (i = 0; i < nlocal; i++)
if (body[i] >= 0) xcmimage[i] = image[i];
else xcmimage[i] = 0;
}
// compute masstotal & center-of-mass of each rigid body
// error if image flag is not 0 in a non-periodic dim
double **x = atom->x;
imageint *image = atom->image;
int *periodicity = domain->periodicity;
double xprd = domain->xprd;
@ -1608,9 +1615,9 @@ void FixRigid::setup_bodies_static()
if (body[i] < 0) continue;
ibody = body[i];
xbox = (image[i] & IMGMASK) - IMGMAX;
ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (image[i] >> IMG2BITS) - IMGMAX;
xbox = (xcmimage[i] & IMGMASK) - IMGMAX;
ybox = (xcmimage[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (xcmimage[i] >> IMG2BITS) - IMGMAX;
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
@ -1654,9 +1661,10 @@ void FixRigid::setup_bodies_static()
readfile(0,masstotal,xcm,inbody);
}
// set image flags for each rigid body to default values
// then remap the xcm of each body back into simulation box if needed
// staticflag check insures this in only done once, not on successive runs
// one-time set of rigid body image flags to default values
// staticflag insures this is only done once, not on successive runs
// then remap the xcm of each body back into simulation box
// and reset body xcmimage flags via pre_neighbor()
if (!staticflag) {
for (ibody = 0; ibody < nbody; ibody++)
@ -1679,9 +1687,9 @@ void FixRigid::setup_bodies_static()
if (body[i] < 0) continue;
ibody = body[i];
xbox = (image[i] & IMGMASK) - IMGMAX;
ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (image[i] >> IMG2BITS) - IMGMAX;
xbox = (xcmimage[i] & IMGMASK) - IMGMAX;
ybox = (xcmimage[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (xcmimage[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;
@ -1834,9 +1842,9 @@ void FixRigid::setup_bodies_static()
ibody = body[i];
xbox = (image[i] & IMGMASK) - IMGMAX;
ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (image[i] >> IMG2BITS) - IMGMAX;
xbox = (xcmimage[i] & IMGMASK) - IMGMAX;
ybox = (xcmimage[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (xcmimage[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;
@ -2022,7 +2030,6 @@ void FixRigid::setup_bodies_dynamic()
double **v = atom->v;
double *rmass = atom->rmass;
double *mass = atom->mass;
imageint *image = atom->image;
int *type = atom->type;
int nlocal = atom->nlocal;
@ -2043,7 +2050,7 @@ void FixRigid::setup_bodies_dynamic()
sum[ibody][1] += v[i][1] * massone;
sum[ibody][2] += v[i][2] * massone;
domain->unmap(x[i],image[i],unwrap);
domain->unmap(x[i],xcmimage[i],unwrap);
dx = unwrap[0] - xcm[ibody][0];
dy = unwrap[1] - xcm[ibody][1];
dz = unwrap[2] - xcm[ibody][2];
@ -2264,6 +2271,7 @@ double FixRigid::memory_usage()
{
int nmax = atom->nmax;
double bytes = nmax * sizeof(int);
bytes += nmax * sizeof(imageint);
bytes += nmax*3 * sizeof(double);
bytes += maxvatom*6 * sizeof(double); // vatom
if (extended) {
@ -2281,6 +2289,7 @@ double FixRigid::memory_usage()
void FixRigid::grow_arrays(int nmax)
{
memory->grow(body,nmax,"rigid:body");
memory->grow(xcmimage,nmax,"rigid:xcmimage");
memory->grow(displace,nmax,3,"rigid:displace");
if (extended) {
memory->grow(eflags,nmax,"rigid:eflags");
@ -2296,6 +2305,7 @@ void FixRigid::grow_arrays(int nmax)
void FixRigid::copy_arrays(int i, int j, int delflag)
{
body[j] = body[i];
xcmimage[j] = xcmimage[i];
displace[j][0] = displace[i][0];
displace[j][1] = displace[i][1];
displace[j][2] = displace[i][2];
@ -2318,6 +2328,7 @@ void FixRigid::copy_arrays(int i, int j, int delflag)
void FixRigid::set_arrays(int i)
{
body[i] = -1;
xcmimage[i] = 0;
displace[i][0] = 0.0;
displace[i][1] = 0.0;
displace[i][2] = 0.0;
@ -2329,13 +2340,14 @@ void FixRigid::set_arrays(int i)
int FixRigid::pack_exchange(int i, double *buf)
{
buf[0] = body[i];
buf[1] = displace[i][0];
buf[2] = displace[i][1];
buf[3] = displace[i][2];
if (!extended) return 4;
buf[0] = ubuf(body[i]).d;
buf[1] = ubuf(xcmimage[i]).d;
buf[2] = displace[i][0];
buf[3] = displace[i][1];
buf[4] = displace[i][2];
if (!extended) return 5;
int m = 4;
int m = 5;
buf[m++] = eflags[i];
for (int j = 0; j < orientflag; j++)
buf[m++] = orient[i][j];
@ -2353,13 +2365,14 @@ int FixRigid::pack_exchange(int i, double *buf)
int FixRigid::unpack_exchange(int nlocal, double *buf)
{
body[nlocal] = static_cast<int> (buf[0]);
displace[nlocal][0] = buf[1];
displace[nlocal][1] = buf[2];
displace[nlocal][2] = buf[3];
if (!extended) return 4;
body[nlocal] = (int) ubuf(buf[0]).i;
xcmimage[nlocal] = (imageint) ubuf(buf[1]).i;
displace[nlocal][0] = buf[2];
displace[nlocal][1] = buf[3];
displace[nlocal][2] = buf[4];
if (!extended) return 5;
int m = 4;
int m = 5;
eflags[nlocal] = static_cast<int> (buf[m++]);
for (int j = 0; j < orientflag; j++)
orient[nlocal][j] = buf[m++];

View File

@ -47,6 +47,7 @@ class FixRigid : public Fix {
int pack_exchange(int, double *);
int unpack_exchange(int, double *);
void setup_pre_neighbor();
void pre_neighbor();
int dof(int);
void deform(int);
@ -102,6 +103,8 @@ class FixRigid : public Fix {
int orientflag; // 1 if particles store spatial orientation
int dorientflag; // 1 if particles store dipole orientation
imageint *xcmimage; // internal image flags for atoms in rigid bodies
// set relative to in-box xcm of each body
int *eflags; // flags for extended particles
double **orient; // orientation vector of particle wrt rigid body
double **dorient; // orientation of dipole mu wrt rigid body
@ -133,6 +136,7 @@ class FixRigid : public Fix {
int POINT,SPHERE,ELLIPSOID,LINE,TRIANGLE,DIPOLE; // bitmasks for eflags
int OMEGA,ANGMOM,TORQUE;
void image_shift();
void set_xv();
void set_v();
void setup_bodies_static();

View File

@ -615,7 +615,6 @@ void FixRigidNH::final_integrate()
// sum over atoms to get force and torque on rigid body
imageint *image = atom->image;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
@ -642,9 +641,9 @@ void FixRigidNH::final_integrate()
sum[ibody][1] += f[i][1];
sum[ibody][2] += f[i][2];
xbox = (image[i] & IMGMASK) - IMGMAX;
ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (image[i] >> IMG2BITS) - IMGMAX;
xbox = (xcmimage[i] & IMGMASK) - IMGMAX;
ybox = (xcmimage[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (xcmimage[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
xunwrap = x[i][0] + xbox*xprd;

View File

@ -60,32 +60,42 @@ FixRigidNHSmall::FixRigidNHSmall(LAMMPS *lmp, int narg, char **arg) :
error->all(FLERR,"Fix rigid/small npt/nph period must be > 0.0");
if (domain->dimension == 2 && p_flag[2])
error->all(FLERR,"Invalid fix rigid/small npt/nph command for a 2d simulation");
error->all(FLERR,"Invalid fix rigid/small npt/nph command "
"for a 2d simulation");
if (domain->dimension == 2 && (pcouple == YZ || pcouple == XZ))
error->all(FLERR,"Invalid fix rigid/small npt/nph command for a 2d simulation");
error->all(FLERR,"Invalid fix rigid/small npt/nph command "
"for a 2d simulation");
if (pcouple == XYZ && (p_flag[0] == 0 || p_flag[1] == 0))
error->all(FLERR,"Invalid fix rigid/small npt/nph command pressure settings");
error->all(FLERR,"Invalid fix rigid/small npt/nph command "
"pressure settings");
if (pcouple == XYZ && domain->dimension == 3 && p_flag[2] == 0)
error->all(FLERR,"Invalid fix rigid/small npt/nph command pressure settings");
error->all(FLERR,"Invalid fix rigid/small npt/nph command "
"pressure settings");
if (pcouple == XY && (p_flag[0] == 0 || p_flag[1] == 0))
error->all(FLERR,"Invalid fix rigid/small npt/nph command pressure settings");
error->all(FLERR,"Invalid fix rigid/small npt/nph command "
"pressure settings");
if (pcouple == YZ && (p_flag[1] == 0 || p_flag[2] == 0))
error->all(FLERR,"Invalid fix rigid/small npt/nph command pressure settings");
error->all(FLERR,"Invalid fix rigid/small npt/nph command "
"pressure settings");
if (pcouple == XZ && (p_flag[0] == 0 || p_flag[2] == 0))
error->all(FLERR,"Invalid fix rigid/small npt/nph command pressure settings");
error->all(FLERR,"Invalid fix rigid/small npt/nph command "
"pressure settings");
// require periodicity in tensile dimension
if (p_flag[0] && domain->xperiodic == 0)
error->all(FLERR,
"Cannot use fix rigid/small npt/nph on a non-periodic dimension");
"Cannot use fix rigid/small npt/nph on a "
"non-periodic dimension");
if (p_flag[1] && domain->yperiodic == 0)
error->all(FLERR,
"Cannot use fix rigid/small npt/nph on a non-periodic dimension");
"Cannot use fix rigid/small npt/nph on a "
"non-periodic dimension");
if (p_flag[2] && domain->zperiodic == 0)
error->all(FLERR,
"Cannot use fix rigid/small npt/nph on a non-periodic dimension");
"Cannot use fix rigid/small npt/nph on a "
"non-periodic dimension");
if (pcouple == XYZ && domain->dimension == 3 &&
(p_start[0] != p_start[1] || p_start[0] != p_start[2] ||
@ -113,7 +123,8 @@ FixRigidNHSmall::FixRigidNHSmall(LAMMPS *lmp, int narg, char **arg) :
(p_flag[0] && p_period[0] <= 0.0) ||
(p_flag[1] && p_period[1] <= 0.0) ||
(p_flag[2] && p_period[2] <= 0.0))
error->all(FLERR,"Fix rigid/small nvt/npt/nph damping parameters must be > 0.0");
error->all(FLERR,"Fix rigid/small nvt/npt/nph damping parameters "
"must be > 0.0");
// memory allocation and initialization
@ -653,7 +664,6 @@ void FixRigidNHSmall::final_integrate()
// sum over atoms to get force and torque on rigid body
imageint *image = atom->image;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
@ -678,7 +688,7 @@ void FixRigidNHSmall::final_integrate()
fcm[1] += f[i][1];
fcm[2] += f[i][2];
domain->unmap(x[i],image[i],unwrap);
domain->unmap(x[i],xcmimage[i],unwrap);
xcm = b->xcm;
dx = unwrap[0] - xcm[0];
dy = unwrap[1] - xcm[1];

View File

@ -89,6 +89,7 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) :
bodyown = NULL;
bodytag = NULL;
atom2body = NULL;
xcmimage = NULL;
displace = NULL;
eflags = NULL;
orient = NULL;
@ -439,6 +440,7 @@ FixRigidSmall::~FixRigidSmall()
memory->destroy(bodyown);
memory->destroy(bodytag);
memory->destroy(atom2body);
memory->destroy(xcmimage);
memory->destroy(displace);
memory->destroy(eflags);
memory->destroy(orient);
@ -507,11 +509,15 @@ void FixRigidSmall::init()
allows resetting of atom properties like mass between runs
only do static initialization once if using an infile
cannot do this until now, b/c requires comm->setup() to have setup stencil
invoke pre_neighbor() to insure body xcmimage flags are reset
needed if Verlet::setup::pbc() has remapped/migrated atoms for 2nd run
setup_bodies_static() invokes pre_neighbor itself
------------------------------------------------------------------------- */
void FixRigidSmall::setup_pre_neighbor()
{
if (!staticflag || !infile) setup_bodies_static();
else pre_neighbor();
setup_bodies_dynamic();
}
@ -532,7 +538,6 @@ void FixRigidSmall::setup(int vflag)
double **x = atom->x;
double **f = atom->f;
imageint *image = atom->image;
int nlocal = atom->nlocal;
double *xcm,*fcm,*tcm;
@ -555,7 +560,7 @@ void FixRigidSmall::setup(int vflag)
fcm[1] += f[i][1];
fcm[2] += f[i][2];
domain->unmap(x[i],image[i],unwrap);
domain->unmap(x[i],xcmimage[i],unwrap);
xcm = b->xcm;
dx = unwrap[0] - xcm[0];
dy = unwrap[1] - xcm[1];
@ -740,7 +745,6 @@ void FixRigidSmall::final_integrate()
// sum over atoms to get force and torque on rigid body
imageint *image = atom->image;
double **x = atom->x;
double **f = atom->f;
int nlocal = atom->nlocal;
@ -765,7 +769,7 @@ void FixRigidSmall::final_integrate()
fcm[1] += f[i][1];
fcm[2] += f[i][2];
domain->unmap(x[i],image[i],unwrap);
domain->unmap(x[i],xcmimage[i],unwrap);
xcm = b->xcm;
dx = unwrap[0] - xcm[0];
dy = unwrap[1] - xcm[1];
@ -867,6 +871,26 @@ void FixRigidSmall::final_integrate_respa(int ilevel, int iloop)
final_integrate();
}
/* ----------------------------------------------------------------------
remap xcm of each rigid body back into periodic simulation box
done during pre_neighbor so will be after call to pbc()
and after fix_deform::pre_exchange() may have flipped box
use domain->remap() in case xcm is far away from box
due to first-time definition of rigid body in setup_bodies_static()
or due to box flip
also adjust imagebody = rigid body image flags, due to xcm remap
also adjust rgdimage flags of all atoms in bodies for two effects
(1) change in true image flags due to pbc() call during exchange
(2) change in imagebody due to xcm remap
rgdimage flags are always -1,0,-1 so that body can be unwrapped
around in-box xcm and stay close to simulation box
if don't do this, then a body could end up very far away
when unwrapped by true image flags, and set_xv() will
compute huge displacements every step to reset coords of
all the body atoms to be back inside the box, ditto for triclinic box flip
note: so just want to avoid that numeric probem?
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
atom to processor assignments have changed,
so acquire ghost bodies and setup atom2body
@ -883,31 +907,6 @@ void FixRigidSmall::final_integrate_respa(int ilevel, int iloop)
void FixRigidSmall::pre_neighbor()
{
// remap xcm and image flags of each body as needed
imageint original,oldimage,newimage;
for (int ibody = 0; ibody < nlocal_body; ibody++) {
Body *b = &body[ibody];
original = b->image;
domain->remap(b->xcm,b->image);
if (original == b->image) b->remapflag[3] = 0;
else {
oldimage = original & IMGMASK;
newimage = b->image & IMGMASK;
b->remapflag[0] = newimage - oldimage;
oldimage = (original >> IMGBITS) & IMGMASK;
newimage = (b->image >> IMGBITS) & IMGMASK;
b->remapflag[1] = newimage - oldimage;
oldimage = original >> IMG2BITS;
newimage = b->image >> IMG2BITS;
b->remapflag[2] = newimage - oldimage;
b->remapflag[3] = 1;
}
}
// acquire ghost bodies via forward comm
// also gets new remapflags needed for adjusting atom image flags
// reset atom2body for owned atoms
@ -919,40 +918,42 @@ void FixRigidSmall::pre_neighbor()
reset_atom2body();
//check(4);
// adjust image flags of any atom in a rigid body whose xcm was remapped
for (int ibody = 0; ibody < nlocal_body; ibody++) {
Body *b = &body[ibody];
domain->remap(b->xcm,b->image);
}
image_shift();
}
/* ----------------------------------------------------------------------
reset body xcmimage flags of atoms in bodies
xcmimage flags are relative to xcm so that body can be unwrapped
xcmimage = true image flag - imagebody flag
------------------------------------------------------------------------- */
void FixRigidSmall::image_shift()
{
int ibody;
imageint tdim,bdim,xdim[3];
imageint *image = atom->image;
int nlocal = atom->nlocal;
imageint idim,otherdims;
for (int i = 0; i < nlocal; i++) {
if (atom2body[i] < 0) continue;
Body *b = &body[atom2body[i]];
if (b->remapflag[3] == 0) continue;
tdim = image[i] & IMGMASK;
bdim = b->image & IMGMASK;
xdim[0] = IMGMAX + tdim - bdim;
tdim = (image[i] >> IMGBITS) & IMGMASK;
bdim = (b->image >> IMGBITS) & IMGMASK;
xdim[1] = IMGMAX + tdim - bdim;
tdim = image[i] >> IMG2BITS;
bdim = b->image >> IMG2BITS;
xdim[2] = IMGMAX + tdim - bdim;
if (b->remapflag[0]) {
idim = image[i] & IMGMASK;
otherdims = image[i] ^ idim;
idim -= b->remapflag[0];
idim &= IMGMASK;
image[i] = otherdims | idim;
}
if (b->remapflag[1]) {
idim = (image[i] >> IMGBITS) & IMGMASK;
otherdims = image[i] ^ (idim << IMGBITS);
idim -= b->remapflag[1];
idim &= IMGMASK;
image[i] = otherdims | (idim << IMGBITS);
}
if (b->remapflag[2]) {
idim = image[i] >> IMG2BITS;
otherdims = image[i] ^ (idim << IMG2BITS);
idim -= b->remapflag[2];
idim &= IMGMASK;
image[i] = otherdims | (idim << IMG2BITS);
}
xcmimage[i] = (xdim[2] << IMG2BITS) | (xdim[1] << IMGBITS) | xdim[0];
}
}
@ -1091,7 +1092,6 @@ void FixRigidSmall::set_xv()
double xz = domain->xz;
double yz = domain->yz;
imageint *image = atom->image;
double **x = atom->x;
double **v = atom->v;
double **f = atom->f;
@ -1106,9 +1106,9 @@ void FixRigidSmall::set_xv()
if (atom2body[i] < 0) continue;
Body *b = &body[atom2body[i]];
xbox = (image[i] & IMGMASK) - IMGMAX;
ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (image[i] >> IMG2BITS) - IMGMAX;
xbox = (xcmimage[i] & IMGMASK) - IMGMAX;
ybox = (xcmimage[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (xcmimage[i] >> IMG2BITS) - IMGMAX;
// save old positions and velocities for virial
@ -1264,7 +1264,6 @@ void FixRigidSmall::set_v()
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
imageint *image = atom->image;
int nlocal = atom->nlocal;
// set v of each atom
@ -1300,9 +1299,9 @@ void FixRigidSmall::set_v()
fc1 = massone*(v[i][1] - v1)/dtf - f[i][1];
fc2 = massone*(v[i][2] - v2)/dtf - f[i][2];
xbox = (image[i] & IMGMASK) - IMGMAX;
ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (image[i] >> IMG2BITS) - IMGMAX;
xbox = (xcmimage[i] & IMGMASK) - IMGMAX;
ybox = (xcmimage[i] >> IMGBITS & IMGMASK) - IMGMAX;
zbox = (xcmimage[i] >> IMG2BITS) - IMGMAX;
if (triclinic == 0) {
x0 = x[i][0] + xbox*xprd;
@ -1771,6 +1770,15 @@ void FixRigidSmall::setup_bodies_static()
}
}
// first-time setting of body xcmimage flags = true image flags
if (!staticflag) {
imageint *image = atom->image;
for (i = 0; i < nlocal; i++)
if (bodytag[i] >= 0) xcmimage[i] = image[i];
else xcmimage[i] = 0;
}
// acquire ghost bodies via forward comm
// set atom2body for ghost atoms via forward comm
// set atom2body for other owned atoms via reset_atom2body()
@ -1783,7 +1791,6 @@ void FixRigidSmall::setup_bodies_static()
// compute mass & center-of-mass of each rigid body
double **x = atom->x;
imageint *image = atom->image;
double *xcm;
@ -1803,7 +1810,7 @@ void FixRigidSmall::setup_bodies_static()
if (rmass) massone = rmass[i];
else massone = mass[type[i]];
domain->unmap(x[i],image[i],unwrap);
domain->unmap(x[i],xcmimage[i],unwrap);
xcm = b->xcm;
xcm[0] += unwrap[0] * massone;
xcm[1] += unwrap[1] * massone;
@ -1833,14 +1840,16 @@ void FixRigidSmall::setup_bodies_static()
readfile(0,NULL,inbody);
}
// set image flags for each rigid body to default values
// then remap the xcm of each body back into simulation box if needed
// staticflag check insures this in only done once, not on successive runs
// one-time set of rigid body image flags to default values
// staticflag insures this is only done once, not on successive runs
// then remap the xcm of each body back into simulation box
// and reset body xcmimage flags via pre_neighbor()
if (!staticflag)
if (!staticflag) {
for (ibody = 0; ibody < nlocal_body; ibody++)
body[ibody].image = ((imageint) IMGMAX << IMG2BITS) |
((imageint) IMGMAX << IMGBITS) | IMGMAX;
}
pre_neighbor();
@ -1859,7 +1868,7 @@ void FixRigidSmall::setup_bodies_static()
if (atom2body[i] < 0) continue;
Body *b = &body[atom2body[i]];
domain->unmap(x[i],image[i],unwrap);
domain->unmap(x[i],xcmimage[i],unwrap);
xcm = b->xcm;
dx = unwrap[0] - xcm[0];
dy = unwrap[1] - xcm[1];
@ -2015,7 +2024,7 @@ void FixRigidSmall::setup_bodies_static()
Body *b = &body[atom2body[i]];
domain->unmap(x[i],image[i],unwrap);
domain->unmap(x[i],xcmimage[i],unwrap);
xcm = b->xcm;
delta[0] = unwrap[0] - xcm[0];
delta[1] = unwrap[1] - xcm[1];
@ -2203,7 +2212,6 @@ void FixRigidSmall::setup_bodies_dynamic()
double *rmass = atom->rmass;
double *mass = atom->mass;
int *type = atom->type;
imageint *image = atom->image;
int nlocal = atom->nlocal;
double *xcm,*vcm,*acm;
@ -2229,7 +2237,7 @@ void FixRigidSmall::setup_bodies_dynamic()
vcm[1] += v[i][1] * massone;
vcm[2] += v[i][2] * massone;
domain->unmap(x[i],image[i],unwrap);
domain->unmap(x[i],xcmimage[i],unwrap);
xcm = b->xcm;
dx = unwrap[0] - xcm[0];
dy = unwrap[1] - xcm[1];
@ -2525,6 +2533,7 @@ void FixRigidSmall::grow_arrays(int nmax)
memory->grow(bodyown,nmax,"rigid/small:bodyown");
memory->grow(bodytag,nmax,"rigid/small:bodytag");
memory->grow(atom2body,nmax,"rigid/small:atom2body");
memory->grow(xcmimage,nmax,"rigid/small:xcmimage");
memory->grow(displace,nmax,3,"rigid/small:displace");
if (extended) {
memory->grow(eflags,nmax,"rigid/small:eflags");
@ -2540,6 +2549,7 @@ void FixRigidSmall::grow_arrays(int nmax)
void FixRigidSmall::copy_arrays(int i, int j, int delflag)
{
bodytag[j] = bodytag[i];
xcmimage[j] = xcmimage[i];
displace[j][0] = displace[i][0];
displace[j][1] = displace[i][1];
displace[j][2] = displace[i][2];
@ -2579,6 +2589,7 @@ void FixRigidSmall::set_arrays(int i)
bodyown[i] = -1;
bodytag[i] = 0;
atom2body[i] = -1;
xcmimage[i] = 0;
displace[i][0] = 0.0;
displace[i][1] = 0.0;
displace[i][2] = 0.0;
@ -2670,13 +2681,14 @@ void FixRigidSmall::set_molecule(int nlocalprev, tagint tagprev, int imol,
int FixRigidSmall::pack_exchange(int i, double *buf)
{
buf[0] = ubuf(bodytag[i]).d;
buf[1] = displace[i][0];
buf[2] = displace[i][1];
buf[3] = displace[i][2];
buf[1] = ubuf(xcmimage[i]).d;
buf[2] = displace[i][0];
buf[3] = displace[i][1];
buf[4] = displace[i][2];
// extended attribute info
int m = 4;
int m = 5;
if (extended) {
buf[m++] = eflags[i];
for (int j = 0; j < orientflag; j++)
@ -2714,13 +2726,14 @@ int FixRigidSmall::pack_exchange(int i, double *buf)
int FixRigidSmall::unpack_exchange(int nlocal, double *buf)
{
bodytag[nlocal] = (tagint) ubuf(buf[0]).i;
displace[nlocal][0] = buf[1];
displace[nlocal][1] = buf[2];
displace[nlocal][2] = buf[3];
xcmimage[nlocal] = (imageint) ubuf(buf[1]).i;
displace[nlocal][0] = buf[2];
displace[nlocal][1] = buf[3];
displace[nlocal][2] = buf[4];
// extended attribute info
int m = 4;
int m = 5;
if (extended) {
eflags[nlocal] = static_cast<int> (buf[m++]);
for (int j = 0; j < orientflag; j++)
@ -3327,7 +3340,8 @@ double FixRigidSmall::compute_scalar()
double FixRigidSmall::memory_usage()
{
int nmax = atom->nmax;
double bytes = 2 * nmax * sizeof(int);
double bytes = nmax*2 * sizeof(int);
bytes += nmax * sizeof(imageint);
bytes += nmax*3 * sizeof(double);
bytes += maxvatom*6 * sizeof(double); // vatom
if (extended) {

View File

@ -117,15 +117,16 @@ class FixRigidSmall : public Fix {
// ID = tag of atom that owns body
int *atom2body; // index of owned/ghost body this atom is in, -1 if not
// can point to original or any image of the body
imageint *xcmimage; // internal image flags for atoms in rigid bodies
// set relative to in-box xcm of each body
double **displace; // displacement of each atom in body coords
int *eflags; // flags for extended particles
double **orient; // orientation vector of particle wrt rigid body
double **dorient; // orientation of dipole mu wrt rigid body
int *eflags; // flags for extended particles
double **orient; // orientation vector of particle wrt rigid body
double **dorient; // orientation of dipole mu wrt rigid body
int extended; // 1 if any particles have extended attributes
int orientflag; // 1 if particles store spatial orientation
int dorientflag; // 1 if particles store dipole orientation
int extended; // 1 if any particles have extended attributes
int orientflag; // 1 if particles store spatial orientation
int dorientflag; // 1 if particles store dipole orientation
int POINT,SPHERE,ELLIPSOID,LINE,TRIANGLE,DIPOLE; // bitmasks for eflags
int OMEGA,ANGMOM,TORQUE;
@ -182,6 +183,7 @@ class FixRigidSmall : public Fix {
double *rsqclose;
double rsqfar;
void image_shift();
void set_xv();
void set_v();
void create_bodies();