git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@2776 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp
2009-04-28 19:46:52 +00:00
parent 2dacebfcd0
commit 1904459e45
4 changed files with 447 additions and 44 deletions

View File

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

View File

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

View File

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

View File

@ -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 &);