Merge pull request #772 from akohlmey/improved-variable-error-reporting

More improved variable error reporting
This commit is contained in:
Steve Plimpton 2018-01-16 13:00:42 -07:00 committed by GitHub
commit 5d254855eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 155 additions and 151 deletions

View File

@ -933,7 +933,7 @@ double Variable::compute_equal(int ivar)
double Variable::compute_equal(char *str)
{
return evaluate(str,NULL);
return evaluate(str,NULL,-1);
}
/* ----------------------------------------------------------------------
@ -956,7 +956,7 @@ void Variable::compute_atom(int ivar, int igroup,
if (style[ivar] == ATOM) {
treetype = ATOM;
evaluate(data[ivar][0],&tree);
evaluate(data[ivar][0],&tree,ivar);
collapse_tree(tree);
} else vstore = reader[ivar]->fixstore->vstore;
@ -1030,7 +1030,7 @@ int Variable::compute_vector(int ivar, double **result)
eval_in_progress[ivar] = 1;
treetype = VECTOR;
evaluate(data[ivar][0],&tree);
evaluate(data[ivar][0],&tree,ivar);
collapse_tree(tree);
int nlen = size_tree_vector(tree);
if (nlen == 0)
@ -1206,9 +1206,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
if (tree) {
Tree *newtree;
evaluate(contents,&newtree);
evaluate(contents,&newtree,ivar);
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = evaluate(contents,NULL);
} else argstack[nargstack++] = evaluate(contents,NULL,ivar);
delete [] contents;
@ -1891,7 +1891,7 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
"vector-style variable formula",ivar);
Tree *newtree;
evaluate(data[ivar][0],&newtree);
evaluate(data[ivar][0],&newtree,ivar);
treestack[ntreestack++] = newtree;
// v_name = per-atom vector from atomfile-style variable
@ -1997,12 +1997,12 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
i = find_matching_paren(str,i,contents,ivar);
i++;
if (math_function(word,contents,tree,
treestack,ntreestack,argstack,nargstack));
else if (group_function(word,contents,tree,
treestack,ntreestack,argstack,nargstack));
else if (special_function(word,contents,tree,
treestack,ntreestack,argstack,nargstack));
if (math_function(word,contents,tree,treestack,ntreestack,
argstack,nargstack,ivar));
else if (group_function(word,contents,tree,treestack,ntreestack,
argstack,nargstack,ivar));
else if (special_function(word,contents,tree,treestack,ntreestack,
argstack,nargstack,ivar));
else {
char msg[128];
sprintf(msg,"Invalid math/group/special function '%s()'"
@ -3271,7 +3271,7 @@ tagint Variable::int_between_brackets(char *&ptr, int varallow)
int Variable::math_function(char *word, char *contents, Tree **tree,
Tree **treestack, int &ntreestack,
double *argstack, int &nargstack)
double *argstack, int &nargstack, int ivar)
{
// word not a match to any math function
@ -3306,16 +3306,16 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
newtree->first = newtree->second = NULL;
newtree->nextra = 0;
Tree *argtree;
evaluate(args[0],&argtree);
evaluate(args[0],&argtree,ivar);
newtree->first = argtree;
if (narg > 1) {
evaluate(args[1],&argtree);
evaluate(args[1],&argtree,ivar);
newtree->second = argtree;
if (narg > 2) {
newtree->nextra = narg-2;
newtree->extra = new Tree*[narg-2];
for (int i = 2; i < narg; i++) {
evaluate(args[i],&argtree);
evaluate(args[i],&argtree,ivar);
newtree->extra[i-2] = argtree;
}
}
@ -3323,12 +3323,12 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
treestack[ntreestack++] = newtree;
} else {
value1 = evaluate(args[0],NULL);
value1 = evaluate(args[0],NULL,ivar);
if (narg > 1) {
value2 = evaluate(args[1],NULL);
value2 = evaluate(args[1],NULL,ivar);
if (narg > 2) {
for (int i = 2; i < narg; i++)
values[i-2] = evaluate(args[i],NULL);
values[i-2] = evaluate(args[i],NULL,ivar);
}
}
}
@ -3338,112 +3338,113 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
if (strcmp(word,"sqrt") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = SQRT;
else {
if (value1 < 0.0)
error->all(FLERR,"Sqrt of negative value in variable formula");
print_var_error(FLERR,"Sqrt of negative value in "
"variable formula",ivar);
argstack[nargstack++] = sqrt(value1);
}
} else if (strcmp(word,"exp") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = EXP;
else argstack[nargstack++] = exp(value1);
} else if (strcmp(word,"ln") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = LN;
else {
if (value1 <= 0.0)
error->all(FLERR,"Log of zero/negative value in variable formula");
print_var_error(FLERR,"Log of zero/negative value in variable formula",ivar);
argstack[nargstack++] = log(value1);
}
} else if (strcmp(word,"log") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = LOG;
else {
if (value1 <= 0.0)
error->all(FLERR,"Log of zero/negative value in variable formula");
print_var_error(FLERR,"Log of zero/negative value in variable formula",ivar);
argstack[nargstack++] = log10(value1);
}
} else if (strcmp(word,"abs") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = ABS;
else argstack[nargstack++] = fabs(value1);
} else if (strcmp(word,"sin") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = SIN;
else argstack[nargstack++] = sin(value1);
} else if (strcmp(word,"cos") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = COS;
else argstack[nargstack++] = cos(value1);
} else if (strcmp(word,"tan") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = TAN;
else argstack[nargstack++] = tan(value1);
} else if (strcmp(word,"asin") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = ASIN;
else {
if (value1 < -1.0 || value1 > 1.0)
error->all(FLERR,"Arcsin of invalid value in variable formula");
print_var_error(FLERR,"Arcsin of invalid value in variable formula",ivar);
argstack[nargstack++] = asin(value1);
}
} else if (strcmp(word,"acos") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = ACOS;
else {
if (value1 < -1.0 || value1 > 1.0)
error->all(FLERR,"Arccos of invalid value in variable formula");
print_var_error(FLERR,"Arccos of invalid value in variable formula",ivar);
argstack[nargstack++] = acos(value1);
}
} else if (strcmp(word,"atan") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = ATAN;
else argstack[nargstack++] = atan(value1);
} else if (strcmp(word,"atan2") == 0) {
if (narg != 2)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = ATAN2;
else argstack[nargstack++] = atan2(value1,value2);
} else if (strcmp(word,"random") == 0) {
if (narg != 3)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = RANDOM;
else {
if (randomequal == NULL) {
int seed = static_cast<int> (values[0]);
if (seed <= 0)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
randomequal = new RanMars(lmp,seed);
}
argstack[nargstack++] = randomequal->uniform()*(value2-value1) + value1;
}
} else if (strcmp(word,"normal") == 0) {
if (narg != 3)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = NORMAL;
else {
if (value2 < 0.0)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (randomequal == NULL) {
int seed = static_cast<int> (values[0]);
if (seed <= 0)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
randomequal = new RanMars(lmp,seed);
}
argstack[nargstack++] = value1 + value2*randomequal->gaussian();
@ -3451,27 +3452,27 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"ceil") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = CEIL;
else argstack[nargstack++] = ceil(value1);
} else if (strcmp(word,"floor") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = FLOOR;
else argstack[nargstack++] = floor(value1);
} else if (strcmp(word,"round") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = ROUND;
else argstack[nargstack++] = MYROUND(value1);
} else if (strcmp(word,"ramp") == 0) {
if (narg != 2)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (update->whichflag == 0)
error->all(FLERR,"Cannot use ramp in variable formula between runs");
print_var_error(FLERR,"Cannot use ramp in variable formula between runs",ivar);
if (tree) newtree->type = RAMP;
else {
double delta = update->ntimestep - update->beginstep;
@ -3482,13 +3483,13 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"stagger") == 0) {
if (narg != 2)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = STAGGER;
else {
int ivalue1 = static_cast<int> (value1);
int ivalue2 = static_cast<int> (value2);
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue1 <= ivalue2)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
int lower = update->ntimestep/ivalue1 * ivalue1;
int delta = update->ntimestep - lower;
double value;
@ -3499,14 +3500,14 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"logfreq") == 0) {
if (narg != 3)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = LOGFREQ;
else {
int ivalue1 = static_cast<int> (value1);
int ivalue2 = static_cast<int> (value2);
int ivalue3 = static_cast<int> (values[0]);
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 || ivalue2 >= ivalue3)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
double value;
if (update->ntimestep < ivalue1) value = ivalue1;
else {
@ -3521,14 +3522,14 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"logfreq2") == 0) {
if (narg != 3)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = LOGFREQ2;
else {
int ivalue1 = static_cast<int> (value1);
int ivalue2 = static_cast<int> (value2);
int ivalue3 = static_cast<int> (values[0]);
if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 )
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
double value;
if (update->ntimestep < ivalue1) value = ivalue1;
else {
@ -3546,7 +3547,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"stride") == 0) {
if (narg != 3)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = STRIDE;
else {
int ivalue1 = static_cast<int> (value1);
@ -3566,7 +3567,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"stride2") == 0) {
if (narg != 6)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (tree) newtree->type = STRIDE2;
else {
int ivalue1 = static_cast<int> (value1);
@ -3604,9 +3605,9 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"vdisplace") == 0) {
if (narg != 2)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (update->whichflag == 0)
error->all(FLERR,"Cannot use vdisplace in variable formula between runs");
print_var_error(FLERR,"Cannot use vdisplace in variable formula between runs",ivar);
if (tree) newtree->type = VDISPLACE;
else {
double delta = update->ntimestep - update->beginstep;
@ -3616,13 +3617,13 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"swiggle") == 0) {
if (narg != 3)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (update->whichflag == 0)
error->all(FLERR,"Cannot use swiggle in variable formula between runs");
print_var_error(FLERR,"Cannot use swiggle in variable formula between runs",ivar);
if (tree) newtree->type = CWIGGLE;
else {
if (values[0] == 0.0)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
double delta = update->ntimestep - update->beginstep;
double omega = 2.0*MY_PI/values[0];
double value = value1 + value2*sin(omega*delta*update->dt);
@ -3631,13 +3632,13 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"cwiggle") == 0) {
if (narg != 3)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
if (update->whichflag == 0)
error->all(FLERR,"Cannot use cwiggle in variable formula between runs");
print_var_error(FLERR,"Cannot use cwiggle in variable formula between runs",ivar);
if (tree) newtree->type = CWIGGLE;
else {
if (values[0] == 0.0)
error->all(FLERR,"Invalid math function in variable formula");
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
double delta = update->ntimestep - update->beginstep;
double omega = 2.0*MY_PI/values[0];
double value = value1 + value2*(1.0-cos(omega*delta*update->dt));
@ -3667,7 +3668,7 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
int Variable::group_function(char *word, char *contents, Tree **tree,
Tree **treestack, int &ntreestack,
double *argstack, int &nargstack)
double *argstack, int &nargstack, int ivar)
{
// word not a match to any group function
@ -3690,7 +3691,7 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
int igroup = group->find(args[0]);
if (igroup == -1)
error->all(FLERR,"Group ID in variable formula does not exist");
print_var_error(FLERR,"Group ID in variable formula does not exist",ivar);
// match word to group function
@ -3698,18 +3699,18 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
if (strcmp(word,"count") == 0) {
if (narg == 1) value = group->count(igroup);
else if (narg == 2) value = group->count(igroup,region_function(args[1]));
else error->all(FLERR,"Invalid group function in variable formula");
else if (narg == 2) value = group->count(igroup,region_function(args[1],ivar));
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"mass") == 0) {
if (narg == 1) value = group->mass(igroup);
else if (narg == 2) value = group->mass(igroup,region_function(args[1]));
else error->all(FLERR,"Invalid group function in variable formula");
else if (narg == 2) value = group->mass(igroup,region_function(args[1],ivar));
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"charge") == 0) {
if (narg == 1) value = group->charge(igroup);
else if (narg == 2) value = group->charge(igroup,region_function(args[1]));
else error->all(FLERR,"Invalid group function in variable formula");
else if (narg == 2) value = group->charge(igroup,region_function(args[1],ivar));
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"xcm") == 0) {
atom->check_mass(FLERR);
@ -3718,14 +3719,14 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
double masstotal = group->mass(igroup);
group->xcm(igroup,masstotal,xcm);
} else if (narg == 3) {
int iregion = region_function(args[2]);
int iregion = region_function(args[2],ivar);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
if (strcmp(args[1],"x") == 0) value = xcm[0];
else if (strcmp(args[1],"y") == 0) value = xcm[1];
else if (strcmp(args[1],"z") == 0) value = xcm[2];
else error->all(FLERR,"Invalid group function in variable formula");
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"vcm") == 0) {
atom->check_mass(FLERR);
@ -3734,37 +3735,37 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
double masstotal = group->mass(igroup);
group->vcm(igroup,masstotal,vcm);
} else if (narg == 3) {
int iregion = region_function(args[2]);
int iregion = region_function(args[2],ivar);
double masstotal = group->mass(igroup,iregion);
group->vcm(igroup,masstotal,vcm,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
if (strcmp(args[1],"x") == 0) value = vcm[0];
else if (strcmp(args[1],"y") == 0) value = vcm[1];
else if (strcmp(args[1],"z") == 0) value = vcm[2];
else error->all(FLERR,"Invalid group function in variable formula");
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"fcm") == 0) {
double fcm[3];
if (narg == 2) group->fcm(igroup,fcm);
else if (narg == 3) group->fcm(igroup,fcm,region_function(args[2]));
else error->all(FLERR,"Invalid group function in variable formula");
else if (narg == 3) group->fcm(igroup,fcm,region_function(args[2],ivar));
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
if (strcmp(args[1],"x") == 0) value = fcm[0];
else if (strcmp(args[1],"y") == 0) value = fcm[1];
else if (strcmp(args[1],"z") == 0) value = fcm[2];
else error->all(FLERR,"Invalid group function in variable formula");
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"bound") == 0) {
double minmax[6];
if (narg == 2) group->bounds(igroup,minmax);
else if (narg == 3) group->bounds(igroup,minmax,region_function(args[2]));
else error->all(FLERR,"Invalid group function in variable formula");
else if (narg == 3) group->bounds(igroup,minmax,region_function(args[2],ivar));
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
if (strcmp(args[1],"xmin") == 0) value = minmax[0];
else if (strcmp(args[1],"xmax") == 0) value = minmax[1];
else if (strcmp(args[1],"ymin") == 0) value = minmax[2];
else if (strcmp(args[1],"ymax") == 0) value = minmax[3];
else if (strcmp(args[1],"zmin") == 0) value = minmax[4];
else if (strcmp(args[1],"zmax") == 0) value = minmax[5];
else error->all(FLERR,"Invalid group function in variable formula");
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"gyration") == 0) {
atom->check_mass(FLERR);
@ -3774,16 +3775,16 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
group->xcm(igroup,masstotal,xcm);
value = group->gyration(igroup,masstotal,xcm);
} else if (narg == 2) {
int iregion = region_function(args[1]);
int iregion = region_function(args[1],ivar);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
value = group->gyration(igroup,masstotal,xcm,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"ke") == 0) {
if (narg == 1) value = group->ke(igroup);
else if (narg == 2) value = group->ke(igroup,region_function(args[1]));
else error->all(FLERR,"Invalid group function in variable formula");
else if (narg == 2) value = group->ke(igroup,region_function(args[1],ivar));
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"angmom") == 0) {
atom->check_mass(FLERR);
@ -3793,15 +3794,15 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
group->xcm(igroup,masstotal,xcm);
group->angmom(igroup,xcm,lmom);
} else if (narg == 3) {
int iregion = region_function(args[2]);
int iregion = region_function(args[2],ivar);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
group->angmom(igroup,xcm,lmom,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
if (strcmp(args[1],"x") == 0) value = lmom[0];
else if (strcmp(args[1],"y") == 0) value = lmom[1];
else if (strcmp(args[1],"z") == 0) value = lmom[2];
else error->all(FLERR,"Invalid group function in variable formula");
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"torque") == 0) {
atom->check_mass(FLERR);
@ -3811,15 +3812,15 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
group->xcm(igroup,masstotal,xcm);
group->torque(igroup,xcm,tq);
} else if (narg == 3) {
int iregion = region_function(args[2]);
int iregion = region_function(args[2],ivar);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
group->torque(igroup,xcm,tq,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
if (strcmp(args[1],"x") == 0) value = tq[0];
else if (strcmp(args[1],"y") == 0) value = tq[1];
else if (strcmp(args[1],"z") == 0) value = tq[2];
else error->all(FLERR,"Invalid group function in variable formula");
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"inertia") == 0) {
atom->check_mass(FLERR);
@ -3829,18 +3830,18 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
group->xcm(igroup,masstotal,xcm);
group->inertia(igroup,xcm,inertia);
} else if (narg == 3) {
int iregion = region_function(args[2]);
int iregion = region_function(args[2],ivar);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
group->inertia(igroup,xcm,inertia,iregion);
} else error->all(FLERR,"Invalid group function in variable formula");
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
if (strcmp(args[1],"xx") == 0) value = inertia[0][0];
else if (strcmp(args[1],"yy") == 0) value = inertia[1][1];
else if (strcmp(args[1],"zz") == 0) value = inertia[2][2];
else if (strcmp(args[1],"xy") == 0) value = inertia[0][1];
else if (strcmp(args[1],"yz") == 0) value = inertia[1][2];
else if (strcmp(args[1],"xz") == 0) value = inertia[0][2];
else error->all(FLERR,"Invalid group function in variable formula");
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
} else if (strcmp(word,"omega") == 0) {
atom->check_mass(FLERR);
@ -3852,17 +3853,17 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
group->inertia(igroup,xcm,inertia);
group->omega(angmom,inertia,omega);
} else if (narg == 3) {
int iregion = region_function(args[2]);
int iregion = region_function(args[2],ivar);
double masstotal = group->mass(igroup,iregion);
group->xcm(igroup,masstotal,xcm,iregion);
group->angmom(igroup,xcm,angmom,iregion);
group->inertia(igroup,xcm,inertia,iregion);
group->omega(angmom,inertia,omega);
} else error->all(FLERR,"Invalid group function in variable formula");
} else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
if (strcmp(args[1],"x") == 0) value = omega[0];
else if (strcmp(args[1],"y") == 0) value = omega[1];
else if (strcmp(args[1],"z") == 0) value = omega[2];
else error->all(FLERR,"Invalid group function in variable formula");
else print_var_error(FLERR,"Invalid group function in variable formula",ivar);
}
// delete stored args
@ -3885,11 +3886,11 @@ int Variable::group_function(char *word, char *contents, Tree **tree,
/* ---------------------------------------------------------------------- */
int Variable::region_function(char *id)
int Variable::region_function(char *id, int ivar)
{
int iregion = domain->find_region(id);
if (iregion == -1)
error->all(FLERR,"Region ID in variable formula does not exist");
print_var_error(FLERR,"Region ID in variable formula does not exist",ivar);
// init region in case sub-regions have been deleted
@ -3911,7 +3912,7 @@ int Variable::region_function(char *id)
int Variable::special_function(char *word, char *contents, Tree **tree,
Tree **treestack, int &ntreestack,
double *argstack, int &nargstack)
double *argstack, int &nargstack, int ivar)
{
double value,xvalue,sx,sy,sxx,sxy;
@ -3946,7 +3947,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
else if (strcmp(word,"slope") == 0) method = SLOPE;
if (narg != 1)
error->all(FLERR,"Invalid special function in variable formula");
print_var_error(FLERR,"Invalid special function in variable formula",ivar);
Compute *compute = NULL;
Fix *fix = NULL;
@ -3974,8 +3975,8 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
if (index == 0 && compute->vector_flag) {
if (update->whichflag == 0) {
if (compute->invoked_vector != update->ntimestep)
error->all(FLERR,
"Compute used in variable between runs is not current");
print_var_error(FLERR,"Compute used in variable between runs "
"is not current",ivar);
} else if (!(compute->invoked_flag & INVOKED_VECTOR)) {
compute->compute_vector();
compute->invoked_flag |= INVOKED_VECTOR;
@ -3984,19 +3985,19 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
nstride = 1;
} else if (index && compute->array_flag) {
if (index > compute->size_array_cols)
error->all(FLERR,"Variable formula compute array "
"is accessed out-of-range");
print_var_error(FLERR,"Variable formula compute array "
"is accessed out-of-range",ivar);
if (update->whichflag == 0) {
if (compute->invoked_array != update->ntimestep)
error->all(FLERR,
"Compute used in variable between runs is not current");
print_var_error(FLERR,"Compute used in variable between runs "
"is not current",ivar);
} else if (!(compute->invoked_flag & INVOKED_ARRAY)) {
compute->compute_array();
compute->invoked_flag |= INVOKED_ARRAY;
}
nvec = compute->size_array_rows;
nstride = compute->size_array_cols;
} else error->all(FLERR,"Mismatched compute in variable formula");
} else print_var_error(FLERR,"Mismatched compute in variable formula",ivar);
// argument is fix
@ -4009,22 +4010,22 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
} else index = 0;
int ifix = modify->find_fix(&args[0][2]);
if (ifix < 0) error->all(FLERR,"Invalid fix ID in variable formula");
if (ifix < 0) print_var_error(FLERR,"Invalid fix ID in variable formula",ivar);
fix = modify->fix[ifix];
if (index == 0 && fix->vector_flag) {
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
print_var_error(FLERR,"Fix in variable not computed at compatible time",ivar);
nvec = fix->size_vector;
nstride = 1;
} else if (index && fix->array_flag) {
if (index > fix->size_array_cols)
error->all(FLERR,
"Variable formula fix array is accessed out-of-range");
print_var_error(FLERR,"Variable formula fix array "
"is accessed out-of-range",ivar);
if (update->whichflag > 0 && update->ntimestep % fix->global_freq)
error->all(FLERR,"Fix in variable not computed at compatible time");
print_var_error(FLERR,"Fix in variable not computed at compatible time",ivar);
nvec = fix->size_array_rows;
nstride = fix->size_array_cols;
} else error->all(FLERR,"Mismatched fix in variable formula");
} else print_var_error(FLERR,"Mismatched fix in variable formula",ivar);
// argument is vector-style variable
@ -4037,21 +4038,21 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
} else index = 0;
if (index)
error->all(FLERR,"Invalid special function in variable formula");
print_var_error(FLERR,"Invalid special function in variable formula",ivar);
ivar = find(&args[0][2]);
if (ivar < 0)
error->all(FLERR,"Invalid special function in variable formula");
print_var_error(FLERR,"Invalid special function in variable formula",ivar);
if (style[ivar] != VECTOR)
error->all(FLERR,
"Mis-matched special function variable in variable formula");
print_var_error(FLERR,"Mis-matched special function variable "
"in variable formula",ivar);
if (eval_in_progress[ivar])
error->all(FLERR,"Variable has circular dependency");
print_var_error(FLERR,"Variable has circular dependency",ivar);
double *vec;
nvec = compute_vector(ivar,&vec);
nstride = 1;
} else error->all(FLERR,"Invalid special function in variable formula");
} else print_var_error(FLERR,"Invalid special function in variable formula",ivar);
value = 0.0;
if (method == SLOPE) sx = sy = sxx = sxy = 0.0;
@ -4158,13 +4159,13 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"gmask") == 0) {
if (tree == NULL)
error->all(FLERR,"Gmask function in equal-style variable formula");
print_var_error(FLERR,"Gmask function in equal-style variable formula",ivar);
if (narg != 1)
error->all(FLERR,"Invalid special function in variable formula");
print_var_error(FLERR,"Invalid special function in variable formula",ivar);
int igroup = group->find(args[0]);
if (igroup == -1)
error->all(FLERR,"Group ID in variable formula does not exist");
print_var_error(FLERR,"Group ID in variable formula does not exist",ivar);
Tree *newtree = new Tree();
newtree->type = GMASK;
@ -4175,11 +4176,11 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"rmask") == 0) {
if (tree == NULL)
error->all(FLERR,"Rmask function in equal-style variable formula");
print_var_error(FLERR,"Rmask function in equal-style variable formula",ivar);
if (narg != 1)
error->all(FLERR,"Invalid special function in variable formula");
print_var_error(FLERR,"Invalid special function in variable formula",ivar);
int iregion = region_function(args[0]);
int iregion = region_function(args[0],ivar);
domain->regions[iregion]->prematch();
Tree *newtree = new Tree();
@ -4191,14 +4192,14 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"grmask") == 0) {
if (tree == NULL)
error->all(FLERR,"Grmask function in equal-style variable formula");
print_var_error(FLERR,"Grmask function in equal-style variable formula",ivar);
if (narg != 2)
error->all(FLERR,"Invalid special function in variable formula");
print_var_error(FLERR,"Invalid special function in variable formula",ivar);
int igroup = group->find(args[0]);
if (igroup == -1)
error->all(FLERR,"Group ID in variable formula does not exist");
int iregion = region_function(args[1]);
print_var_error(FLERR,"Group ID in variable formula does not exist",ivar);
int iregion = region_function(args[1],ivar);
domain->regions[iregion]->prematch();
Tree *newtree = new Tree();
@ -4213,11 +4214,11 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"next") == 0) {
if (narg != 1)
error->all(FLERR,"Invalid special function in variable formula");
print_var_error(FLERR,"Invalid special function in variable formula",ivar);
int ivar = find(args[0]);
if (ivar < 0)
error->all(FLERR,"Variable ID in variable formula does not exist");
print_var_error(FLERR,"Variable ID in variable formula does not exist",ivar);
// SCALARFILE has single current value, read next one
// save value in tree or on argstack
@ -4242,7 +4243,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
} else if (style[ivar] == ATOMFILE) {
if (tree == NULL)
error->all(FLERR,"Atomfile variable in equal-style variable formula");
print_var_error(FLERR,"Atomfile variable in equal-style variable formula",ivar);
double *result;
memory->create(result,atom->nlocal,"variable:result");
@ -4260,11 +4261,11 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
newtree->nextra = 0;
treestack[ntreestack++] = newtree;
} else error->all(FLERR,"Invalid variable style in special function next");
} else print_var_error(FLERR,"Invalid variable style in special function next",ivar);
} else if (strcmp(word,"is_active") == 0) {
if (narg != 2)
error->all(FLERR,"Invalid is_active() function in variable formula");
print_var_error(FLERR,"Invalid is_active() function in variable formula",ivar);
Info info(lmp);
value = (info.is_active(args[0],args[1])) ? 1.0 : 0.0;
@ -4282,7 +4283,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"is_available") == 0) {
if (narg != 2)
error->all(FLERR,"Invalid is_available() function in variable formula");
print_var_error(FLERR,"Invalid is_available() function in variable formula",ivar);
Info info(lmp);
value = (info.is_available(args[0],args[1])) ? 1.0 : 0.0;
@ -4300,7 +4301,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
} else if (strcmp(word,"is_defined") == 0) {
if (narg != 2)
error->all(FLERR,"Invalid is_defined() function in variable formula");
print_var_error(FLERR,"Invalid is_defined() function in variable formula",ivar);
Info info(lmp);
value = (info.is_defined(args[0],args[1])) ? 1.0 : 0.0;
@ -4589,18 +4590,19 @@ char *Variable::find_next_comma(char *str)
/* ----------------------------------------------------------------------
debug routine for printing formula tree recursively
helper routine for printing variable name with error message
------------------------------------------------------------------------- */
void Variable::print_var_error(const char *srcfile, int lineno,
const char *errmsg, int ivar)
{
const char *varname = (const char*)"(unknown)";
if ((ivar >= 0) && (ivar < nvar)) varname = names[ivar];
if ((ivar >= 0) && (ivar < nvar)) {
char msg[128];
char msg[128];
sprintf(msg,"Variable %s: %s",varname,errmsg);
error->all(srcfile,lineno,msg);}
sprintf(msg,"Variable %s: %s",names[ivar],errmsg);
error->all(srcfile,lineno,msg);
} else error->all(srcfile,lineno,errmsg);
}
/* ----------------------------------------------------------------------
debug routine for printing formula tree recursively
@ -4662,7 +4664,7 @@ double Variable::evaluate_boolean(char *str)
expect = OP;
char *contents;
i = find_matching_paren(str,i,contents);
i = find_matching_paren(str,i,contents,-1);
i++;
// evaluate contents and push on stack

View File

@ -97,18 +97,20 @@ class Variable : protected Pointers {
void remove(int);
void grow();
void copy(int, char **, char **);
double evaluate(char *, Tree **, int ivar=-1);
double evaluate(char *, Tree **, int);
double collapse_tree(Tree *);
double eval_tree(Tree *, int);
int size_tree_vector(Tree *);
int compare_tree_vector(int, int);
void free_tree(Tree *);
int find_matching_paren(char *, int, char *&, int ivar=-1);
int math_function(char *, char *, Tree **, Tree **, int &, double *, int &);
int group_function(char *, char *, Tree **, Tree **, int &, double *, int &);
int region_function(char *);
int find_matching_paren(char *, int, char *&, int);
int math_function(char *, char *, Tree **, Tree **,
int &, double *, int &, int);
int group_function(char *, char *, Tree **, Tree **,
int &, double *, int &, int);
int region_function(char *, int);
int special_function(char *, char *, Tree **, Tree **,
int &, double *, int &);
int &, double *, int &, int);
void peratom2global(int, char *, double *, int, tagint,
Tree **, Tree **, int &, double *, int &);
int is_atom_vector(char *);