361
365
} else if (strcmp(arg[iarg],"iso") == 0) {
362
366
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
363
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0)
364
error->all(FLERR,"Illegal fix rigid command");
367
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
368
strcmp(style,"rigid/npt/omp") != 0 &&
369
strcmp(style,"rigid/nph/omp") != 0)
370
error->all(FLERR,"Illegal fix rigid command");
366
372
p_start[0] = p_start[1] = p_start[2] = force->numeric(FLERR,arg[iarg+1]);
367
373
p_stop[0] = p_stop[1] = p_stop[2] = force->numeric(FLERR,arg[iarg+2]);
377
383
} else if (strcmp(arg[iarg],"aniso") == 0) {
378
384
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
379
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0)
380
error->all(FLERR,"Illegal fix rigid command");
385
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
386
strcmp(style,"rigid/npt/omp") != 0 &&
387
strcmp(style,"rigid/nph/omp") != 0)
388
error->all(FLERR,"Illegal fix rigid command");
381
389
p_start[0] = p_start[1] = p_start[2] = force->numeric(FLERR,arg[iarg+1]);
382
390
p_stop[0] = p_stop[1] = p_stop[2] = force->numeric(FLERR,arg[iarg+2]);
383
391
p_period[0] = p_period[1] = p_period[2] =
392
400
} else if (strcmp(arg[iarg],"x") == 0) {
393
401
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
402
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
403
strcmp(style,"rigid/npt/omp") != 0 &&
404
strcmp(style,"rigid/nph/omp") != 0)
405
error->all(FLERR,"Illegal fix rigid command");
394
406
p_start[0] = force->numeric(FLERR,arg[iarg+1]);
395
407
p_stop[0] = force->numeric(FLERR,arg[iarg+2]);
396
408
p_period[0] = force->numeric(FLERR,arg[iarg+3]);
400
412
} else if (strcmp(arg[iarg],"y") == 0) {
401
413
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
414
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
415
strcmp(style,"rigid/npt/omp") != 0 &&
416
strcmp(style,"rigid/nph/omp") != 0)
417
error->all(FLERR,"Illegal fix rigid command");
402
418
p_start[1] = force->numeric(FLERR,arg[iarg+1]);
403
419
p_stop[1] = force->numeric(FLERR,arg[iarg+2]);
404
420
p_period[1] = force->numeric(FLERR,arg[iarg+3]);
408
424
} else if (strcmp(arg[iarg],"z") == 0) {
409
425
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
426
if (strcmp(style,"rigid/npt") != 0 && strcmp(style,"rigid/nph") != 0 &&
427
strcmp(style,"rigid/npt/omp") != 0 &&
428
strcmp(style,"rigid/nph/omp") != 0)
429
error->all(FLERR,"Illegal fix rigid command");
410
430
p_start[2] = force->numeric(FLERR,arg[iarg+1]);
411
431
p_stop[2] = force->numeric(FLERR,arg[iarg+2]);
412
432
p_period[2] = force->numeric(FLERR,arg[iarg+3]);
443
463
} else if (strcmp(arg[iarg],"tparam") == 0) {
444
464
if (iarg+4 > narg) error->all(FLERR,"Illegal fix rigid command");
445
if (strcmp(style,"rigid/nvt") != 0 && strcmp(style,"rigid/npt") != 0)
465
if (strcmp(style,"rigid/nvt") != 0 && strcmp(style,"rigid/npt") != 0 &&
466
strcmp(style,"rigid/nvt/omp") != 0 &&
467
strcmp(style,"rigid/npt/omp") != 0)
446
468
error->all(FLERR,"Illegal fix rigid command");
447
469
t_chain = force->inumeric(FLERR,arg[iarg+1]);
448
470
t_iter = force->inumeric(FLERR,arg[iarg+2]);
640
668
if (strstr(update->integrate_style,"respa"))
641
669
step_respa = ((Respa *) update->integrate)->step;
643
// one-time initialization of rigid body attributes
644
// setup_bodies_static = extended flags, masstotal, COM, inertia tensor
645
// setup_bodies_dynamic = vcm and angmom
671
// setup rigid bodies, using current atom info
672
// allows resetting of atom properties like mass between runs
673
// only do this if not using an infile, else was called in constructor
649
setup_bodies_static();
650
setup_bodies_dynamic();
675
if (!infile) setup_bodies_static();
653
677
// temperature scale factor
963
/* ----------------------------------------------------------------------
964
apply evolution operators to quat, quat momentum
965
see Miller paper cited in fix rigid/nvt and fix rigid/npt
966
------------------------------------------------------------------------- */
968
void FixRigid::no_squish_rotate(int k, double *p, double *q,
969
double *inertia, double dt) const
971
double phi,c_phi,s_phi,kp[4],kq[4];
973
// apply permuation operator on p and q, get kp and kq
976
kq[0] = -q[1]; kp[0] = -p[1];
977
kq[1] = q[0]; kp[1] = p[0];
978
kq[2] = q[3]; kp[2] = p[3];
979
kq[3] = -q[2]; kp[3] = -p[2];
981
kq[0] = -q[2]; kp[0] = -p[2];
982
kq[1] = -q[3]; kp[1] = -p[3];
983
kq[2] = q[0]; kp[2] = p[0];
984
kq[3] = q[1]; kp[3] = p[1];
986
kq[0] = -q[3]; kp[0] = -p[3];
987
kq[1] = q[2]; kp[1] = p[2];
988
kq[2] = -q[1]; kp[2] = -p[1];
989
kq[3] = q[0]; kp[3] = p[0];
992
// obtain phi, cosines and sines
994
phi = p[0]*kq[0] + p[1]*kq[1] + p[2]*kq[2] + p[3]*kq[3];
995
if (fabs(inertia[k-1]) < 1e-6) phi *= 0.0;
996
else phi /= 4.0 * inertia[k-1];
997
c_phi = cos(dt * phi);
998
s_phi = sin(dt * phi);
1002
p[0] = c_phi*p[0] + s_phi*kp[0];
1003
p[1] = c_phi*p[1] + s_phi*kp[1];
1004
p[2] = c_phi*p[2] + s_phi*kp[2];
1005
p[3] = c_phi*p[3] + s_phi*kp[3];
1007
q[0] = c_phi*q[0] + s_phi*kq[0];
1008
q[1] = c_phi*q[1] + s_phi*kq[1];
1009
q[2] = c_phi*q[2] + s_phi*kq[2];
1010
q[3] = c_phi*q[3] + s_phi*kq[3];
1013
1002
/* ---------------------------------------------------------------------- */
1015
1004
void FixRigid::initial_integrate_respa(int vflag, int ilevel, int iloop)
1035
1024
done during pre_neighbor so will be after call to pbc()
1036
1025
and after fix_deform::pre_exchange() may have flipped box
1037
1026
use domain->remap() in case xcm is far away from box
1038
due to 1st definition of rigid body or due to box flip
1039
if don't do this, then atoms of a body which drifts far away
1040
from a triclinic box will be remapped back into box
1041
with huge displacements when the box tilt changes via set_x()
1042
adjust image flag of body and image flags of all atoms in body
1027
due to first-time definition of rigid body in setup_bodies_static()
1029
also adjust imagebody = rigid body image flags, due to xcm remap
1030
also reset body xcmimage flags of all atoms in bodies
1031
xcmimage flags are relative to xcm so that body can be unwrapped
1032
if don't do this, would need xcm to move with true image flags
1033
then a body could end up very far away from box
1034
set_xv() will then compute huge displacements every step to
1035
reset coords of all body atoms to be back inside the box,
1036
ditto for triclinic box flip, which causes numeric problems
1043
1037
------------------------------------------------------------------------- */
1045
1039
void FixRigid::pre_neighbor()
1047
imageint original,oldimage,newimage;
1049
for (int ibody = 0; ibody < nbody; ibody++) {
1050
original = imagebody[ibody];
1041
for (int ibody = 0; ibody < nbody; ibody++)
1051
1042
domain->remap(xcm[ibody],imagebody[ibody]);
1053
if (original == imagebody[ibody]) remapflag[ibody][3] = 0;
1055
oldimage = original & IMGMASK;
1056
newimage = imagebody[ibody] & IMGMASK;
1057
remapflag[ibody][0] = newimage - oldimage;
1058
oldimage = (original >> IMGBITS) & IMGMASK;
1059
newimage = (imagebody[ibody] >> IMGBITS) & IMGMASK;
1060
remapflag[ibody][1] = newimage - oldimage;
1061
oldimage = original >> IMG2BITS;
1062
newimage = imagebody[ibody] >> IMG2BITS;
1063
remapflag[ibody][2] = newimage - oldimage;
1064
remapflag[ibody][3] = 1;
1068
// adjust image flags of any atom in a rigid body whose xcm was remapped
1069
// subtracting remapflag = new-old keeps ix,iy,iz near 0
1070
// so body is always in central simulation box
1046
/* ----------------------------------------------------------------------
1047
reset body xcmimage flags of atoms in bodies
1048
xcmimage flags are relative to xcm so that body can be unwrapped
1049
xcmimage = true image flag - imagebody flag
1050
------------------------------------------------------------------------- */
1052
void FixRigid::image_shift()
1055
imageint tdim,bdim,xdim[3];
1072
1057
imageint *image = atom->image;
1073
1058
int nlocal = atom->nlocal;
1076
imageint idim,otherdims;
1078
1060
for (int i = 0; i < nlocal; i++) {
1079
if (body[i] == -1) continue;
1080
if (remapflag[body[i]][3] == 0) continue;
1061
if (body[i] < 0) continue;
1081
1062
ibody = body[i];
1083
if (remapflag[ibody][0]) {
1084
idim = image[i] & IMGMASK;
1085
otherdims = image[i] ^ idim;
1086
idim -= remapflag[ibody][0];
1088
image[i] = otherdims | idim;
1090
if (remapflag[ibody][1]) {
1091
idim = (image[i] >> IMGBITS) & IMGMASK;
1092
otherdims = image[i] ^ (idim << IMGBITS);
1093
idim -= remapflag[ibody][1];
1095
image[i] = otherdims | (idim << IMGBITS);
1097
if (remapflag[ibody][2]) {
1098
idim = image[i] >> IMG2BITS;
1099
otherdims = image[i] ^ (idim << IMG2BITS);
1100
idim -= remapflag[ibody][2];
1102
image[i] = otherdims | (idim << IMG2BITS);
1064
tdim = image[i] & IMGMASK;
1065
bdim = imagebody[ibody] & IMGMASK;
1066
xdim[0] = IMGMAX + tdim - bdim;
1067
tdim = (image[i] >> IMGBITS) & IMGMASK;
1068
bdim = (imagebody[ibody] >> IMGBITS) & IMGMASK;
1069
xdim[1] = IMGMAX + tdim - bdim;
1070
tdim = image[i] >> IMG2BITS;
1071
bdim = imagebody[ibody] >> IMG2BITS;
1072
xdim[2] = IMGMAX + tdim - bdim;
1074
xcmimage[i] = (xdim[2] << IMG2BITS) | (xdim[1] << IMGBITS) | xdim[0];
1524
1495
/* ----------------------------------------------------------------------
1525
one-time initialization of static rigid body attributes
1526
extended flags, masstotal, center-of-mass
1527
Cartesian and diagonalized inertia tensor
1528
read per-body attributes from infile if specified
1496
initialization of static rigid body attributes
1497
called from init() so body/atom properties can be changed between runs
1498
unless reading from infile, in which case called once from constructor
1499
sets extended flags, masstotal, center-of-mass
1500
sets Cartesian and diagonalized inertia tensor
1501
sets body image flags, but only on first call
1529
1502
------------------------------------------------------------------------- */
1531
1504
void FixRigid::setup_bodies_static()
1680
1661
readfile(0,masstotal,xcm,inbody);
1683
// set image flags for each rigid body to default values
1684
// then remap the xcm of each body back into simulation box if needed
1664
// one-time set of rigid body image flags to default values
1665
// staticflag insures this is only done once, not on successive runs
1666
// then remap the xcm of each body back into simulation box
1667
// and reset body xcmimage flags via pre_neighbor()
1686
for (ibody = 0; ibody < nbody; ibody++)
1687
imagebody[ibody] = ((imageint) IMGMAX << IMG2BITS) |
1688
((imageint) IMGMAX << IMGBITS) | IMGMAX;
1670
for (ibody = 0; ibody < nbody; ibody++)
1671
imagebody[ibody] = ((imageint) IMGMAX << IMG2BITS) |
1672
((imageint) IMGMAX << IMGBITS) | IMGMAX;
1690
1675
pre_neighbor();
2020
2005
if (infile) memory->destroy(inbody);
2007
// static properties have now been initialized once
2008
// used to prevent re-initialization which would re-read infile
2023
2013
/* ----------------------------------------------------------------------
2024
one-time initialization of dynamic rigid body attributes
2025
Vcm and angmom, computed explicitly from constituent particles
2026
even if wrong for overlapping particles, is OK,
2027
since is just setting initial time=0 Vcm and angmom of the body
2014
initialization of dynamic rigid body attributes
2015
set vcm and angmom, computed explicitly from constituent particles
2016
OK if wrong for overlapping particles,
2017
since is just setting vcm/angmom at start of run,
2028
2018
which can be estimated value
2029
2019
------------------------------------------------------------------------- */
2372
2366
int FixRigid::unpack_exchange(int nlocal, double *buf)
2374
body[nlocal] = static_cast<int> (buf[0]);
2375
displace[nlocal][0] = buf[1];
2376
displace[nlocal][1] = buf[2];
2377
displace[nlocal][2] = buf[3];
2378
if (!extended) return 4;
2368
body[nlocal] = (int) ubuf(buf[0]).i;
2369
xcmimage[nlocal] = (imageint) ubuf(buf[1]).i;
2370
displace[nlocal][0] = buf[2];
2371
displace[nlocal][1] = buf[3];
2372
displace[nlocal][2] = buf[4];
2373
if (!extended) return 5;
2381
2376
eflags[nlocal] = static_cast<int> (buf[m++]);
2382
2377
for (int j = 0; j < orientflag; j++)
2383
2378
orient[nlocal][j] = buf[m++];