Unverified Commit c5768acb authored by Axel Kohlmeyer's avatar Axel Kohlmeyer Committed by GitHub
Browse files

Merge pull request #1801 from lammps/rigid-gravity

enable fix rigid commands to add gravity to COM of rigid bodies
parents 97a798c7 1cd6d302
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
#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 −0
Original line number Diff line number Diff line
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
+69 −10
Original line number Diff line number Diff line
@@ -52,8 +52,8 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
  torque(NULL), quat(NULL), imagebody(NULL), fflag(NULL),
  tflag(NULL), langextra(NULL), sum(NULL), all(NULL),
  remapflag(NULL), xcmimage(NULL), eflags(NULL), orient(NULL),
  dorient(NULL), id_dilate(NULL), random(NULL), avec_ellipsoid(NULL),
  avec_line(NULL), avec_tri(NULL)
  dorient(NULL), id_dilate(NULL), id_gravity(NULL), random(NULL),
  avec_ellipsoid(NULL), avec_line(NULL), avec_tri(NULL)
{
  int i,ibody;

@@ -124,14 +124,17 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
    if (custom_flag) {
      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]) {
        int is_double=0;
        int custom_index = atom->find_custom(arg[4]+2,is_double);
        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)
          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 *value = atom->ivector[custom_index];
        for (i = 0; i < nlocal; i++)
@@ -163,12 +166,15 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
          if (mask[i] & groupbit)
            molecule[i] = (tagint)((tagint)value[i] - minval + 1);
        delete[] value;

      } else error->all(FLERR,"Unsupported fix rigid custom property");

    } else {
      if (atom->molecule_flag == 0)
        error->all(FLERR,"Fix rigid molecule requires atom attribute molecule");
      molecule = atom->molecule;
    }

    iarg = 4 + custom_flag;

    tagint maxmol_tag = -1;
@@ -297,6 +303,7 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
  }

  // number of linear rigid bodies is counted later

  nlinear = 0;

  // parse optional args
@@ -308,12 +315,14 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
  tstat_flag = 0;
  pstat_flag = 0;
  allremap = 1;
  id_dilate = NULL;
  t_chain = 10;
  t_iter = 1;
  t_order = 3;
  p_chain = 10;

  inpfile = NULL;
  id_gravity = NULL;
  id_dilate = NULL;

  pcouple = NONE;
  pstyle = ANISO;
@@ -543,12 +552,20 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
      iarg += 2;

    } 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;
      else if  (strcmp("no",arg[iarg+1]) == 0) reinitflag = 0;
      else error->all(FLERR,"Illegal fix rigid command");
      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");
  }

@@ -621,6 +638,9 @@ FixRigid::~FixRigid()

  delete random;
  delete [] inpfile;
  delete [] id_dilate;
  delete [] id_gravity;

  memory->destroy(mol2body);
  memory->destroy(body2mol);

@@ -687,7 +707,7 @@ void FixRigid::init()
  avec_tri = (AtomVecTri *) atom->style_match("tri");

  // 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;
  for (i = 0; i < modify->nfix; i++)
@@ -701,24 +721,54 @@ void FixRigid::init()
      if (rflag && (modify->fmask[i] & POST_FORCE) &&
          !modify->fix[i]->rigid_flag) {
        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);
      }
    }
  }

  // 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

  for (i = 0; i < modify->nfix; i++) {
    if (strcmp(modify->fix[i]->style,"npt") == 0) break;
    if (strcmp(modify->fix[i]->style,"nph") == 0) break;
  }

  if (i < modify->nfix) {
    for (int j = i; j < modify->nfix; j++)
      if (strcmp(modify->fix[j]->style,"rigid") == 0)
        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

  dtv = update->dt;
@@ -1061,8 +1111,17 @@ void FixRigid::compute_forces_and_torques()
    torque[ibody][1] = all[ibody][4] + langextra[ibody][4];
    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];
    }
  }
}

/* ---------------------------------------------------------------------- */

+5 −1
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ class FixRigid : public Fix {
  int triclinic;

  char *inpfile;            // file to read rigid body attributes from

  int rstyle;               // SINGLE,MOLECULE,GROUP
  int setupflag;            // 1 if body properties are setup, else 0
  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
  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 AtomVecEllipsoid *avec_ellipsoid;
  class AtomVecLine *avec_line;
+54 −3
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) :
  xcmimage(NULL), displace(NULL), eflags(NULL), orient(NULL), dorient(NULL),
  avec_ellipsoid(NULL), avec_line(NULL), avec_tri(NULL), counts(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;

@@ -107,7 +107,8 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) :
      bodyID = new tagint[nlocal];
      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]) {
        int is_double=0;
        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]);
      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");
  }
@@ -515,6 +523,8 @@ FixRigidSmall::~FixRigidSmall()

  delete random;
  delete [] inpfile;
  delete [] id_dilate;
  delete [] id_gravity;

  memory->destroy(langextra);
  memory->destroy(mass_body);
@@ -543,6 +553,7 @@ void FixRigidSmall::init()
  triclinic = domain->triclinic;

  // warn if more than one rigid fix
  // if earlyflag, warn if any post-force fixes come after a rigid fix

  int count = 0;
  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

  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");
  }

  // 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

  dtv = update->dt;
@@ -954,8 +993,20 @@ void FixRigidSmall::compute_forces_and_torques()
      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;
    }
  }
}

/* ---------------------------------------------------------------------- */

Loading