Commit fc89638b authored by sjplimp's avatar sjplimp
Browse files

git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@2922 f3b2605a-c512-4ea7-a41b-209d697bcdaa
parent 9248f42b
Loading
Loading
Loading
Loading
+487 −79
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@
#include "stdlib.h"
#include "string.h"
#include "fix_rigid.h"
#include "math_extra.h"
#include "atom.h"
#include "atom_vec.h"
#include "domain.h"
#include "update.h"
#include "respa.h"
@@ -51,8 +53,12 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
  // perform initial allocation of atom-based arrays
  // register with Atom class

  extended = dorientflag = qorientflag = 0;
  body = NULL;
  displace = NULL;
  eflags = NULL;
  dorient = NULL;
  qorient = NULL;
  grow_arrays(atom->nmax);
  atom->add_callback(0);

@@ -299,6 +305,17 @@ FixRigid::FixRigid(LAMMPS *lmp, int narg, char **arg) :
  for (ibody = 0; ibody < nbody; ibody++)
    image[ibody] = (512 << 20) | (512 << 10) | 512;

  // bitmasks for properties of extended particles

  INERTIA_SPHERE_RADIUS = 1;
  INERTIA_SPHERE_SHAPE = 2;
  INERTIA_ELLIPSOID = 4;
  ORIENT_DIPOLE = 8;
  ORIENT_QUAT = 16;
  OMEGA = 32;
  ANGMOM = 64;
  TORQUE = 128;

  // print statistics

  int nsum = 0;
@@ -322,6 +339,9 @@ FixRigid::~FixRigid()
  
  memory->sfree(body);
  memory->destroy_2d_double_array(displace);
  memory->sfree(eflags);
  memory->destroy_2d_double_array(dorient);
  memory->destroy_2d_double_array(qorient);
  
  // delete nbody-length arrays

@@ -364,7 +384,7 @@ int FixRigid::setmask()

