added XOR operator to variable command

This commit is contained in:
Steve Plimpton
2016-10-03 17:57:33 -06:00
parent e2c7acabac
commit c3ff8812b3
7 changed files with 64 additions and 31 deletions

View File

@ -1,7 +1,7 @@
<!-- HTML_ONLY --> <!-- HTML_ONLY -->
<HEAD> <HEAD>
<TITLE>LAMMPS Users Manual</TITLE> <TITLE>LAMMPS Users Manual</TITLE>
<META NAME="docnumber" CONTENT="29 Sep 2016 version"> <META NAME="docnumber" CONTENT="30 Sep 2016 version">
<META NAME="author" CONTENT="http://lammps.sandia.gov - Sandia National Laboratories"> <META NAME="author" CONTENT="http://lammps.sandia.gov - Sandia National Laboratories">
<META NAME="copyright" CONTENT="Copyright (2003) Sandia Corporation. This software and manual is distributed under the GNU General Public License."> <META NAME="copyright" CONTENT="Copyright (2003) Sandia Corporation. This software and manual is distributed under the GNU General Public License.">
</HEAD> </HEAD>
@ -21,7 +21,7 @@
<H1></H1> <H1></H1>
LAMMPS Documentation :c,h3 LAMMPS Documentation :c,h3
29 Sep 2016 version :c,h4 30 Sep 2016 version :c,h4
Version info: :h4 Version info: :h4

View File

@ -139,7 +139,7 @@ InP, myString, a123, ab_23_cd, etc :pre
and Boolean operators: and Boolean operators:
A == B, A != B, A < B, A <= B, A > B, A >= B, A && B, A || B, !A :pre A == B, A != B, A < B, A <= B, A > B, A >= B, A && B, A || B, A |^ B, !A :pre
Each A and B is a number or string or a variable reference like $a or Each A and B is a number or string or a variable reference like $a or
$\{abc\}, or A or B can be another Boolean expression. $\{abc\}, or A or B can be another Boolean expression.
@ -155,9 +155,10 @@ precedence: the unary logical NOT operator "!" has the highest
precedence, the 4 relational operators "<", "<=", ">", and ">=" are precedence, the 4 relational operators "<", "<=", ">", and ">=" are
next; the two remaining relational operators "==" and "!=" are next; next; the two remaining relational operators "==" and "!=" are next;
then the logical AND operator "&&"; and finally the logical OR then the logical AND operator "&&"; and finally the logical OR
operator "||" has the lowest precedence. Parenthesis can be used to operator "||" and logical XOR (exclusive or) operator "|^" have the
group one or more portions of an expression and/or enforce a different lowest precedence. Parenthesis can be used to group one or more
order of evaluation than what would occur with the default precedence. portions of an expression and/or enforce a different order of
evaluation than what would occur with the default precedence.
When the 6 relational operators (first 6 in list above) compare 2 When the 6 relational operators (first 6 in list above) compare 2
numbers, they return either a 1.0 or 0.0 depending on whether the numbers, they return either a 1.0 or 0.0 depending on whether the
@ -171,9 +172,11 @@ relationship between A and B is TRUE or FALSE (or just A). The
logical AND operator will return 1.0 if both its arguments are logical AND operator will return 1.0 if both its arguments are
non-zero, else it returns 0.0. The logical OR operator will return non-zero, else it returns 0.0. The logical OR operator will return
1.0 if either of its arguments is non-zero, else it returns 0.0. The 1.0 if either of its arguments is non-zero, else it returns 0.0. The
logical NOT operator returns 1.0 if its argument is 0.0, else it logical XOR operator will return 1.0 if one of its arguments is zero
returns 0.0. The 3 logical operators can only be used to operate on and the other non-zero, else it returns 0.0. The logical NOT operator
numbers, not on strings. returns 1.0 if its argument is 0.0, else it returns 0.0. The 3
logical operators can only be used to operate on numbers, not on
strings.
The overall Boolean expression produces a TRUE result if the result is The overall Boolean expression produces a TRUE result if the result is
non-zero. If the result is zero, the expression result is FALSE. non-zero. If the result is zero, the expression result is FALSE.

View File

