git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@2776 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
356
src/group.cpp
356
src/group.cpp
@ -501,6 +501,30 @@ double Group::count(int igroup)
|
|||||||
return nall;
|
return nall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
count atoms in group and region
|
||||||
|
compute in double precision in case system is huge
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
double Group::count(int igroup, int iregion)
|
||||||
|
{
|
||||||
|
int groupbit = bitmask[igroup];
|
||||||
|
Region *region = domain->regions[iregion];
|
||||||
|
|
||||||
|
double **x = atom->x;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) n++;
|
||||||
|
|
||||||
|
double nsingle = n;
|
||||||
|
double nall;
|
||||||
|
MPI_Allreduce(&nsingle,&nall,1,MPI_DOUBLE,MPI_SUM,world);
|
||||||
|
return nall;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the total mass of group of atoms
|
compute the total mass of group of atoms
|
||||||
use either per-type mass or per-atom rmass
|
use either per-type mass or per-atom rmass
|
||||||
@ -510,10 +534,10 @@ double Group::mass(int igroup)
|
|||||||
{
|
{
|
||||||
int groupbit = bitmask[igroup];
|
int groupbit = bitmask[igroup];
|
||||||
|
|
||||||
int *mask = atom->mask;
|
|
||||||
int *type = atom->type;
|
|
||||||
double *mass = atom->mass;
|
double *mass = atom->mass;
|
||||||
double *rmass = atom->rmass;
|
double *rmass = atom->rmass;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int *type = atom->type;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
double one = 0.0;
|
double one = 0.0;
|
||||||
@ -531,6 +555,40 @@ double Group::mass(int igroup)
|
|||||||
return all;
|
return all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
compute the total mass of group of atoms in region
|
||||||
|
use either per-type mass or per-atom rmass
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
double Group::mass(int igroup, int iregion)
|
||||||
|
{
|
||||||
|
int groupbit = bitmask[igroup];
|
||||||
|
Region *region = domain->regions[iregion];
|
||||||
|
|
||||||
|
double **x = atom->x;
|
||||||
|
double *mass = atom->mass;
|
||||||
|
double *rmass = atom->rmass;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int *type = atom->type;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
double one = 0.0;
|
||||||
|
|
||||||
|
if (rmass) {
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
|
||||||
|
one += rmass[i];
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
|
||||||
|
one += mass[type[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
double all;
|
||||||
|
MPI_Allreduce(&one,&all,1,MPI_DOUBLE,MPI_SUM,world);
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the total charge of group of atoms
|
compute the total charge of group of atoms
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
@ -539,8 +597,8 @@ double Group::charge(int igroup)
|
|||||||
{
|
{
|
||||||
int groupbit = bitmask[igroup];
|
int groupbit = bitmask[igroup];
|
||||||
|
|
||||||
int *mask = atom->mask;
|
|
||||||
double *q = atom->q;
|
double *q = atom->q;
|
||||||
|
int *mask = atom->mask;
|
||||||
int nlocal = atom->nlocal;
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
double qone = 0.0;
|
double qone = 0.0;
|
||||||
@ -552,6 +610,30 @@ double Group::charge(int igroup)
|
|||||||
return qall;
|
return qall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
compute the total charge of group of atoms in region
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
double Group::charge(int igroup, int iregion)
|
||||||
|
{
|
||||||
|
int groupbit = bitmask[igroup];
|
||||||
|
Region *region = domain->regions[iregion];
|
||||||
|
|
||||||
|
double **x = atom->x;
|
||||||
|
double *q = atom->q;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
double qone = 0.0;
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
|
||||||
|
qone += q[i];
|
||||||
|
|
||||||
|
double qall;
|
||||||
|
MPI_Allreduce(&qone,&qall,1,MPI_DOUBLE,MPI_SUM,world);
|
||||||
|
return qall;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the coordinate bounds of the group of atoms
|
compute the coordinate bounds of the group of atoms
|
||||||
periodic images are not considered, so atoms are NOT unwrapped
|
periodic images are not considered, so atoms are NOT unwrapped
|
||||||
@ -596,7 +678,52 @@ void Group::bounds(int igroup, double *minmax)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the center-of-mass coords of group with total mass = masstotal
|
compute the coordinate bounds of the group of atoms in region
|
||||||
|
periodic images are not considered, so atoms are NOT unwrapped
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Group::bounds(int igroup, double *minmax, int iregion)
|
||||||
|
{
|
||||||
|
int groupbit = bitmask[igroup];
|
||||||
|
Region *region = domain->regions[iregion];
|
||||||
|
|
||||||
|
double extent[6];
|
||||||
|
extent[0] = extent[2] = extent[4] = BIG;
|
||||||
|
extent[1] = extent[3] = extent[5] = -BIG;
|
||||||
|
|
||||||
|
double **x = atom->x;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
for (int i = 0; i < nlocal; i++) {
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
|
||||||
|
extent[0] = MIN(extent[0],x[i][0]);
|
||||||
|
extent[1] = MAX(extent[1],x[i][0]);
|
||||||
|
extent[2] = MIN(extent[2],x[i][1]);
|
||||||
|
extent[3] = MAX(extent[3],x[i][1]);
|
||||||
|
extent[4] = MIN(extent[4],x[i][2]);
|
||||||
|
extent[5] = MAX(extent[5],x[i][2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute extent across all procs
|
||||||
|
// flip sign of MIN to do it in one Allreduce MAX
|
||||||
|
// set box by extent in shrink-wrapped dims
|
||||||
|
|
||||||
|
extent[0] = -extent[0];
|
||||||
|
extent[2] = -extent[2];
|
||||||
|
extent[4] = -extent[4];
|
||||||
|
|
||||||
|
MPI_Allreduce(extent,minmax,6,MPI_DOUBLE,MPI_MAX,world);
|
||||||
|
|
||||||
|
minmax[0] = -minmax[0];
|
||||||
|
minmax[2] = -minmax[2];
|
||||||
|
minmax[4] = -minmax[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
compute the center-of-mass coords of group of atoms
|
||||||
|
masstotal = total mass
|
||||||
return center-of-mass coords in cm[]
|
return center-of-mass coords in cm[]
|
||||||
must unwrap atoms to compute center-of-mass correctly
|
must unwrap atoms to compute center-of-mass correctly
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
@ -653,7 +780,67 @@ void Group::xcm(int igroup, double masstotal, double *cm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the center-of-mass velocity of group with total mass = masstotal
|
compute the center-of-mass coords of group of atoms in region
|
||||||
|
mastotal = total mass
|
||||||
|
return center-of-mass coords in cm[]
|
||||||
|
must unwrap atoms to compute center-of-mass correctly
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Group::xcm(int igroup, double masstotal, double *cm, int iregion)
|
||||||
|
{
|
||||||
|
int groupbit = bitmask[igroup];
|
||||||
|
Region *region = domain->regions[iregion];
|
||||||
|
|
||||||
|
double **x = atom->x;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int *type = atom->type;
|
||||||
|
int *image = atom->image;
|
||||||
|
double *mass = atom->mass;
|
||||||
|
double *rmass = atom->rmass;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
double cmone[3];
|
||||||
|
cmone[0] = cmone[1] = cmone[2] = 0.0;
|
||||||
|
double xprd = domain->xprd;
|
||||||
|
double yprd = domain->yprd;
|
||||||
|
double zprd = domain->zprd;
|
||||||
|
|
||||||
|
int xbox,ybox,zbox;
|
||||||
|
double massone;
|
||||||
|
|
||||||
|
if (rmass) {
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
|
||||||
|
xbox = (image[i] & 1023) - 512;
|
||||||
|
ybox = (image[i] >> 10 & 1023) - 512;
|
||||||
|
zbox = (image[i] >> 20) - 512;
|
||||||
|
massone = rmass[i];
|
||||||
|
cmone[0] += (x[i][0] + xbox*xprd) * massone;
|
||||||
|
cmone[1] += (x[i][1] + ybox*yprd) * massone;
|
||||||
|
cmone[2] += (x[i][2] + zbox*zprd) * massone;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
|
||||||
|
xbox = (image[i] & 1023) - 512;
|
||||||
|
ybox = (image[i] >> 10 & 1023) - 512;
|
||||||
|
zbox = (image[i] >> 20) - 512;
|
||||||
|
massone = mass[type[i]];
|
||||||
|
cmone[0] += (x[i][0] + xbox*xprd) * massone;
|
||||||
|
cmone[1] += (x[i][1] + ybox*yprd) * massone;
|
||||||
|
cmone[2] += (x[i][2] + zbox*zprd) * massone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MPI_Allreduce(cmone,cm,3,MPI_DOUBLE,MPI_SUM,world);
|
||||||
|
cm[0] /= masstotal;
|
||||||
|
cm[1] /= masstotal;
|
||||||
|
cm[2] /= masstotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
compute the center-of-mass velocity of group of atoms
|
||||||
|
masstotal = total mass
|
||||||
return center-of-mass velocity in cm[]
|
return center-of-mass velocity in cm[]
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
@ -695,6 +882,52 @@ void Group::vcm(int igroup, double masstotal, double *cm)
|
|||||||
cm[2] /= masstotal;
|
cm[2] /= masstotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
compute the center-of-mass velocity of group of atoms in region
|
||||||
|
masstotal = total mass
|
||||||
|
return center-of-mass velocity in cm[]
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Group::vcm(int igroup, double masstotal, double *cm, int iregion)
|
||||||
|
{
|
||||||
|
int groupbit = bitmask[igroup];
|
||||||
|
Region *region = domain->regions[iregion];
|
||||||
|
|
||||||
|
double **x = atom->x;
|
||||||
|
double **v = atom->v;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int *type = atom->type;
|
||||||
|
double *mass = atom->mass;
|
||||||
|
double *rmass = atom->rmass;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
double p[3],massone;
|
||||||
|
p[0] = p[1] = p[2] = 0.0;
|
||||||
|
|
||||||
|
if (rmass) {
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
|
||||||
|
massone = rmass[i];
|
||||||
|
p[0] += v[i][0]*massone;
|
||||||
|
p[1] += v[i][1]*massone;
|
||||||
|
p[2] += v[i][2]*massone;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
|
||||||
|
massone = mass[type[i]];
|
||||||
|
p[0] += v[i][0]*massone;
|
||||||
|
p[1] += v[i][1]*massone;
|
||||||
|
p[2] += v[i][2]*massone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MPI_Allreduce(p,cm,3,MPI_DOUBLE,MPI_SUM,world);
|
||||||
|
cm[0] /= masstotal;
|
||||||
|
cm[1] /= masstotal;
|
||||||
|
cm[2] /= masstotal;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the total force on group of atoms
|
compute the total force on group of atoms
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
@ -721,7 +954,34 @@ void Group::fcm(int igroup, double *cm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the total kinetic energy of group and return it
|
compute the total force on group of atoms in region
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Group::fcm(int igroup, double *cm, int iregion)
|
||||||
|
{
|
||||||
|
int groupbit = bitmask[igroup];
|
||||||
|
Region *region = domain->regions[iregion];
|
||||||
|
|
||||||
|
double **x = atom->x;
|
||||||
|
double **f = atom->f;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
double flocal[3];
|
||||||
|
flocal[0] = flocal[1] = flocal[2] = 0.0;
|
||||||
|
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
|
||||||
|
flocal[0] += f[i][0];
|
||||||
|
flocal[1] += f[i][1];
|
||||||
|
flocal[2] += f[i][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
MPI_Allreduce(flocal,cm,3,MPI_DOUBLE,MPI_SUM,world);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
compute the total kinetic energy of group of atoms and return it
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
double Group::ke(int igroup)
|
double Group::ke(int igroup)
|
||||||
@ -756,7 +1016,45 @@ double Group::ke(int igroup)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the radius-of-gyration of group around center-of-mass cm
|
compute the total kinetic energy of group of atoms in region and return it
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
double Group::ke(int igroup, int iregion)
|
||||||
|
{
|
||||||
|
int groupbit = bitmask[igroup];
|
||||||
|
Region *region = domain->regions[iregion];
|
||||||
|
|
||||||
|
double **x = atom->x;
|
||||||
|
double **v = atom->v;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int *type = atom->type;
|
||||||
|
double *mass = atom->mass;
|
||||||
|
double *rmass = atom->rmass;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
double one = 0.0;
|
||||||
|
|
||||||
|
if (rmass) {
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
|
||||||
|
one += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) *
|
||||||
|
rmass[i];
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2]))
|
||||||
|
one += (v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]) *
|
||||||
|
mass[type[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
double all;
|
||||||
|
MPI_Allreduce(&one,&all,1,MPI_DOUBLE,MPI_SUM,world);
|
||||||
|
all *= 0.5 * force->mvv2e;
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
compute the radius-of-gyration of group of atoms
|
||||||
|
around center-of-mass cm
|
||||||
must unwrap atoms to compute Rg correctly
|
must unwrap atoms to compute Rg correctly
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
@ -797,6 +1095,50 @@ double Group::gyration(int igroup, double masstotal, double *cm)
|
|||||||
return sqrt(rg_all/masstotal);
|
return sqrt(rg_all/masstotal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
compute the radius-of-gyration of group of atoms in region
|
||||||
|
around center-of-mass cm
|
||||||
|
must unwrap atoms to compute Rg correctly
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
double Group::gyration(int igroup, double masstotal, double *cm, int iregion)
|
||||||
|
{
|
||||||
|
int groupbit = bitmask[igroup];
|
||||||
|
Region *region = domain->regions[iregion];
|
||||||
|
|
||||||
|
double **x = atom->x;
|
||||||
|
int *mask = atom->mask;
|
||||||
|
int *type = atom->type;
|
||||||
|
int *image = atom->image;
|
||||||
|
double *mass = atom->mass;
|
||||||
|
double *rmass = atom->rmass;
|
||||||
|
int nlocal = atom->nlocal;
|
||||||
|
|
||||||
|
int xbox,ybox,zbox;
|
||||||
|
double dx,dy,dz,massone;
|
||||||
|
double xprd = domain->xprd;
|
||||||
|
double yprd = domain->yprd;
|
||||||
|
double zprd = domain->zprd;
|
||||||
|
double rg = 0.0;
|
||||||
|
|
||||||
|
for (int i = 0; i < nlocal; i++)
|
||||||
|
if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
|
||||||
|
xbox = (image[i] & 1023) - 512;
|
||||||
|
ybox = (image[i] >> 10 & 1023) - 512;
|
||||||
|
zbox = (image[i] >> 20) - 512;
|
||||||
|
dx = (x[i][0] + xbox*xprd) - cm[0];
|
||||||
|
dy = (x[i][1] + ybox*yprd) - cm[1];
|
||||||
|
dz = (x[i][2] + zbox*zprd) - cm[2];
|
||||||
|
if (rmass) massone = rmass[i];
|
||||||
|
else massone = mass[type[i]];
|
||||||
|
rg += (dx*dx + dy*dy + dz*dz) * massone;
|
||||||
|
}
|
||||||
|
double rg_all;
|
||||||
|
MPI_Allreduce(&rg,&rg_all,1,MPI_DOUBLE,MPI_SUM,world);
|
||||||
|
|
||||||
|
return sqrt(rg_all/masstotal);
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
compute the angular momentum L (lmom) of group around center-of-mass cm
|
compute the angular momentum L (lmom) of group around center-of-mass cm
|
||||||
must unwrap atoms to compute L correctly
|
must unwrap atoms to compute L correctly
|
||||||
|
|||||||
@ -33,14 +33,23 @@ class Group : protected Pointers {
|
|||||||
void read_restart(FILE *);
|
void read_restart(FILE *);
|
||||||
|
|
||||||
double count(int); // count atoms in group
|
double count(int); // count atoms in group
|
||||||
|
double count(int,int); // count atoms in group & region
|
||||||
double mass(int); // total mass of atoms in group
|
double mass(int); // total mass of atoms in group
|
||||||
|
double mass(int,int);
|
||||||
double charge(int); // total charge of atoms in group
|
double charge(int); // total charge of atoms in group
|
||||||
|
double charge(int,int);
|
||||||
void bounds(int, double *); // bounds of atoms in group
|
void bounds(int, double *); // bounds of atoms in group
|
||||||
|
void bounds(int, double *, int);
|
||||||
void xcm(int, double, double *); // center-of-mass coords of group
|
void xcm(int, double, double *); // center-of-mass coords of group
|
||||||
|
void xcm(int, double, double *, int);
|
||||||
void vcm(int, double, double *); // center-of-mass velocity of group
|
void vcm(int, double, double *); // center-of-mass velocity of group
|
||||||
|
void vcm(int, double, double *, int);
|
||||||
void fcm(int, double *); // total force on group
|
void fcm(int, double *); // total force on group
|
||||||
|
void fcm(int, double *, int);
|
||||||
double ke(int); // kinetic energy of group
|
double ke(int); // kinetic energy of group
|
||||||
|
double ke(int, int);
|
||||||
double gyration(int, double, double *); // radius-of-gyration of group
|
double gyration(int, double, double *); // radius-of-gyration of group
|
||||||
|
double gyration(int, double, double *, int);
|
||||||
void angmom(int, double *, double *); // angular momentum of group
|
void angmom(int, double *, double *); // angular momentum of group
|
||||||
void inertia(int, double *, double [3][3]); // inertia tensor
|
void inertia(int, double *, double [3][3]); // inertia tensor
|
||||||
void omega(double *, double [3][3], double *); // angular velocity
|
void omega(double *, double [3][3], double *); // angular velocity
|
||||||
|
|||||||
125
src/variable.cpp
125
src/variable.cpp
@ -1408,35 +1408,46 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
process a group function in formula
|
process a group function in formula with optional region arg
|
||||||
push result onto tree or arg stack
|
push result onto tree or arg stack
|
||||||
word = group function
|
word = group function
|
||||||
contents = str bewteen parentheses with one or two args
|
contents = str bewteen parentheses with one,two,three args
|
||||||
return 0 if not a match, 1 if successfully processed
|
return 0 if not a match, 1 if successfully processed
|
||||||
customize by adding a group function:
|
customize by adding a group function:
|
||||||
count(group),mass(group),charge(group),
|
count(group),mass(group),charge(group),
|
||||||
xcm(group,dim),vcm(group,dim),fcm(group,dim),
|
xcm(group,dim),vcm(group,dim),fcm(group,dim),
|
||||||
bound(group,xmin),gyration(group)
|
bound(group,xmin),gyration(group),ke(group)
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
int Variable::group_function(char *word, char *contents, Tree **tree,
|
int Variable::group_function(char *word, char *contents, Tree **tree,
|
||||||
Tree **treestack, int &ntreestack,
|
Tree **treestack, int &ntreestack,
|
||||||
double *argstack, int &nargstack)
|
double *argstack, int &nargstack)
|
||||||
{
|
{
|
||||||
// parse contents for arg1,arg2 separated by comma
|
// parse contents for arg1,arg2,arg3 separated by commas
|
||||||
|
|
||||||
char *arg1,*arg2;
|
char *ptr1 = strchr(contents,',');
|
||||||
char *ptr = strchr(contents,',');
|
if (ptr1) *ptr1 = '\0';
|
||||||
if (ptr) *ptr = '\0';
|
char *ptr2 = strchr(ptr1+1,',');
|
||||||
|
if (ptr2) *ptr2 = '\0';
|
||||||
|
|
||||||
|
char *arg1,*arg2,*arg3;
|
||||||
int n = strlen(contents) + 1;
|
int n = strlen(contents) + 1;
|
||||||
arg1 = new char[n];
|
arg1 = new char[n];
|
||||||
strcpy(arg1,contents);
|
strcpy(arg1,contents);
|
||||||
if (ptr) {
|
int narg = 1;
|
||||||
n = strlen(ptr+1) + 1;
|
if (ptr1) {
|
||||||
|
n = strlen(ptr1+1) + 1;
|
||||||
arg2 = new char[n];
|
arg2 = new char[n];
|
||||||
strcpy(arg2,ptr+1);
|
strcpy(arg2,ptr1+1);
|
||||||
|
narg = 2;
|
||||||
} else arg2 = NULL;
|
} else arg2 = NULL;
|
||||||
|
if (ptr2) {
|
||||||
|
n = strlen(ptr2+1) + 1;
|
||||||
|
arg3 = new char[n];
|
||||||
|
strcpy(arg3,ptr1+1);
|
||||||
|
narg = 3;
|
||||||
|
} else arg3 = NULL;
|
||||||
|
|
||||||
int igroup = group->find(arg1);
|
int igroup = group->find(arg1);
|
||||||
if (igroup == -1)
|
if (igroup == -1)
|
||||||
error->all("Group ID in variable formula does not exist");
|
error->all("Group ID in variable formula does not exist");
|
||||||
@ -1454,59 +1465,67 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
|
|||||||
// match word to group function
|
// match word to group function
|
||||||
|
|
||||||
if (strcmp(word,"count") == 0) {
|
if (strcmp(word,"count") == 0) {
|
||||||
if (arg2)
|
if (narg == 1) value = group->count(igroup);
|
||||||
error->all("Invalid group function in variable formula");
|
else if (narg == 2) value = group->count(igroup,region_function(arg2));
|
||||||
value = group->count(igroup);
|
else error->all("Invalid group function in variable formula");
|
||||||
|
|
||||||
} else if (strcmp(word,"mass") == 0) {
|
} else if (strcmp(word,"mass") == 0) {
|
||||||
if (arg2)
|
if (narg == 1) value = group->mass(igroup);
|
||||||
error->all("Invalid group function in variable formula");
|
else if (narg == 2) value = group->mass(igroup,region_function(arg2));
|
||||||
value = group->mass(igroup);
|
else error->all("Invalid group function in variable formula");
|
||||||
|
|
||||||
} else if (strcmp(word,"charge") == 0) {
|
} else if (strcmp(word,"charge") == 0) {
|
||||||
if (arg2)
|
if (narg == 1) value = group->charge(igroup);
|
||||||
error->all("Invalid group function in variable formula");
|
else if (narg == 2) value = group->charge(igroup,region_function(arg2));
|
||||||
value = group->charge(igroup);
|
else error->all("Invalid group function in variable formula");
|
||||||
|
|
||||||
} else if (strcmp(word,"xcm") == 0) {
|
} else if (strcmp(word,"xcm") == 0) {
|
||||||
if (!arg2)
|
|
||||||
error->all("Invalid group function in variable formula");
|
|
||||||
atom->check_mass();
|
atom->check_mass();
|
||||||
double masstotal = group->mass(igroup);
|
|
||||||
double xcm[3];
|
double xcm[3];
|
||||||
group->xcm(igroup,masstotal,xcm);
|
if (narg == 2) {
|
||||||
|
double masstotal = group->mass(igroup);
|
||||||
|
group->xcm(igroup,masstotal,xcm);
|
||||||
|
} else if (narg == 3) {
|
||||||
|
int iregion = region_function(arg3);
|
||||||
|
double masstotal = group->mass(igroup,iregion);
|
||||||
|
group->xcm(igroup,masstotal,xcm,iregion);
|
||||||
|
} else error->all("Invalid group function in variable formula");
|
||||||
if (strcmp(arg2,"x") == 0) value = xcm[0];
|
if (strcmp(arg2,"x") == 0) value = xcm[0];
|
||||||
else if (strcmp(arg2,"y") == 0) value = xcm[1];
|
else if (strcmp(arg2,"y") == 0) value = xcm[1];
|
||||||
else if (strcmp(arg2,"z") == 0) value = xcm[2];
|
else if (strcmp(arg2,"z") == 0) value = xcm[2];
|
||||||
else error->all("Invalid group function in variable formula");
|
else error->all("Invalid group function in variable formula");
|
||||||
|
|
||||||
} else if (strcmp(word,"vcm") == 0) {
|
} else if (strcmp(word,"vcm") == 0) {
|
||||||
if (!arg2)
|
|
||||||
error->all("Invalid group function in variable formula");
|
|
||||||
atom->check_mass();
|
atom->check_mass();
|
||||||
double masstotal = group->mass(igroup);
|
|
||||||
double vcm[3];
|
double vcm[3];
|
||||||
group->vcm(igroup,masstotal,vcm);
|
if (narg == 2) {
|
||||||
|
double masstotal = group->mass(igroup);
|
||||||
|
group->vcm(igroup,masstotal,vcm);
|
||||||
|
} else if (narg == 3) {
|
||||||
|
int iregion = region_function(arg3);
|
||||||
|
double masstotal = group->mass(igroup,iregion);
|
||||||
|
group->vcm(igroup,masstotal,vcm,iregion);
|
||||||
|
} else error->all("Invalid group function in variable formula");
|
||||||
if (strcmp(arg2,"x") == 0) value = vcm[0];
|
if (strcmp(arg2,"x") == 0) value = vcm[0];
|
||||||
else if (strcmp(arg2,"y") == 0) value = vcm[1];
|
else if (strcmp(arg2,"y") == 0) value = vcm[1];
|
||||||
else if (strcmp(arg2,"z") == 0) value = vcm[2];
|
else if (strcmp(arg2,"z") == 0) value = vcm[2];
|
||||||
else error->all("Invalid group function in variable formula");
|
else error->all("Invalid group function in variable formula");
|
||||||
|
|
||||||
} else if (strcmp(word,"fcm") == 0) {
|
} else if (strcmp(word,"fcm") == 0) {
|
||||||
if (!arg2)
|
|
||||||
error->all("Invalid group function in variable formula");
|
|
||||||
double fcm[3];
|
double fcm[3];
|
||||||
group->fcm(igroup,fcm);
|
if (narg == 2) group->fcm(igroup,fcm);
|
||||||
|
else if (narg == 3) group->fcm(igroup,fcm,region_function(arg3));
|
||||||
|
else error->all("Invalid group function in variable formula");
|
||||||
if (strcmp(arg2,"x") == 0) value = fcm[0];
|
if (strcmp(arg2,"x") == 0) value = fcm[0];
|
||||||
else if (strcmp(arg2,"y") == 0) value = fcm[1];
|
else if (strcmp(arg2,"y") == 0) value = fcm[1];
|
||||||
else if (strcmp(arg2,"z") == 0) value = fcm[2];
|
else if (strcmp(arg2,"z") == 0) value = fcm[2];
|
||||||
else error->all("Invalid group function in variable formula");
|
else error->all("Invalid group function in variable formula");
|
||||||
|
|
||||||
} else if (strcmp(word,"bound") == 0) {
|
} else if (strcmp(word,"bound") == 0) {
|
||||||
if (!arg2)
|
|
||||||
error->all("Invalid group function in variable formula");
|
|
||||||
double minmax[6];
|
double minmax[6];
|
||||||
group->bounds(igroup,minmax);
|
if (narg == 2) group->bounds(igroup,minmax);
|
||||||
|
else if (narg == 3) group->bounds(igroup,minmax,region_function(arg3));
|
||||||
|
else error->all("Invalid group function in variable formula");
|
||||||
if (strcmp(arg2,"xmin") == 0) value = minmax[0];
|
if (strcmp(arg2,"xmin") == 0) value = minmax[0];
|
||||||
else if (strcmp(arg2,"xmax") == 0) value = minmax[1];
|
else if (strcmp(arg2,"xmax") == 0) value = minmax[1];
|
||||||
else if (strcmp(arg2,"ymin") == 0) value = minmax[2];
|
else if (strcmp(arg2,"ymin") == 0) value = minmax[2];
|
||||||
@ -1517,10 +1536,22 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
|
|||||||
|
|
||||||
} else if (strcmp(word,"gyration") == 0) {
|
} else if (strcmp(word,"gyration") == 0) {
|
||||||
atom->check_mass();
|
atom->check_mass();
|
||||||
double masstotal = group->mass(igroup);
|
|
||||||
double xcm[3];
|
double xcm[3];
|
||||||
group->xcm(igroup,masstotal,xcm);
|
if (narg == 1) {
|
||||||
value = group->gyration(igroup,masstotal,xcm);
|
double masstotal = group->mass(igroup);
|
||||||
|
group->xcm(igroup,masstotal,xcm);
|
||||||
|
value = group->gyration(igroup,masstotal,xcm);
|
||||||
|
} else if (narg == 2) {
|
||||||
|
int iregion = region_function(arg2);
|
||||||
|
double masstotal = group->mass(igroup,iregion);
|
||||||
|
group->xcm(igroup,masstotal,xcm,iregion);
|
||||||
|
value = group->gyration(igroup,masstotal,xcm,iregion);
|
||||||
|
} else error->all("Invalid group function in variable formula");
|
||||||
|
|
||||||
|
} else if (strcmp(word,"ke") == 0) {
|
||||||
|
if (narg == 1) value = group->ke(igroup);
|
||||||
|
else if (narg == 2) value = group->ke(igroup,region_function(arg2));
|
||||||
|
else error->all("Invalid group function in variable formula");
|
||||||
|
|
||||||
} else return 0;
|
} else return 0;
|
||||||
|
|
||||||
@ -1533,6 +1564,26 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
process a group function in formula with optional region arg
|
||||||
|
push result onto tree or arg stack
|
||||||
|
word = group function
|
||||||
|
contents = str bewteen parentheses with one,two,three args
|
||||||
|
return 0 if not a match, 1 if successfully processed
|
||||||
|
customize by adding a group function:
|
||||||
|
count(group),mass(group),charge(group),
|
||||||
|
xcm(group,dim),vcm(group,dim),fcm(group,dim),
|
||||||
|
bound(group,xmin),gyration(group)
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int Variable::region_function(char *id)
|
||||||
|
{
|
||||||
|
int iregion = domain->find_region(id);
|
||||||
|
if (iregion == -1)
|
||||||
|
error->all("Invalid region in group function in variable formula");
|
||||||
|
return iregion;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
extract a global value from a per-atom quantity in a formula
|
extract a global value from a per-atom quantity in a formula
|
||||||
flag = 0 -> word is an atom vector
|
flag = 0 -> word is an atom vector
|
||||||
|
|||||||
@ -61,6 +61,7 @@ class Variable : protected Pointers {
|
|||||||
int int_between_brackets(char *, int, int &, int);
|
int int_between_brackets(char *, int, int &, int);
|
||||||
int math_function(char *, char *, Tree **, Tree **, int &, double *, int &);
|
int math_function(char *, char *, Tree **, Tree **, int &, double *, int &);
|
||||||
int group_function(char *, char *, Tree **, Tree **, int &, double *, int &);
|
int group_function(char *, char *, Tree **, Tree **, int &, double *, int &);
|
||||||
|
int region_function(char *);
|
||||||
void peratom2global(int, char *, double *, int, int,
|
void peratom2global(int, char *, double *, int, int,
|
||||||
Tree **, Tree **, int &, double *, int &);
|
Tree **, Tree **, int &, double *, int &);
|
||||||
void atom_vector(char *, Tree **, Tree **, int &);
|
void atom_vector(char *, Tree **, Tree **, int &);
|
||||||
|
|||||||
Reference in New Issue
Block a user