void FixRigid::init()
{
  int i,ibody;
  int i,itype,ibody;

  triclinic = domain->triclinic;

@@ -396,15 +416,81 @@ void FixRigid::init()
  if (strcmp(update->integrate_style,"respa") == 0)
    step_respa = ((Respa *) update->integrate)->step;

  // compute masstotal & center-of-mass of each rigid body
  // extended = 1 if any particle in a rigid body is finite size

  double **x = atom->x;
  double *radius = atom->radius;
  double *rmass = atom->rmass;
  double *mass = atom->mass;
  int *image = atom->image;
  double **shape = atom->shape;
  double *dipole = atom->dipole;
  int *type = atom->type;
  int nlocal = atom->nlocal;

  if (atom->radius_flag || atom->avec->shape_type) {
    int flag = 0;
    for (i = 0; i < nlocal; i++) {
      if (body[i] < 0) continue;
      if (radius && radius[i] > 0.0) flag = 1;
      else if (shape && shape[type[i]][0] > 0.0) flag = 1;
    }

    MPI_Allreduce(&flag,&extended,1,MPI_INT,MPI_MAX,world);
  }

  // grow extended arrays and set extended flags for each particle
  // vorientflag = 1 if any particles store dipole orientation
  // qorientflag = 1 if any particles store quat orientation

  if (extended) {
    if (atom->mu_flag) dorientflag = 1;
    if (atom->quat_flag) qorientflag = 1;
    grow_arrays(atom->nmax);

    for (i = 0; i < nlocal; i++) {
      eflags[i] = 0;
      if (body[i] < 0) continue;

      // set INERTIA if radius or shape > 0.0

      if (radius) {
	if (radius[i] > 0.0) eflags[i] |= INERTIA_SPHERE_RADIUS;
      } else if (shape) {
	if (shape[type[i]][0] > 0.0) {
	  if (shape[type[i]][0] == shape[type[i]][1] &&
	      shape[type[i]][0] == shape[type[i]][2])
	    eflags[i] |= INERTIA_SPHERE_SHAPE;
	  else eflags[i] |= INERTIA_ELLIPSOID;
	}
      }

      // other flags only set if particle is finite size
      // set DIPOLE if atom->mu and atom->dipole exist and dipole[itype] > 0.0
      // set QUAT if atom->quat exists (could be ellipsoid or sphere)
      // set TORQUE if atom->torque exists
      // set exactly one of OMEGA and ANGMOM so particle contributes once
      // set OMEGA if either radius or rmass exists
      // set ANGMOM if shape and mass exist
      // set OMEGE if atom->angmom doesn't exist

      if (eflags[i] == 0) continue;

      if (atom->mu_flag && dipole && dipole[type[i]] > 0.0)
	eflags[i] |= ORIENT_DIPOLE;
      if (atom->quat_flag) eflags[i] |= ORIENT_QUAT;
      if (atom->torque_flag) eflags[i] |= TORQUE;
      if ((radius || rmass) && atom->omega_flag) eflags[i] |= OMEGA;
      else if (shape && mass && atom->angmom_flag) eflags[i] |= ANGMOM;
      else if (atom->omega_flag) eflags[i] != OMEGA;
      else error->one("Could not set finite-size particle attribute "
		      "in fix rigid");
    }
  }

  // compute masstotal & center-of-mass of each rigid body
  
  double **x = atom->x;
  int *image = atom->image;
  
  double xprd = domain->xprd;
  double yprd = domain->yprd;
  double zprd = domain->zprd;
@@ -460,9 +546,10 @@ void FixRigid::init()
  // compute 6 moments of inertia of each body
  // dx,dy,dz = coords relative to center-of-mass
  
  double dx,dy,dz,rad;

  for (ibody = 0; ibody < nbody; ibody++)
    for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
  double dx,dy,dz;

  for (i = 0; i < nlocal; i++) {
    if (body[i] < 0) continue;
@@ -485,6 +572,7 @@ void FixRigid::init()
    dx = xunwrap - xcm[ibody][0];
    dy = yunwrap - xcm[ibody][1];
    dz = zunwrap - xcm[ibody][2];

    if (rmass) massone = rmass[i];
    else massone = mass[type[i]];

@@ -496,6 +584,55 @@ void FixRigid::init()
    sum[ibody][5] -= massone * dx*dz;
  }

  // extended particles contribute extra terms to moments of inertia

  if (extended) {
    double ex[3],ey[3],ez[3],idiag[3];
    double p[3][3],ptrans[3][3],ispace[3][3],itemp[3][3];

    double *radius = atom->radius;
    double **shape = atom->shape;

    for (i = 0; i < nlocal; i++) {
      if (body[i] < 0) continue;
      ibody = body[i];

      itype = type[i];
      if (rmass) massone = rmass[i];
      else massone = mass[itype];

      if (eflags[i] & INERTIA_SPHERE_RADIUS) {
	sum[ibody][0] += 0.4 * massone * radius[i]*radius[i];
	sum[ibody][1] += 0.4 * massone * radius[i]*radius[i];
	sum[ibody][2] += 0.4 * massone * radius[i]*radius[i];
      }
      if (eflags[i] & INERTIA_SPHERE_SHAPE) {
	rad = shape[type[i]][0];
	sum[ibody][0] += 0.4 * massone * rad*rad;
	sum[ibody][1] += 0.4 * massone * rad*rad;
	sum[ibody][2] += 0.4 * massone * rad*rad;
      }
      if (eflags[i] & INERTIA_ELLIPSOID) {
	MathExtra::quat_to_mat(atom->quat[i],p);
	MathExtra::quat_to_mat_trans(atom->quat[i],ptrans);
	idiag[0] = 0.2*massone *
	  (shape[itype][1]*shape[itype][1]+shape[itype][2]*shape[itype][2]);
	idiag[1] = 0.2*massone *
	  (shape[itype][0]*shape[itype][0]+shape[itype][2]*shape[itype][2]);
	idiag[2] = 0.2*massone *
	  (shape[itype][0]*shape[itype][0]+shape[itype][1]*shape[itype][1]);
	MathExtra::diag_times3(idiag,ptrans,itemp);
	MathExtra::times3(p,itemp,ispace);
	sum[ibody][0] += ispace[0][0];
	sum[ibody][1] += ispace[1][1];
	sum[ibody][2] += ispace[2][2];
	sum[ibody][3] += ispace[0][1];
	sum[ibody][4] += ispace[1][2];
	sum[ibody][5] += ispace[0][2];
      }
    }
  }
  
  MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
  
  // inertia = 3 eigenvalues = principal moments of inertia
@@ -569,10 +706,16 @@ void FixRigid::init()
  
  // displace = initial atom coords in basis of principal axes
  // set displace = 0.0 for atoms not in any rigid body
  // for extended particles, set their orientation wrt to rigid body

  double qc[4];

  for (i = 0; i < nlocal; i++) {
    if (body[i] < 0) displace[i][0] = displace[i][1] = displace[i][2] = 0.0;
    else {
    if (body[i] < 0) {
      displace[i][0] = displace[i][1] = displace[i][2] = 0.0;
      continue;
    }

    ibody = body[i];

    xbox = (image[i] & 1023) - 512;
@@ -599,6 +742,29 @@ void FixRigid::init()
      dz*ey_space[ibody][2];
    displace[i][2] = dx*ez_space[ibody][0] + dy*ez_space[ibody][1] +
      dz*ez_space[ibody][2];
    
    if (extended) {
      double **mu = atom->mu;
      double *dipole = atom->dipole;
      int *type = atom->type;

      if (eflags[i] & ORIENT_DIPOLE) {
	dorient[i][0] = mu[i][0]*ex_space[ibody][0] + 
	  mu[i][1]*ex_space[ibody][1] + mu[i][2]*ex_space[ibody][2];
	dorient[i][1] = mu[i][0]*ey_space[ibody][0] + 
	  mu[i][1]*ey_space[ibody][1] + mu[i][2]*ey_space[ibody][2];
	dorient[i][2] = mu[i][0]*ez_space[ibody][0] + 
	  mu[i][1]*ez_space[ibody][1] + mu[i][2]*ez_space[ibody][2];
	MathExtra::snormalize3(dipole[type[i]],dorient[i],dorient[i]);
      } else if (dorientflag)
	dorient[i][0] = dorient[i][1] = dorient[i][2] = 0.0;

      if (eflags[i] & ORIENT_QUAT) {
	qconjugate(quat[ibody],qc);
	quatquat(qc,atom->quat[i],qorient[i]);
	qnormalize(qorient[i]);
      } else if (qorientflag)
	qorient[i][0] = qorient[i][1] = qorient[i][2] = qorient[i][3] = 0.0;
    }
  }
  
@@ -606,6 +772,7 @@ void FixRigid::init()
  // recompute moments of inertia around new axes
  // 3 diagonal moments should equal principal moments
  // 3 off-diagonal moments should be 0.0
  // extended particles contribute extra terms to moments of inertia
  
  for (ibody = 0; ibody < nbody; ibody++)
    for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
@@ -627,6 +794,53 @@ void FixRigid::init()
    sum[ibody][5] -= massone * displace[i][0]*displace[i][2];
  }

  if (extended) {
    double ex[3],ey[3],ez[3],idiag[3];
    double p[3][3],ptrans[3][3],ispace[3][3],itemp[3][3];

    double *radius = atom->radius;
    double **shape = atom->shape;

    for (i = 0; i < nlocal; i++) {
      if (body[i] < 0) continue;
      ibody = body[i];

      itype = type[i];
      if (rmass) massone = rmass[i];
      else massone = mass[itype];

      if (eflags[i] & INERTIA_SPHERE_RADIUS) {
	sum[ibody][0] += 0.4 * massone * radius[i]*radius[i];
	sum[ibody][1] += 0.4 * massone * radius[i]*radius[i];
	sum[ibody][2] += 0.4 * massone * radius[i]*radius[i];
      }
      if (eflags[i] & INERTIA_SPHERE_SHAPE) {
	rad = shape[type[i]][0];
	sum[ibody][0] += 0.4 * massone * rad*rad;
	sum[ibody][1] += 0.4 * massone * rad*rad;
	sum[ibody][2] += 0.4 * massone * rad*rad;
      }
      if (eflags[i] & INERTIA_ELLIPSOID) {
	MathExtra::quat_to_mat(qorient[i],p);
	MathExtra::quat_to_mat_trans(qorient[i],ptrans);
	idiag[0] = 0.2*massone *
	  (shape[itype][1]*shape[itype][1]+shape[itype][2]*shape[itype][2]);
	idiag[1] = 0.2*massone *
	  (shape[itype][0]*shape[itype][0]+shape[itype][2]*shape[itype][2]);
	idiag[2] = 0.2*massone *
	  (shape[itype][0]*shape[itype][0]+shape[itype][1]*shape[itype][1]);
	MathExtra::diag_times3(idiag,ptrans,itemp);
	MathExtra::times3(p,itemp,ispace);
	sum[ibody][0] += ispace[0][0];
	sum[ibody][1] += ispace[1][1];
	sum[ibody][2] += ispace[2][2];
	sum[ibody][3] += ispace[0][1];
	sum[ibody][4] += ispace[1][2];
	sum[ibody][5] += ispace[0][2];
      }
    }
  }

  MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);

  for (ibody = 0; ibody < nbody; ibody++) {
@@ -663,20 +877,20 @@ void FixRigid::init()
void FixRigid::setup(int vflag)
{
  int i,n,ibody;
  double massone,radone;
  
  // vcm = velocity of center-of-mass of each rigid body
  // fcm = force on center-of-mass of each rigid body

  int *type = atom->type;
  double **v = atom->v;
  double **f = atom->f;
  double *rmass = atom->rmass;
  double *mass = atom->mass;
  int *type = atom->type;
  int nlocal = atom->nlocal;

  for (ibody = 0; ibody < nbody; ibody++)
    for (i = 0; i < 6; i++) sum[ibody][i] = 0.0;
  double massone;
  
  for (i = 0; i < nlocal; i++) {
    if (body[i] < 0) continue;
@@ -754,6 +968,42 @@ void FixRigid::setup(int vflag)
    sum[ibody][5] += dx * f[i][1] - dy * f[i][0];
  }

  // extended particles add their rotation/torque to angmom/torque of body

  if (extended) {
    double **omega_one = atom->omega;
    double **angmom_one = atom->angmom;
    double **torque_one = atom->torque;
    double *radius = atom->radius;
    double **shape = atom->shape;

    for (i = 0; i < nlocal; i++) {
      if (body[i] < 0) continue;
      ibody = body[i];

      if (eflags[i] & OMEGA) {
	if (rmass) massone = rmass[i];
	else massone = mass[type[i]];
	if (radius) radone = radius[i];
	else radone = shape[type[i]][0];
	sum[ibody][0] += 0.4 * massone * radone*radone * omega_one[i][0];
	sum[ibody][1] += 0.4 * massone * radone*radone * omega_one[i][1];
	sum[ibody][2] += 0.4 * massone * radone*radone * omega_one[i][2];
      }

      if (eflags[i] & ANGMOM) {
	sum[ibody][0] += angmom_one[i][0];
	sum[ibody][1] += angmom_one[i][1];
	sum[ibody][2] += angmom_one[i][2];
      }
      if (eflags[i] & TORQUE) {
	sum[ibody][3] += torque_one[i][0];
	sum[ibody][4] += torque_one[i][1];
	sum[ibody][5] += torque_one[i][2];
      }
    }
  }
  
  MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);

  for (ibody = 0; ibody < nbody; ibody++) {
@@ -777,7 +1027,7 @@ void FixRigid::setup(int vflag)
		      ez_space[ibody],inertia[ibody],omega[ibody]);
  set_v();

  // guestimate virial as 2x the set_v contribution
  // guesstimate virial as 2x the set_v contribution

  if (vflag_global)
    for (n = 0; n < 6; n++) virial[n] *= 2.0;
@@ -829,7 +1079,7 @@ void FixRigid::initial_integrate(int vflag)
  if (vflag) v_setup(vflag);
  else evflag = 0;

  // set coords and velocities of atoms in rigid bodies
  // set coords/orient and velocity/rotation of atoms in rigid bodies
  // from quarternion and omega
  
  set_xv();
@@ -856,7 +1106,7 @@ void FixRigid::richardson(double *q, double *w,
  qfull[2] = q[2] + dtq * wq[2];
  qfull[3] = q[3] + dtq * wq[3];

  normalize(qfull);
  qnormalize(qfull);

  // 1st half update from dq/dt = 1/2 w q

@@ -866,7 +1116,7 @@ void FixRigid::richardson(double *q, double *w,
  qhalf[2] = q[2] + 0.5*dtq * wq[2];
  qhalf[3] = q[3] + 0.5*dtq * wq[3];

  normalize(qhalf);
  qnormalize(qhalf);

  // udpate ex,ey,ez from qhalf
  // re-compute omega at 1/2 step from m at 1/2 step and q at 1/2 step
@@ -883,7 +1133,7 @@ void FixRigid::richardson(double *q, double *w,
  qhalf[2] += 0.5*dtq * wq[2];
  qhalf[3] += 0.5*dtq * wq[3];

  normalize(qhalf);
  qnormalize(qhalf);

  // corrected Richardson update

@@ -892,7 +1142,7 @@ void FixRigid::richardson(double *q, double *w,
  q[2] = 2.0*qhalf[2] - qfull[2];
  q[3] = 2.0*qhalf[3] - qfull[3];

  normalize(q);
  qnormalize(q);
  exyz_from_q(q,ex,ey,ez);
}

@@ -904,7 +1154,7 @@ void FixRigid::final_integrate()
  double dtfm;
  double xy,xz,yz;

  // sum forces and torques on atoms in rigid body
  // sum over atoms to get force and torque on rigid body
  
  int *image = atom->image;
  double **x = atom->x;
@@ -956,6 +1206,23 @@ void FixRigid::final_integrate()
    sum[ibody][5] += dx*f[i][1] - dy*f[i][0];
  }

  // extended particles add their torque to torque of body

  if (extended) {
    double **torque_one = atom->torque;

    for (i = 0; i < nlocal; i++) {
      if (body[i] < 0) continue;
      ibody = body[i];

      if (eflags[i] & TORQUE) {
	sum[ibody][3] += torque_one[i][0];
	sum[ibody][4] += torque_one[i][1];
	sum[ibody][5] += torque_one[i][2];
      }
    }
  }

  MPI_Allreduce(sum[0],all[0],6*nbody,MPI_DOUBLE,MPI_SUM,world);
  
  for (ibody = 0; ibody < nbody; ibody++) {
@@ -980,7 +1247,7 @@ void FixRigid::final_integrate()
    angmom[ibody][2] += dtf * torque[ibody][2] * tflag[ibody][2];
  }

  // set velocities from angmom & omega
  // set velocity/rotation of atoms in rigid bodies
  // virial is already setup from initial_integrate

  for (ibody = 0; ibody < nbody; ibody++) 
@@ -1238,7 +1505,7 @@ void FixRigid::rotate(double **matrix, int i, int j, int k, int l,
}

/* ----------------------------------------------------------------------
   create quaternion from space-frame ex,ey,ez
   create unit quaternion from space-frame ex,ey,ez
   ex,ey,ez are columns of a rotation matrix
------------------------------------------------------------------------- */

@@ -1277,7 +1544,7 @@ void FixRigid::q_from_exyz(double *ex, double *ey, double *ez, double *q)
  } else
    error->all("Quaternion creation numeric error");

  normalize(q);
  qnormalize(q);
}

/* ----------------------------------------------------------------------
@@ -1331,17 +1598,30 @@ void FixRigid::quatvec(double *a, double *b, double *c)

void FixRigid::quatquat(double *a, double *b, double *c)
{
  c[0] = a[0]*b[0] - (a[1]*b[1] + a[2]*b[2] + a[3]*b[3]);
  c[0] = a[0]*b[0] - a[1]*b[1] - a[2]*b[2] - a[3]*b[3];
  c[1] = a[0]*b[1] + b[0]*a[1] + a[2]*b[3] - a[3]*b[2];
  c[2] = a[0]*b[2] + b[0]*a[2] + a[3]*b[1] - a[1]*b[3];
  c[3] = a[0]*b[3] + b[0]*a[3] + a[1]*b[2] - a[2]*b[1];
}

/* ----------------------------------------------------------------------
   conjugate of a quaternion: qc = conjugate of q
   assume q is of unit length
------------------------------------------------------------------------- */

void FixRigid::qconjugate(double *q, double *qc)
{
  qc[0] = q[0];
  qc[1] = -q[1];
  qc[2] = -q[2];
  qc[3] = -q[3];
}

/* ----------------------------------------------------------------------
   normalize a quaternion
------------------------------------------------------------------------- */

void FixRigid::normalize(double *q)
void FixRigid::qnormalize(double *q)
{
  double norm = 1.0 / sqrt(q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3]);
  q[0] *= norm;
@@ -1355,23 +1635,23 @@ void FixRigid::normalize(double *q)
   only know Idiag so need to do M = Iw in body frame
   ex,ey,ez are column vectors of rotation matrix P
   Mbody = P_transpose Mspace
   wbody = Mbody / Ibody
   wbody = Mbody / Idiag
   wspace = P wbody
   set wbody component to 0.0 if inertia component is 0.0
     otherwise body can spin easily around that axis
------------------------------------------------------------------------- */

void FixRigid::omega_from_angmom(double *m, double *ex, double *ey, double *ez,
				 double *inertia, double *w)
				 double *idiag, double *w)
{
  double wbody[3];

  if (inertia[0] == 0.0) wbody[0] = 0.0;
  else wbody[0] = (m[0]*ex[0] + m[1]*ex[1] + m[2]*ex[2]) / inertia[0];
  if (inertia[1] == 0.0) wbody[1] = 0.0;
  else wbody[1] = (m[0]*ey[0] + m[1]*ey[1] + m[2]*ey[2]) / inertia[1];
  if (inertia[2] == 0.0) wbody[2] = 0.0;
  else wbody[2] = (m[0]*ez[0] + m[1]*ez[1] + m[2]*ez[2]) / inertia[2];
  if (idiag[0] == 0.0) wbody[0] = 0.0;
  else wbody[0] = (m[0]*ex[0] + m[1]*ex[1] + m[2]*ex[2]) / idiag[0];
  if (idiag[1] == 0.0) wbody[1] = 0.0;
  else wbody[1] = (m[0]*ey[0] + m[1]*ey[1] + m[2]*ey[2]) / idiag[1];
  if (idiag[2] == 0.0) wbody[2] = 0.0;
  else wbody[2] = (m[0]*ez[0] + m[1]*ez[1] + m[2]*ez[2]) / idiag[2];

  w[0] = wbody[0]*ex[0] + wbody[1]*ey[0] + wbody[2]*ez[0];
  w[1] = wbody[0]*ex[1] + wbody[1]*ey[1] + wbody[2]*ez[1];
@@ -1383,18 +1663,19 @@ void FixRigid::omega_from_angmom(double *m, double *ex, double *ey, double *ez,
   only know Idiag so need to do M = Iw in body frame
   ex,ey,ez are column vectors of rotation matrix P
   wbody = P_transpose wspace
   Mbody = Ibody wbody
   Mbody = Idiag wbody
   Mspace = P Mbody
------------------------------------------------------------------------- */

void FixRigid::angmom_from_omega(double *w, double *ex, double *ey, double *ez,
				 double *inertia, double *m)
void FixRigid::angmom_from_omega(double *w, 
				  double *ex, double *ey, double *ez,
				  double *idiag, double *m)
{
  double mbody[3];

  mbody[0] = (w[0]*ex[0] + w[1]*ex[1] + w[2]*ex[2]) * inertia[0];
  mbody[1] = (w[0]*ey[0] + w[1]*ey[1] + w[2]*ey[2]) * inertia[1];
  mbody[2] = (w[0]*ez[0] + w[1]*ez[1] + w[2]*ez[2]) * inertia[2];
  mbody[0] = (w[0]*ex[0] + w[1]*ex[1] + w[2]*ex[2]) * idiag[0];
  mbody[1] = (w[0]*ey[0] + w[1]*ey[1] + w[2]*ey[2]) * idiag[1];
  mbody[2] = (w[0]*ez[0] + w[1]*ez[1] + w[2]*ez[2]) * idiag[2];

  m[0] = mbody[0]*ex[0] + mbody[1]*ey[0] + mbody[2]*ez[0];
  m[1] = mbody[0]*ex[1] + mbody[1]*ey[1] + mbody[2]*ez[1];
@@ -1403,17 +1684,18 @@ void FixRigid::angmom_from_omega(double *w, double *ex, double *ey, double *ez,

/* ----------------------------------------------------------------------
   set space-frame coords and velocity of each atom in each rigid body
   set orientation and rotation of extended particles
   x = Q displace + Xcm, mapped back to periodic box
   v = Vcm + (W cross (x - Xcm))
------------------------------------------------------------------------- */

void FixRigid::set_xv()
{
  int ibody;
  int ibody,itype;
  int xbox,ybox,zbox;
  double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone;
  double xy,xz,yz;
  double vr[6];
  double ione[3],exone[3],eyone[3],ezone[3],vr[6],p[3][3];

  int *image = atom->image;
  double **x = atom->x;
@@ -1504,7 +1786,6 @@ void FixRigid::set_xv()
    if (evflag) {
      if (rmass) massone = rmass[i];
      else massone = mass[type[i]];

      fc0 = massone*(v[i][0] - v0)/dtf - f[i][0];
      fc1 = massone*(v[i][1] - v1)/dtf - f[i][1];
      fc2 = massone*(v[i][2] - v2)/dtf - f[i][2]; 
@@ -1519,25 +1800,66 @@ void FixRigid::set_xv()
      v_tally(1,&i,1.0,vr);
    }
  }

  // set orientation, omega, angmom of each extended particle
  
  if (extended) {
    double **omega_one = atom->omega;
    double **angmom_one = atom->angmom;
    double *dipole = atom->dipole;
    double **shape = atom->shape;

    for (int i = 0; i < nlocal; i++) {
      if (body[i] < 0) continue;
      ibody = body[i];
      
      if (eflags[i] & ORIENT_DIPOLE) {
	MathExtra::quat_to_mat(quat[ibody],p);
	MathExtra::times_column3(p,dorient[i],atom->mu[i]);
	MathExtra::snormalize3(dipole[type[i]],atom->mu[i],atom->mu[i]);
      }
      if (eflags[i] & ORIENT_QUAT) {
	quatquat(quat[ibody],qorient[i],atom->quat[i]);
	qnormalize(atom->quat[i]);
      }
      if (eflags[i] & OMEGA) {
	omega_one[i][0] = omega[ibody][0];
	omega_one[i][1] = omega[ibody][1];
	omega_one[i][2] = omega[ibody][2];
      }
      if (eflags[i] & ANGMOM) {
	itype = type[i];
	ione[0] = 0.2*mass[itype] *
	  (shape[itype][1]*shape[itype][1] + shape[itype][2]*shape[itype][2]);
	ione[1] = 0.2*mass[itype] *
	  (shape[itype][0]*shape[itype][0] + shape[itype][2]*shape[itype][2]);
	ione[2] = 0.2*mass[itype] * 
	  (shape[itype][0]*shape[itype][0] + shape[itype][1]*shape[itype][1]);
	exyz_from_q(atom->quat[i],exone,eyone,ezone);
	angmom_from_omega(omega[ibody],exone,eyone,ezone,ione,angmom_one[i]);
      }
    }
  }
}

/* ----------------------------------------------------------------------
   set space-frame velocity of each atom in a rigid body
   set omega and angmom of extended particles
   v = Vcm + (W cross (x - Xcm))
------------------------------------------------------------------------- */

void FixRigid::set_v()
{
  int ibody;
  int ibody,itype;
  int xbox,ybox,zbox;
  double dx,dy,dz;
  double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone;
  double xy,xz,yz;
  double vr[6];
  double ione[3],exone[3],eyone[3],ezone[3],vr[6];

  double **f = atom->f;
  double **v = atom->v;
  double **x = atom->x;
  double **v = atom->v;
  double **f = atom->f;
  double *rmass = atom->rmass; 
  double *mass = atom->mass; 
  int *type = atom->type;
@@ -1590,7 +1912,6 @@ void FixRigid::set_v()
    if (evflag) {
      if (rmass) massone = rmass[i];
      else massone = mass[type[i]];

      fc0 = massone*(v[i][0] - v0)/dtf - f[i][0];
      fc1 = massone*(v[i][1] - v1)/dtf - f[i][1];
      fc2 = massone*(v[i][2] - v2)/dtf - f[i][2]; 
@@ -1619,6 +1940,36 @@ void FixRigid::set_v()
      v_tally(1,&i,1.0,vr);
    }
  }

  // set omega, angmom of each extended particle
  
  if (extended) {
    double **omega_one = atom->omega;
    double **angmom_one = atom->angmom;
    double **shape = atom->shape;

    for (int i = 0; i < nlocal; i++) {
      if (body[i] < 0) continue;
      ibody = body[i];

      if (eflags[i] & OMEGA) {
	omega_one[i][0] = omega[ibody][0];
	omega_one[i][1] = omega[ibody][1];
	omega_one[i][2] = omega[ibody][2];
      }
      if (eflags[i] & ANGMOM) {
	itype = type[i];
	ione[0] = 0.2*mass[itype] *
	  (shape[itype][1]*shape[itype][1] + shape[itype][2]*shape[itype][2]);
	ione[1] = 0.2*mass[itype] *
	  (shape[itype][0]*shape[itype][0] + shape[itype][2]*shape[itype][2]);
	ione[2] = 0.2*mass[itype] * 
	  (shape[itype][0]*shape[itype][0] + shape[itype][1]*shape[itype][1]);
	exyz_from_q(atom->quat[i],exone,eyone,ezone);
	angmom_from_omega(omega[ibody],exone,eyone,ezone,ione,angmom_one[i]);
      }
    }
  }
}

/* ----------------------------------------------------------------------
@@ -1631,6 +1982,11 @@ double FixRigid::memory_usage()
  double bytes = nmax * sizeof(int);
  bytes += nmax*3 * sizeof(double);
  bytes += maxvatom*6 * sizeof(double);
  if (extended) {
    bytes += nmax * sizeof(int);
    if (dorientflag) bytes = nmax*3 * sizeof(double);
    if (qorientflag) bytes = nmax*4 * sizeof(double);
  }
  return bytes;
} 

@@ -1642,6 +1998,14 @@ void FixRigid::grow_arrays(int nmax)
{
  body = (int *) memory->srealloc(body,nmax*sizeof(int),"rigid:body");
  displace = memory->grow_2d_double_array(displace,nmax,3,"rigid:displace");
  if (extended) {
    eflags = (int *)
      memory->srealloc(eflags,nmax*sizeof(int),"rigid:eflags");
    if (dorientflag)
      dorient = memory->grow_2d_double_array(dorient,nmax,3,"rigid:dorient");
    if (qorientflag)
      qorient = memory->grow_2d_double_array(qorient,nmax,4,"rigid:qorient");
  }
}

/* ----------------------------------------------------------------------
@@ -1654,6 +2018,20 @@ void FixRigid::copy_arrays(int i, int j)
  displace[j][0] = displace[i][0];
  displace[j][1] = displace[i][1];
  displace[j][2] = displace[i][2];
  if (extended) {
    eflags[j] = eflags[i];
    if (dorientflag) {
      dorient[j][0] = dorient[i][0];
      dorient[j][1] = dorient[i][1];
      dorient[j][2] = dorient[i][2];
    }
    if (qorientflag) {
      qorient[j][0] = qorient[i][0];
      qorient[j][1] = qorient[i][1];
      qorient[j][2] = qorient[i][2];
      qorient[j][3] = qorient[i][3];
    }
  }
}

/* ----------------------------------------------------------------------
@@ -1666,7 +2044,22 @@ int FixRigid::pack_exchange(int i, double *buf)
  buf[1] = displace[i][0];
  buf[2] = displace[i][1];
  buf[3] = displace[i][2];
  return 4;
  if (!extended) return 4;

  int m = 4;
  buf[m++] = eflags[i];
  if (dorientflag) {
    buf[m++] = dorient[i][0];
    buf[m++] = dorient[i][1];
    buf[m++] = dorient[i][2];
  }
  if (qorientflag) {
    buf[m++] = qorient[i][0];
    buf[m++] = qorient[i][1];
    buf[m++] = qorient[i][2];
    buf[m++] = qorient[i][3];
  }
  return m;
}

/* ----------------------------------------------------------------------
@@ -1679,7 +2072,22 @@ int FixRigid::unpack_exchange(int nlocal, double *buf)
  displace[nlocal][0] = buf[1];
  displace[nlocal][1] = buf[2];
  displace[nlocal][2] = buf[3];
  return 4;
  if (!extended) return 4;

  int m = 4;
  eflags[nlocal] = static_cast<int> (buf[m++]);
  if (dorientflag) {
    dorient[nlocal][0] = buf[m++];
    dorient[nlocal][0] = buf[m++];
    dorient[nlocal][0] = buf[m++];
  }
  if (qorientflag) {
    qorient[nlocal][0] = buf[m++];
    qorient[nlocal][0] = buf[m++];
    qorient[nlocal][0] = buf[m++];
    qorient[nlocal][0] = buf[m++];
  }
  return m;
}

/* ---------------------------------------------------------------------- */
+18 −3

File changed.

Preview size limit exceeded, changes collapsed.

+23 −10

File changed.

Preview size limit exceeded, changes collapsed.