@ -47,7 +47,7 @@ style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {st
constants = PI, version, on, off, true, false, yes, no constants = PI, version, on, off, true, false, yes, no
thermo keywords = vol, ke, press, etc from "thermo_style"_thermo_style.html thermo keywords = vol, ke, press, etc from "thermo_style"_thermo_style.html
math operators = (), -x, x+y, x-y, x*y, x/y, x^y, x%y, math operators = (), -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 x == y, x != y, x < y, x <= y, x > y, x >= y, x && y, x || y, x |^ y, !x
math functions = sqrt(x), exp(x), ln(x), log(x), abs(x), math functions = sqrt(x), exp(x), ln(x), log(x), abs(x),
sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x),
random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x) random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x)
@ -450,7 +450,7 @@ Number: 0.2, 100, 1.0e20, -15.4, etc
Constant: PI, version, on, off, true, false, yes, no Constant: PI, version, on, off, true, false, yes, no
Thermo keywords: vol, pe, ebond, etc Thermo keywords: vol, pe, ebond, etc
Math operators: (), -x, x+y, x-y, x*y, x/y, x^y, x%y, \ Math operators: (), -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 x == y, x != y, x < y, x <= y, x > y, x >= y, x && y, x || y, x |^ y, !x
Math functions: sqrt(x), exp(x), ln(x), log(x), abs(x), \ Math functions: sqrt(x), exp(x), ln(x), log(x), abs(x), \
sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), \ sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), \
random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x), \ random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x), \
@ -551,9 +551,10 @@ division and the modulo operator "%" are next; addition and
subtraction are next; the 4 relational operators "<", "<=", ">", and subtraction are next; the 4 relational operators "<", "<=", ">", and
">=" are next; the two remaining relational operators "==" and "!=" ">=" are next; the two remaining relational operators "==" and "!="
are next; then the logical AND operator "&&"; and finally the logical are next; then the logical AND operator "&&"; and finally the logical
OR operator "||" has the lowest precedence. Parenthesis can be used OR operator "||" and logical XOR (exclusive or) operator "|^" have the
to group one or more portions of a formula and/or enforce a different lowest precedence. Parenthesis can be used to group one or more
order of evaluation than what would occur with the default precedence. portions of a formula and/or enforce a different order of evaluation
than what would occur with the default precedence.
NOTE: Because a unary minus is higher precedence than exponentiation, NOTE: Because a unary minus is higher precedence than exponentiation,
the formula "-2^2" will evaluate to 4, not -4. This convention is the formula "-2^2" will evaluate to 4, not -4. This convention is
@ -568,8 +569,10 @@ return 1.0 for all atoms whose x-coordinate is less than 10.0, and 0.0
for the others. The logical AND operator will return 1.0 if both its for the others. The logical AND operator will return 1.0 if both its
arguments are non-zero, else it returns 0.0. The logical OR operator arguments are non-zero, else it returns 0.0. The logical OR operator
will return 1.0 if either of its arguments is non-zero, else it will return 1.0 if either of its arguments is non-zero, else it
returns 0.0. The logical NOT operator returns 1.0 if its argument is returns 0.0. The logical XOR operator will return 1.0 if one of its
0.0, else it returns 0.0. arguments is zero and the other non-zero, else it returns 0.0. The
logical NOT operator returns 1.0 if its argument is 0.0, else it
returns 0.0.
These relational and logical operators can be used as a masking or These relational and logical operators can be used as a masking or
selection operation in a formula. For example, the number of atoms selection operation in a formula. For example, the number of atoms

View File

@ -89,10 +89,9 @@ FixCMAP::FixCMAP(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg)
memory->create(d2cmapgrid,6,CMAPDIM,CMAPDIM,"cmap:d2grid"); memory->create(d2cmapgrid,6,CMAPDIM,CMAPDIM,"cmap:d2grid");
memory->create(d12cmapgrid,6,CMAPDIM,CMAPDIM,"cmap:d12grid"); memory->create(d12cmapgrid,6,CMAPDIM,CMAPDIM,"cmap:d12grid");
// read, initialize, broadcast cmapgrid // read and setup CMAP data
if (me == 0) read_grid_map(arg[3]); read_grid_map(arg[3]);
MPI_Bcast(&cmapgrid[0][0][0],6*CMAPDIM*CMAPDIM,MPI_DOUBLE,0,world);
// perform initial allocation of atom-based arrays // perform initial allocation of atom-based arrays
// register with Atom class // register with Atom class

View File

