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

This commit is contained in:
sjplimp
2010-11-18 17:28:47 +00:00
parent 37b51e682f
commit 31e65b4e72
3 changed files with 303 additions and 95 deletions

View File

@ -608,7 +608,7 @@ void Variable::copy(int narg, char **from, char **to)
constant = PI
thermo keyword = ke, vol, atoms, ...
math operation = (),-x,x+y,x-y,x*y,x/y,x^y,
x==y,x!=y,x<y,x<=y,x>y,x>=y,
x==y,x!=y,x<y,x<=y,x>y,x>=y,x&&y,x||y,
sqrt(x),exp(x),ln(x),log(x),
sin(x),cos(x),tan(x),asin(x),atan2(y,x),...
group function = count(group), mass(group), xcm(group,x), ...
@ -3069,3 +3069,175 @@ void Variable::print_tree(Tree *tree, int level)
if (tree->right) print_tree(tree->right,level+1);
return;
}
/* ----------------------------------------------------------------------
recursive evaluation of string str
called from "if" command in input script
str is a boolean expression containing one or more items:
number = 0.0, -5.45, 2.8e-4, ...
math operation = (),x==y,x!=y,x<y,x<=y,x>y,x>=y,x&&y,x||y
------------------------------------------------------------------------- */
double Variable::evaluate_boolean(char *str)
{
int op,opprevious;
double value1,value2;
char onechar;
char *ptr;
double argstack[MAXLEVEL];
int opstack[MAXLEVEL];
int nargstack = 0;
int nopstack = 0;
int i = 0;
int expect = ARG;
while (1) {
onechar = str[i];
// whitespace: just skip
if (isspace(onechar)) i++;
// ----------------
// parentheses: recursively evaluate contents of parens
// ----------------
else if (onechar == '(') {
if (expect == OP) error->all("Invalid Boolean syntax in if command");
expect = OP;
char *contents;
i = find_matching_paren(str,i,contents);
i++;
// evaluate contents and push on stack
argstack[nargstack++] = evaluate_boolean(contents);
delete [] contents;
// ----------------
// number: push value onto stack
// ----------------
} else if (isdigit(onechar) || onechar == '.') {
if (expect == OP) error->all("Invalid Boolean syntax in if command");
expect = OP;
// istop = end of number, including scientific notation
int istart = i;
while (isdigit(str[i]) || str[i] == '.') i++;
if (str[i] == 'e' || str[i] == 'E') {
i++;
if (str[i] == '+' || str[i] == '-') i++;
while (isdigit(str[i])) i++;
}
int istop = i - 1;
int n = istop - istart + 1;
char *number = new char[n+1];
strncpy(number,&str[istart],n);
number[n] = '\0';
argstack[nargstack++] = atof(number);
delete [] number;
// ----------------
// Boolean operator, including end-of-string
// ----------------
} else if (strchr("<>=!&|\0",onechar)) {
if (onechar == '=') {
if (str[i+1] != '=')
error->all("Invalid Boolean syntax in if command");
op = EQ;
i++;
} else if (onechar == '!') {
if (str[i+1] != '=')
error->all("Invalid Boolean syntax in if command");
op = NE;
i++;
} else if (onechar == '<') {
if (str[i+1] != '=') op = LT;
else {
op = LE;
i++;
}
} else if (onechar == '>') {
if (str[i+1] != '=') op = GT;
else {
op = GE;
i++;
}
} else if (onechar == '&') {
if (str[i+1] != '&')
error->all("Invalid Boolean syntax in if command");
op = AND;
i++;
} else if (onechar == '|') {
if (str[i+1] != '|')
error->all("Invalid Boolean syntax in if command");
op = OR;
i++;
} else op = DONE;
i++;
if (expect == ARG) error->all("Invalid Boolean syntax in if command");
expect = ARG;
// evaluate stack as deep as possible while respecting precedence
// before pushing current op onto stack
while (nopstack && precedence[opstack[nopstack-1]] >= precedence[op]) {
opprevious = opstack[--nopstack];
value2 = argstack[--nargstack];
value1 = argstack[--nargstack];
if (opprevious == EQ) {
if (value1 == value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == NE) {
if (value1 != value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == LT) {
if (value1 < value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == LE) {
if (value1 <= value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == GT) {
if (value1 > value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == GE) {
if (value1 >= value2) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == AND) {
if (value1 != 0.0 && value2 != 0.0) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} else if (opprevious == OR) {
if (value1 != 0.0 || value2 != 0.0) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
}
}
// if end-of-string, break out of entire formula evaluation loop
if (op == DONE) break;
// push current operation onto stack
opstack[nopstack++] = op;
} else error->all("Invalid Boolean syntax in if command");
}
if (nopstack) error->all("Invalid Boolean syntax in if command");
if (nargstack != 1) error->all("Invalid Boolean syntax in if command");
return argstack[0];
}