Merge pull request #1801 from lammps/rigid-gravity
enable fix rigid commands to add gravity to COM of rigid bodies
This commit is contained in:
63
examples/rigid/in.rigid.gravity
Normal file
63
examples/rigid/in.rigid.gravity
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#Pour composite granular particles on flat wall
|
||||||
|
|
||||||
|
newton on
|
||||||
|
atom_style sphere
|
||||||
|
atom_modify map array sort 0 0
|
||||||
|
|
||||||
|
thermo_modify flush yes
|
||||||
|
units si
|
||||||
|
|
||||||
|
variable minrad equal 0.5
|
||||||
|
variable maxrad equal 1.4
|
||||||
|
|
||||||
|
variable skin equal 0.3*${maxrad}
|
||||||
|
|
||||||
|
boundary p p f
|
||||||
|
region reg block 0 20 0 20 0 200 units box
|
||||||
|
create_box 1 reg
|
||||||
|
|
||||||
|
fix prop all property/atom mol ghost yes
|
||||||
|
|
||||||
|
variable dumpfreq equal 1000
|
||||||
|
variable logfreq equal 1000
|
||||||
|
|
||||||
|
pair_style gran/hooke/history 4e5 NULL 1e2 NULL 0.5 0
|
||||||
|
pair_coeff * *
|
||||||
|
|
||||||
|
timestep 0.0001
|
||||||
|
|
||||||
|
group particles type 1
|
||||||
|
atom_modify first particles
|
||||||
|
|
||||||
|
neighbor ${skin} bin
|
||||||
|
group rigid type 1
|
||||||
|
neigh_modify every 1 delay 0 check yes exclude molecule/intra all
|
||||||
|
|
||||||
|
thermo ${logfreq}
|
||||||
|
thermo_style custom step cpu atoms ke
|
||||||
|
thermo_modify flush yes lost warn
|
||||||
|
|
||||||
|
comm_modify vel yes cutoff 3
|
||||||
|
|
||||||
|
molecule mymol molecule.data
|
||||||
|
region pourreg block 5 15 5 15 80 100 side in units box
|
||||||
|
|
||||||
|
#Note: in versions prior to 1/2020, the 'disable' keyword to fix/gravity
|
||||||
|
# and the 'gravity' keyword to fix rigid/small were not available.
|
||||||
|
# These settings produce undesirable behavior, where gravity can induce
|
||||||
|
# torque on rigid bodies.
|
||||||
|
#fix gravfix all gravity 9.8 vector 0 0 -1 #disable
|
||||||
|
#fix rigidfix all rigid/small molecule mol mymol #gravity gravfix
|
||||||
|
|
||||||
|
#The correct behavior is recovered with the following settings:
|
||||||
|
fix gravfix all gravity 9.8 vector 0 0 -1 disable
|
||||||
|
fix rigidfix all rigid/small molecule mol mymol gravity gravfix
|
||||||
|
|
||||||
|
fix pourfix all pour 5 0 1234 region pourreg mol mymol rigid rigidfix
|
||||||
|
|
||||||
|
fix zwall all wall/gran hooke/history 4000.0 NULL 100.0 NULL 0.5 0 zplane 0.1 NULL
|
||||||
|
|
||||||
|
#dump 1 all custom 1000 molecule_pour.dump id type mass radius x y z fx fy fz
|
||||||
|
|
||||||
|
run 100000
|
||||||
|
|
||||||
41
examples/rigid/molecule.data
Normal file
41
examples/rigid/molecule.data
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
LAMMPS data file created for rigid body molecule template
|
||||||
|
|
||||||
|
5 atoms
|
||||||
|
|
||||||
|
2.3388800000000005 mass
|
||||||
|
|
||||||
|
6.002239704473936 4.99 4.989999999999999 com
|
||||||
|
|
||||||
|
116.79265620480001 144.26721336320003 144.26721336320006 -70.05220681600004 -70.05220681600002 -58.238345888000005 inertia
|
||||||
|
|
||||||
|
Coords
|
||||||
|
|
||||||
|
1 5 5 5
|
||||||
|
2 5.1 5.0 5.0
|
||||||
|
3 5.2 5.0 5.0
|
||||||
|
4 6.2 5.0 5.0
|
||||||
|
5 7.2 5.0 5.0
|
||||||
|
|
||||||
|
Types
|
||||||
|
|
||||||
|
1 1
|
||||||
|
2 1
|
||||||
|
3 1
|
||||||
|
4 1
|
||||||
|
5 1
|
||||||
|
|
||||||
|
Diameters
|
||||||
|
|
||||||
|
1 1.0
|
||||||
|
2 0.9
|
||||||
|
3 1.2
|
||||||
|
4 1.2
|
||||||
|
5 1.0
|
||||||
|
|
||||||
|
Masses
|
||||||
|
|
||||||
|
1 0.5235987755982988
|
||||||
|
2 0.3817035074111599
|
||||||
|
3 0.9047786842338602
|
||||||
|
4 0.9047786842338602
|
||||||
|
5 0.5235987755982988
|
||||||
@ -52,8 +52,8 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
torque(NULL), quat(NULL), imagebody(NULL), fflag(NULL),
|
torque(NULL), quat(NULL), imagebody(NULL), fflag(NULL),
|
||||||
tflag(NULL), langextra(NULL), sum(NULL), all(NULL),
|
tflag(NULL), langextra(NULL), sum(NULL), all(NULL),
|
||||||
remapflag(NULL), xcmimage(NULL), eflags(NULL), orient(NULL),
|
remapflag(NULL), xcmimage(NULL), eflags(NULL), orient(NULL),
|
||||||
dorient(NULL), id_dilate(NULL), random(NULL), avec_ellipsoid(NULL),
|
dorient(NULL), id_dilate(NULL), id_gravity(NULL), random(NULL),
|
||||||
avec_line(NULL), avec_tri(NULL)
|
avec_ellipsoid(NULL), avec_line(NULL), avec_tri(NULL)
|
||||||
{
|
{
|
||||||
int i,ibody;
|
int i,ibody;
|
||||||
|
|
||||||
@ -124,14 +124,17 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
if (custom_flag) {
|
if (custom_flag) {
|
||||||
if (narg < 5) error->all(FLERR,"Illegal fix rigid command");
|
if (narg < 5) error->all(FLERR,"Illegal fix rigid command");
|
||||||
|
|
||||||
// determine whether atom-style variable or atom property is used.
|
// determine whether atom-style variable or atom property is used
|
||||||
|
|
||||||
if (strstr(arg[4],"i_") == arg[4]) {
|
if (strstr(arg[4],"i_") == arg[4]) {
|
||||||
int is_double=0;
|
int is_double=0;
|
||||||
int custom_index = atom->find_custom(arg[4]+2,is_double);
|
int custom_index = atom->find_custom(arg[4]+2,is_double);
|
||||||
if (custom_index == -1)
|
if (custom_index == -1)
|
||||||
error->all(FLERR,"Fix rigid custom requires previously defined property/atom");
|
error->all(FLERR,"Fix rigid custom requires "
|
||||||
|
"previously defined property/atom");
|
||||||
else if (is_double)
|
else if (is_double)
|
||||||
error->all(FLERR,"Fix rigid custom requires integer-valued property/atom");
|
error->all(FLERR,"Fix rigid custom requires "
|
||||||
|
"integer-valued property/atom");
|
||||||
int minval = INT_MAX;
|
int minval = INT_MAX;
|
||||||
int *value = atom->ivector[custom_index];
|
int *value = atom->ivector[custom_index];
|
||||||
for (i = 0; i < nlocal; i++)
|
for (i = 0; i < nlocal; i++)
|
||||||
@ -163,12 +166,15 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
if (mask[i] & groupbit)
|
if (mask[i] & groupbit)
|
||||||
molecule[i] = (tagint)((tagint)value[i] - minval + 1);
|
molecule[i] = (tagint)((tagint)value[i] - minval + 1);
|
||||||
delete[] value;
|
delete[] value;
|
||||||
|
|
||||||
} else error->all(FLERR,"Unsupported fix rigid custom property");
|
} else error->all(FLERR,"Unsupported fix rigid custom property");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (atom->molecule_flag == 0)
|
if (atom->molecule_flag == 0)
|
||||||
error->all(FLERR,"Fix rigid molecule requires atom attribute molecule");
|
error->all(FLERR,"Fix rigid molecule requires atom attribute molecule");
|
||||||
molecule = atom->molecule;
|
molecule = atom->molecule;
|
||||||
}
|
}
|
||||||
|
|
||||||
iarg = 4 + custom_flag;
|
iarg = 4 + custom_flag;
|
||||||
|
|
||||||
tagint maxmol_tag = -1;
|
tagint maxmol_tag = -1;
|
||||||
@ -297,6 +303,7 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
// number of linear rigid bodies is counted later
|
// number of linear rigid bodies is counted later
|
||||||
|
|
||||||
nlinear = 0;
|
nlinear = 0;
|
||||||
|
|
||||||
// parse optional args
|
// parse optional args
|
||||||
@ -308,12 +315,14 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
tstat_flag = 0;
|
tstat_flag = 0;
|
||||||
pstat_flag = 0;
|
pstat_flag = 0;
|
||||||
allremap = 1;
|
allremap = 1;
|
||||||
id_dilate = NULL;
|
|
||||||
t_chain = 10;
|
t_chain = 10;
|
||||||
t_iter = 1;
|
t_iter = 1;
|
||||||
t_order = 3;
|
t_order = 3;
|
||||||
p_chain = 10;
|
p_chain = 10;
|
||||||
|
|
||||||
inpfile = NULL;
|
inpfile = NULL;
|
||||||
|
id_gravity = NULL;
|
||||||
|
id_dilate = NULL;
|
||||||
|
|
||||||
pcouple = NONE;
|
pcouple = NONE;
|
||||||
pstyle = ANISO;
|
pstyle = ANISO;
|
||||||
@ -543,12 +552,20 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
iarg += 2;
|
iarg += 2;
|
||||||
|
|
||||||
} else if (strcmp(arg[iarg],"reinit") == 0) {
|
} else if (strcmp(arg[iarg],"reinit") == 0) {
|
||||||
if (iarg+2 > narg) error->all(FLERR,"Illegal fix rigid/small command");
|
if (iarg+2 > narg) error->all(FLERR,"Illegal fix rigid command");
|
||||||
if (strcmp("yes",arg[iarg+1]) == 0) reinitflag = 1;
|
if (strcmp("yes",arg[iarg+1]) == 0) reinitflag = 1;
|
||||||
else if (strcmp("no",arg[iarg+1]) == 0) reinitflag = 0;
|
else if (strcmp("no",arg[iarg+1]) == 0) reinitflag = 0;
|
||||||
else error->all(FLERR,"Illegal fix rigid command");
|
else error->all(FLERR,"Illegal fix rigid command");
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
|
|
||||||
|
} else if (strcmp(arg[iarg],"gravity") == 0) {
|
||||||
|
if (iarg+2 > narg) error->all(FLERR,"Illegal fix rigid command");
|
||||||
|
delete [] id_gravity;
|
||||||
|
int n = strlen(arg[iarg+1]) + 1;
|
||||||
|
id_gravity = new char[n];
|
||||||
|
strcpy(id_gravity,arg[iarg+1]);
|
||||||
|
iarg += 2;
|
||||||
|
|
||||||
} else error->all(FLERR,"Illegal fix rigid command");
|
} else error->all(FLERR,"Illegal fix rigid command");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,6 +638,9 @@ FixRigid::~FixRigid()
|
|||||||
|
|
||||||
delete random;
|
delete random;
|
||||||
delete [] inpfile;
|
delete [] inpfile;
|
||||||
|
delete [] id_dilate;
|
||||||
|
delete [] id_gravity;
|
||||||
|
|
||||||
memory->destroy(mol2body);
|
memory->destroy(mol2body);
|
||||||
memory->destroy(body2mol);
|
memory->destroy(body2mol);
|
||||||
|
|
||||||
@ -687,7 +707,7 @@ void FixRigid::init()
|
|||||||
avec_tri = (AtomVecTri *) atom->style_match("tri");
|
avec_tri = (AtomVecTri *) atom->style_match("tri");
|
||||||
|
|
||||||
// warn if more than one rigid fix
|
// warn if more than one rigid fix
|
||||||
// if earlyflag, warn if any post-force fixes come after POEMS fix
|
// if earlyflag, warn if any post-force fixes come after a rigid fix
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (i = 0; i < modify->nfix; i++)
|
for (i = 0; i < modify->nfix; i++)
|
||||||
@ -701,24 +721,54 @@ void FixRigid::init()
|
|||||||
if (rflag && (modify->fmask[i] & POST_FORCE) &&
|
if (rflag && (modify->fmask[i] & POST_FORCE) &&
|
||||||
!modify->fix[i]->rigid_flag) {
|
!modify->fix[i]->rigid_flag) {
|
||||||
char str[128];
|
char str[128];
|
||||||
snprintf(str,128,"Fix %s alters forces after fix rigid",modify->fix[i]->id);
|
snprintf(str,128,"Fix %s alters forces after fix rigid",
|
||||||
|
modify->fix[i]->id);
|
||||||
error->warning(FLERR,str);
|
error->warning(FLERR,str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// warn if body properties are read from inpfile
|
||||||
|
// and the gravity keyword is not set and a gravity fix exists
|
||||||
|
// this could mean body particles are overlapped
|
||||||
|
// and gravity is not applied correctly
|
||||||
|
|
||||||
|
if (inpfile && !id_gravity) {
|
||||||
|
for (i = 0; i < modify->nfix; i++) {
|
||||||
|
if (strcmp(modify->fix[i]->style,"gravity") == 0) {
|
||||||
|
if (comm->me == 0)
|
||||||
|
error->warning(FLERR,"Gravity may not be correctly applied "
|
||||||
|
"to rigid bodies if they consist of "
|
||||||
|
"overlapped particles");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// error if npt,nph fix comes before rigid fix
|
// error if npt,nph fix comes before rigid fix
|
||||||
|
|
||||||
for (i = 0; i < modify->nfix; i++) {
|
for (i = 0; i < modify->nfix; i++) {
|
||||||
if (strcmp(modify->fix[i]->style,"npt") == 0) break;
|
if (strcmp(modify->fix[i]->style,"npt") == 0) break;
|
||||||
if (strcmp(modify->fix[i]->style,"nph") == 0) break;
|
if (strcmp(modify->fix[i]->style,"nph") == 0) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i < modify->nfix) {
|
if (i < modify->nfix) {
|
||||||
for (int j = i; j < modify->nfix; j++)
|
for (int j = i; j < modify->nfix; j++)
|
||||||
if (strcmp(modify->fix[j]->style,"rigid") == 0)
|
if (strcmp(modify->fix[j]->style,"rigid") == 0)
|
||||||
error->all(FLERR,"Rigid fix must come before NPT/NPH fix");
|
error->all(FLERR,"Rigid fix must come before NPT/NPH fix");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add gravity forces based on gravity vector from fix
|
||||||
|
|
||||||
|
if (id_gravity) {
|
||||||
|
int ifix = modify->find_fix(id_gravity);
|
||||||
|
if (ifix < 0) error->all(FLERR,"Fix rigid cannot find fix gravity ID");
|
||||||
|
if (strcmp(modify->fix[ifix]->style,"gravity") != 0)
|
||||||
|
error->all(FLERR,"Fix rigid gravity fix is invalid");
|
||||||
|
int tmp;
|
||||||
|
gvec = (double *) modify->fix[ifix]->extract("gvec",tmp);
|
||||||
|
}
|
||||||
|
|
||||||
// timestep info
|
// timestep info
|
||||||
|
|
||||||
dtv = update->dt;
|
dtv = update->dt;
|
||||||
@ -1061,8 +1111,17 @@ void FixRigid::compute_forces_and_torques()
|
|||||||
torque[ibody][1] = all[ibody][4] + langextra[ibody][4];
|
torque[ibody][1] = all[ibody][4] + langextra[ibody][4];
|
||||||
torque[ibody][2] = all[ibody][5] + langextra[ibody][5];
|
torque[ibody][2] = all[ibody][5] + langextra[ibody][5];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// add gravity force to COM of each body
|
||||||
|
|
||||||
|
if (id_gravity) {
|
||||||
|
for (ibody = 0; ibody < nbody; ibody++) {
|
||||||
|
fcm[ibody][0] += gvec[0]*masstotal[ibody];
|
||||||
|
fcm[ibody][1] += gvec[1]*masstotal[ibody];
|
||||||
|
fcm[ibody][2] += gvec[2]*masstotal[ibody];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|||||||
@ -66,7 +66,8 @@ class FixRigid : public Fix {
|
|||||||
double *step_respa;
|
double *step_respa;
|
||||||
int triclinic;
|
int triclinic;
|
||||||
|
|
||||||
char *inpfile; // file to read rigid body attributes from
|
char *inpfile; // file to read rigid body attributes from
|
||||||
|
|
||||||
int rstyle; // SINGLE,MOLECULE,GROUP
|
int rstyle; // SINGLE,MOLECULE,GROUP
|
||||||
int setupflag; // 1 if body properties are setup, else 0
|
int setupflag; // 1 if body properties are setup, else 0
|
||||||
int earlyflag; // 1 if forces/torques computed at post_force()
|
int earlyflag; // 1 if forces/torques computed at post_force()
|
||||||
@ -131,6 +132,9 @@ class FixRigid : public Fix {
|
|||||||
int dilate_group_bit; // mask for dilation group
|
int dilate_group_bit; // mask for dilation group
|
||||||
char *id_dilate; // group name to dilate
|
char *id_dilate; // group name to dilate
|
||||||
|
|
||||||
|
char *id_gravity; // ID of fix gravity command to add gravity forces
|
||||||
|
double *gvec; // ptr to gravity vector inside the fix
|
||||||
|
|
||||||
class RanMars *random;
|
class RanMars *random;
|
||||||
class AtomVecEllipsoid *avec_ellipsoid;
|
class AtomVecEllipsoid *avec_ellipsoid;
|
||||||
class AtomVecLine *avec_line;
|
class AtomVecLine *avec_line;
|
||||||
|
|||||||
@ -57,7 +57,7 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
xcmimage(NULL), displace(NULL), eflags(NULL), orient(NULL), dorient(NULL),
|
xcmimage(NULL), displace(NULL), eflags(NULL), orient(NULL), dorient(NULL),
|
||||||
avec_ellipsoid(NULL), avec_line(NULL), avec_tri(NULL), counts(NULL),
|
avec_ellipsoid(NULL), avec_line(NULL), avec_tri(NULL), counts(NULL),
|
||||||
itensor(NULL), mass_body(NULL), langextra(NULL), random(NULL),
|
itensor(NULL), mass_body(NULL), langextra(NULL), random(NULL),
|
||||||
id_dilate(NULL), onemols(NULL)
|
id_dilate(NULL), id_gravity(NULL), onemols(NULL)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -107,7 +107,8 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
bodyID = new tagint[nlocal];
|
bodyID = new tagint[nlocal];
|
||||||
customflag = 1;
|
customflag = 1;
|
||||||
|
|
||||||
// determine whether atom-style variable or atom property is used.
|
// determine whether atom-style variable or atom property is used
|
||||||
|
|
||||||
if (strstr(arg[4],"i_") == arg[4]) {
|
if (strstr(arg[4],"i_") == arg[4]) {
|
||||||
int is_double=0;
|
int is_double=0;
|
||||||
int custom_index = atom->find_custom(arg[4]+2,is_double);
|
int custom_index = atom->find_custom(arg[4]+2,is_double);
|
||||||
@ -356,6 +357,13 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
p_chain = force->numeric(FLERR,arg[iarg+1]);
|
p_chain = force->numeric(FLERR,arg[iarg+1]);
|
||||||
iarg += 2;
|
iarg += 2;
|
||||||
|
|
||||||
|
} else if (strcmp(arg[iarg],"gravity") == 0) {
|
||||||
|
if (iarg+2 > narg) error->all(FLERR,"Illegal fix rigid/small command");
|
||||||
|
delete [] id_gravity;
|
||||||
|
int n = strlen(arg[iarg+1]) + 1;
|
||||||
|
id_gravity = new char[n];
|
||||||
|
strcpy(id_gravity,arg[iarg+1]);
|
||||||
|
iarg += 2;
|
||||||
|
|
||||||
} else error->all(FLERR,"Illegal fix rigid/small command");
|
} else error->all(FLERR,"Illegal fix rigid/small command");
|
||||||
}
|
}
|
||||||
@ -515,6 +523,8 @@ FixRigidSmall::~FixRigidSmall()
|
|||||||
|
|
||||||
delete random;
|
delete random;
|
||||||
delete [] inpfile;
|
delete [] inpfile;
|
||||||
|
delete [] id_dilate;
|
||||||
|
delete [] id_gravity;
|
||||||
|
|
||||||
memory->destroy(langextra);
|
memory->destroy(langextra);
|
||||||
memory->destroy(mass_body);
|
memory->destroy(mass_body);
|
||||||
@ -543,6 +553,7 @@ void FixRigidSmall::init()
|
|||||||
triclinic = domain->triclinic;
|
triclinic = domain->triclinic;
|
||||||
|
|
||||||
// warn if more than one rigid fix
|
// warn if more than one rigid fix
|
||||||
|
// if earlyflag, warn if any post-force fixes come after a rigid fix
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (i = 0; i < modify->nfix; i++)
|
for (i = 0; i < modify->nfix; i++)
|
||||||
@ -563,6 +574,23 @@ void FixRigidSmall::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// warn if body properties are read from inpfile or a mol template file
|
||||||
|
// and the gravity keyword is not set and a gravity fix exists
|
||||||
|
// this could mean body particles are overlapped
|
||||||
|
// and gravity is not applied correctly
|
||||||
|
|
||||||
|
if ((inpfile || onemols) && !id_gravity) {
|
||||||
|
for (i = 0; i < modify->nfix; i++) {
|
||||||
|
if (strcmp(modify->fix[i]->style,"gravity") == 0) {
|
||||||
|
if (comm->me == 0)
|
||||||
|
error->warning(FLERR,"Gravity may not be correctly applied "
|
||||||
|
"to rigid bodies if they consist of "
|
||||||
|
"overlapped particles");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// error if npt,nph fix comes before rigid fix
|
// error if npt,nph fix comes before rigid fix
|
||||||
|
|
||||||
for (i = 0; i < modify->nfix; i++) {
|
for (i = 0; i < modify->nfix; i++) {
|
||||||
@ -575,6 +603,17 @@ void FixRigidSmall::init()
|
|||||||
error->all(FLERR,"Rigid fix must come before NPT/NPH fix");
|
error->all(FLERR,"Rigid fix must come before NPT/NPH fix");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add gravity forces based on gravity vector from fix
|
||||||
|
|
||||||
|
if (id_gravity) {
|
||||||
|
int ifix = modify->find_fix(id_gravity);
|
||||||
|
if (ifix < 0) error->all(FLERR,"Fix rigid/small cannot find fix gravity ID");
|
||||||
|
if (strcmp(modify->fix[ifix]->style,"gravity") != 0)
|
||||||
|
error->all(FLERR,"Fix rigid/small gravity fix is invalid");
|
||||||
|
int tmp;
|
||||||
|
gvec = (double *) modify->fix[ifix]->extract("gvec",tmp);
|
||||||
|
}
|
||||||
|
|
||||||
// timestep info
|
// timestep info
|
||||||
|
|
||||||
dtv = update->dt;
|
dtv = update->dt;
|
||||||
@ -954,8 +993,20 @@ void FixRigidSmall::compute_forces_and_torques()
|
|||||||
tcm[2] += langextra[ibody][5];
|
tcm[2] += langextra[ibody][5];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// add gravity force to COM of each body
|
||||||
|
|
||||||
|
if (id_gravity) {
|
||||||
|
double mass;
|
||||||
|
for (ibody = 0; ibody < nlocal_body; ibody++) {
|
||||||
|
mass = body[ibody].mass;
|
||||||
|
fcm = body[ibody].fcm;
|
||||||
|
fcm[0] += gvec[0]*mass;
|
||||||
|
fcm[1] += gvec[1]*mass;
|
||||||
|
fcm[2] += gvec[2]*mass;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|||||||
@ -164,6 +164,9 @@ class FixRigidSmall : public Fix {
|
|||||||
int dilate_group_bit; // mask for dilation group
|
int dilate_group_bit; // mask for dilation group
|
||||||
char *id_dilate; // group name to dilate
|
char *id_dilate; // group name to dilate
|
||||||
|
|
||||||
|
char *id_gravity; // ID of fix gravity command to add gravity forces
|
||||||
|
double *gvec; // ptr to gravity vector inside the fix
|
||||||
|
|
||||||
double p_current[3],p_target[3];
|
double p_current[3],p_target[3];
|
||||||
|
|
||||||
// molecules added on-the-fly as rigid bodies
|
// molecules added on-the-fly as rigid bodies
|
||||||
|
|||||||
@ -383,6 +383,19 @@ void FixRigidNHOMP::compute_forces_and_torques()
|
|||||||
torque[ibody][1] = all[ibody][4] + langextra[ibody][4];
|
torque[ibody][1] = all[ibody][4] + langextra[ibody][4];
|
||||||
torque[ibody][2] = all[ibody][5] + langextra[ibody][5];
|
torque[ibody][2] = all[ibody][5] + langextra[ibody][5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add gravity force to COM of each body
|
||||||
|
|
||||||
|
if (id_gravity) {
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
#pragma omp parallel for default(none) private(ibody) schedule(static)
|
||||||
|
#endif
|
||||||
|
for (ibody = 0; ibody < nbody; ibody++) {
|
||||||
|
fcm[ibody][0] += gvec[0]*masstotal[ibody];
|
||||||
|
fcm[ibody][1] += gvec[1]*masstotal[ibody];
|
||||||
|
fcm[ibody][2] += gvec[2]*masstotal[ibody];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|||||||
@ -256,6 +256,19 @@ void FixRigidOMP::compute_forces_and_torques()
|
|||||||
torque[ibody][1] = all[ibody][4] + langextra[ibody][4];
|
torque[ibody][1] = all[ibody][4] + langextra[ibody][4];
|
||||||
torque[ibody][2] = all[ibody][5] + langextra[ibody][5];
|
torque[ibody][2] = all[ibody][5] + langextra[ibody][5];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add gravity force to COM of each body
|
||||||
|
|
||||||
|
if (id_gravity) {
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
#pragma omp parallel for default(none) private(ibody) schedule(static)
|
||||||
|
#endif
|
||||||
|
for (int ibody = 0; ibody < nbody; ibody++) {
|
||||||
|
fcm[ibody][0] += gvec[0]*masstotal[ibody];
|
||||||
|
fcm[ibody][1] += gvec[1]*masstotal[ibody];
|
||||||
|
fcm[ibody][2] += gvec[2]*masstotal[ibody];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|||||||
@ -196,6 +196,21 @@ void FixRigidSmallOMP::compute_forces_and_torques()
|
|||||||
tcm[2] += langextra[ibody][5];
|
tcm[2] += langextra[ibody][5];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add gravity force to COM of each body
|
||||||
|
|
||||||
|
if (id_gravity) {
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
#pragma omp parallel for default(none) private(ibody) schedule(static)
|
||||||
|
#endif
|
||||||
|
for (int ibody = 0; ibody < nbody; ibody++) {
|
||||||
|
double * _noalias const fcm = body[ibody].fcm;
|
||||||
|
const double mass = body[ibody].mass;
|
||||||
|
fcm[0] += gvec[0]*mass;
|
||||||
|
fcm[1] += gvec[1]*mass;
|
||||||
|
fcm[2] += gvec[2]*mass;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|||||||
@ -37,7 +37,8 @@ enum{CONSTANT,EQUAL};
|
|||||||
|
|
||||||
FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) :
|
FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) :
|
||||||
Fix(lmp, narg, arg),
|
Fix(lmp, narg, arg),
|
||||||
mstr(NULL), vstr(NULL), pstr(NULL), tstr(NULL), xstr(NULL), ystr(NULL), zstr(NULL)
|
mstr(NULL), vstr(NULL), pstr(NULL), tstr(NULL),
|
||||||
|
xstr(NULL), ystr(NULL), zstr(NULL)
|
||||||
{
|
{
|
||||||
if (narg < 5) error->all(FLERR,"Illegal fix gravity command");
|
if (narg < 5) error->all(FLERR,"Illegal fix gravity command");
|
||||||
|
|
||||||
@ -61,8 +62,10 @@ FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
mstyle = CONSTANT;
|
mstyle = CONSTANT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iarg;
|
||||||
|
|
||||||
if (strcmp(arg[4],"chute") == 0) {
|
if (strcmp(arg[4],"chute") == 0) {
|
||||||
if (narg != 6) error->all(FLERR,"Illegal fix gravity command");
|
if (narg < 6) error->all(FLERR,"Illegal fix gravity command");
|
||||||
style = CHUTE;
|
style = CHUTE;
|
||||||
if (strstr(arg[5],"v_") == arg[5]) {
|
if (strstr(arg[5],"v_") == arg[5]) {
|
||||||
int n = strlen(&arg[5][2]) + 1;
|
int n = strlen(&arg[5][2]) + 1;
|
||||||
@ -73,9 +76,10 @@ FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
vert = force->numeric(FLERR,arg[5]);
|
vert = force->numeric(FLERR,arg[5]);
|
||||||
vstyle = CONSTANT;
|
vstyle = CONSTANT;
|
||||||
}
|
}
|
||||||
|
iarg = 6;
|
||||||
|
|
||||||
} else if (strcmp(arg[4],"spherical") == 0) {
|
} else if (strcmp(arg[4],"spherical") == 0) {
|
||||||
if (narg != 7) error->all(FLERR,"Illegal fix gravity command");
|
if (narg < 7) error->all(FLERR,"Illegal fix gravity command");
|
||||||
style = SPHERICAL;
|
style = SPHERICAL;
|
||||||
if (strstr(arg[5],"v_") == arg[5]) {
|
if (strstr(arg[5],"v_") == arg[5]) {
|
||||||
int n = strlen(&arg[5][2]) + 1;
|
int n = strlen(&arg[5][2]) + 1;
|
||||||
@ -95,9 +99,10 @@ FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
theta = force->numeric(FLERR,arg[6]);
|
theta = force->numeric(FLERR,arg[6]);
|
||||||
tstyle = CONSTANT;
|
tstyle = CONSTANT;
|
||||||
}
|
}
|
||||||
|
iarg = 7;
|
||||||
|
|
||||||
} else if (strcmp(arg[4],"vector") == 0) {
|
} else if (strcmp(arg[4],"vector") == 0) {
|
||||||
if (narg != 8) error->all(FLERR,"Illegal fix gravity command");
|
if (narg < 8) error->all(FLERR,"Illegal fix gravity command");
|
||||||
style = VECTOR;
|
style = VECTOR;
|
||||||
if (strstr(arg[5],"v_") == arg[5]) {
|
if (strstr(arg[5],"v_") == arg[5]) {
|
||||||
int n = strlen(&arg[5][2]) + 1;
|
int n = strlen(&arg[5][2]) + 1;
|
||||||
@ -126,9 +131,23 @@ FixGravity::FixGravity(LAMMPS *lmp, int narg, char **arg) :
|
|||||||
zdir = force->numeric(FLERR,arg[7]);
|
zdir = force->numeric(FLERR,arg[7]);
|
||||||
zstyle = CONSTANT;
|
zstyle = CONSTANT;
|
||||||
}
|
}
|
||||||
|
iarg = 8;
|
||||||
|
|
||||||
} else error->all(FLERR,"Illegal fix gravity command");
|
} else error->all(FLERR,"Illegal fix gravity command");
|
||||||
|
|
||||||
|
// optional keywords
|
||||||
|
|
||||||
|
disable = 0;
|
||||||
|
|
||||||
|
while (iarg < narg) {
|
||||||
|
if (strcmp(arg[iarg],"disable") == 0) {
|
||||||
|
disable = 1;
|
||||||
|
iarg++;
|
||||||
|
} else error->all(FLERR,"Illegal fix gravity command");
|
||||||
|
}
|
||||||
|
|
||||||
|
// initializations
|
||||||
|
|
||||||
degree2rad = MY_PI/180.0;
|
degree2rad = MY_PI/180.0;
|
||||||
time_origin = update->ntimestep;
|
time_origin = update->ntimestep;
|
||||||
|
|
||||||
@ -266,6 +285,12 @@ void FixGravity::post_force(int /*vflag*/)
|
|||||||
set_acceleration();
|
set_acceleration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// just exit if application of force is disabled
|
||||||
|
|
||||||
|
if (disable) return;
|
||||||
|
|
||||||
|
// apply gravity force to each particle
|
||||||
|
|
||||||
double **x = atom->x;
|
double **x = atom->x;
|
||||||
double **f = atom->f;
|
double **f = atom->f;
|
||||||
double *rmass = atom->rmass;
|
double *rmass = atom->rmass;
|
||||||
@ -338,9 +363,9 @@ void FixGravity::set_acceleration()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xacc = magnitude*xgrav;
|
gvec[0] = xacc = magnitude*xgrav;
|
||||||
yacc = magnitude*ygrav;
|
gvec[1] = yacc = magnitude*ygrav;
|
||||||
zacc = magnitude*zgrav;
|
gvec[2] = zacc = magnitude*zgrav;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
@ -357,3 +382,16 @@ double FixGravity::compute_scalar()
|
|||||||
}
|
}
|
||||||
return egrav_all;
|
return egrav_all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
extract current gravity direction vector
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void *FixGravity::extract(const char *name, int &dim)
|
||||||
|
{
|
||||||
|
if (strcmp(name,"gvec") == 0) {
|
||||||
|
dim = 1;
|
||||||
|
return (void *) gvec;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|||||||
@ -36,9 +36,10 @@ class FixGravity : public Fix {
|
|||||||
virtual void post_force(int);
|
virtual void post_force(int);
|
||||||
virtual void post_force_respa(int, int, int);
|
virtual void post_force_respa(int, int, int);
|
||||||
double compute_scalar();
|
double compute_scalar();
|
||||||
|
void *extract(const char *, int &);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int style;
|
int style,disable;
|
||||||
double magnitude;
|
double magnitude;
|
||||||
double vert,phi,theta;
|
double vert,phi,theta;
|
||||||
double xdir,ydir,zdir;
|
double xdir,ydir,zdir;
|
||||||
@ -46,6 +47,8 @@ class FixGravity : public Fix {
|
|||||||
double degree2rad;
|
double degree2rad;
|
||||||
int ilevel_respa;
|
int ilevel_respa;
|
||||||
int time_origin;
|
int time_origin;
|
||||||
|
double gvec[3];
|
||||||
|
|
||||||
int eflag;
|
int eflag;
|
||||||
double egrav,egrav_all;
|
double egrav,egrav_all;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user