@ -56,11 +56,11 @@ enum{INDEX,LOOP,WORLD,UNIVERSE,ULOOP,STRING,GETENV,
enum{ARG,OP}; enum{ARG,OP};
// customize by adding a function // customize by adding a function
// if add before OR, // if add before XOR:
// also set precedence level in constructor and precedence length in *.h // also set precedence level in constructor and precedence length in *.h
enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY, enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY,
NOT,EQ,NE,LT,LE,GT,GE,AND,OR, NOT,EQ,NE,LT,LE,GT,GE,AND,OR,XOR,
SQRT,EXP,LN,LOG,ABS,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2, SQRT,EXP,LN,LOG,ABS,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2,
RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,LOGFREQ2, RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,LOGFREQ2,
STRIDE,STRIDE2,VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,GRMASK, STRIDE,STRIDE2,VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,GRMASK,
@ -103,7 +103,7 @@ Variable::Variable(LAMMPS *lmp) : Pointers(lmp)
// customize by assigning a precedence level // customize by assigning a precedence level
precedence[DONE] = 0; precedence[DONE] = 0;
precedence[OR] = 1; precedence[OR] = precedence[XOR] = 1;
precedence[AND] = 2; precedence[AND] = 2;
precedence[EQ] = precedence[NE] = 3; precedence[EQ] = precedence[NE] = 3;
precedence[LT] = precedence[LE] = precedence[GT] = precedence[GE] = 4; precedence[LT] = precedence[LE] = precedence[GT] = precedence[GE] = 4;
@ -2088,9 +2088,9 @@ double Variable::evaluate(char *str, Tree **tree)
op = AND; op = AND;
i++; i++;
} else if (onechar == '|') { } else if (onechar == '|') {
if (str[i+1] != '|') if (str[i+1] == '|') op = OR;
error->all(FLERR,"Invalid syntax in variable formula"); else if (str[i+1] == '^') op = XOR;
op = OR; else error->all(FLERR,"Invalid syntax in variable formula");
i++; i++;
} else op = DONE; } else op = DONE;
@ -2180,6 +2180,10 @@ double Variable::evaluate(char *str, Tree **tree)
} else if (opprevious == OR) { } else if (opprevious == OR) {
if (value1 != 0.0 || value2 != 0.0) argstack[nargstack++] = 1.0; if (value1 != 0.0 || value2 != 0.0) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0; else argstack[nargstack++] = 0.0;
} else if (opprevious == XOR) {
if ((value1 == 0.0 && value2 != 0.0) ||
(value1 != 0.0 && value2 == 0.0)) argstack[nargstack++] = 1.0;
else argstack[nargstack++] = 0.0;
} }
} }
} }
@ -2390,6 +2394,17 @@ double Variable::collapse_tree(Tree *tree)
return tree->value; return tree->value;
} }
if (tree->type == XOR) {
arg1 = collapse_tree(tree->first);
arg2 = collapse_tree(tree->second);
if (tree->first->type != VALUE || tree->second->type != VALUE) return 0.0;
tree->type = VALUE;
if ((arg1 == 0.0 && arg2 != 0.0) || (arg1 != 0.0 && arg2 == 0.0))
tree->value = 1.0;
else tree->value = 0.0;
return tree->value;
}
if (tree->type == SQRT) { if (tree->type == SQRT) {
arg1 = collapse_tree(tree->first); arg1 = collapse_tree(tree->first);
if (tree->first->type != VALUE) return 0.0; if (tree->first->type != VALUE) return 0.0;
@ -2809,6 +2824,13 @@ double Variable::eval_tree(Tree *tree, int i)
return 1.0; return 1.0;
else return 0.0; else return 0.0;
} }
if (tree->type == XOR) {
if ((eval_tree(tree->first,i) == 0.0 && eval_tree(tree->second,i) != 0.0)
||
(eval_tree(tree->first,i) != 0.0 && eval_tree(tree->second,i) == 0.0))
return 1.0;
else return 0.0;
}
if (tree->type == SQRT) { if (tree->type == SQRT) {
arg1 = eval_tree(tree->first,i); arg1 = eval_tree(tree->first,i);
@ -4678,9 +4700,9 @@ double Variable::evaluate_boolean(char *str)
op = AND; op = AND;
i++; i++;
} else if (onechar == '|') { } else if (onechar == '|') {
if (str[i+1] != '|') if (str[i+1] == '|') op = OR;
error->all(FLERR,"Invalid Boolean syntax in if command"); else if (str[i+1] == '^') op = XOR;
op = OR; else error->all(FLERR,"Invalid Boolean syntax in if command");
i++; i++;
} else op = DONE; } else op = DONE;
@ -4764,6 +4786,12 @@ double Variable::evaluate_boolean(char *str)
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command"); if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
if (value1 != 0.0 || value2 != 0.0) argstack[nargstack].value = 1.0; if (value1 != 0.0 || value2 != 0.0) argstack[nargstack].value = 1.0;
else argstack[nargstack].value = 0.0; else argstack[nargstack].value = 0.0;
} else if (opprevious == XOR) {
if (flag2) error->all(FLERR,"Invalid Boolean syntax in if command");
if ((value1 == 0.0 && value2 != 0.0) ||
(value1 != 0.0 && value2 == 0.0))
argstack[nargstack].value = 1.0;
else argstack[nargstack].value = 0.0;
} }
argstack[nargstack++].flag = 0; argstack[nargstack++].flag = 0;

View File

@ -78,8 +78,8 @@ class Variable : protected Pointers {
class RanMars *randomequal; // random number generator for equal-style vars class RanMars *randomequal; // random number generator for equal-style vars
class RanMars *randomatom; // random number generator for atom-style vars class RanMars *randomatom; // random number generator for atom-style vars
int precedence[17]; // precedence level of math operators int precedence[18]; // precedence level of math operators
// set length to include up to OR in enum // set length to include up to XOR in enum
class Python *python; // ptr to embedded Python interpreter class Python *python; // ptr to embedded Python interpreter

View File

@ -1 +1 @@
#define LAMMPS_VERSION "29 Sep 2016" #define LAMMPS_VERSION "30 Sep 2016"