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 -->
<HEAD>
<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="copyright" CONTENT="Copyright (2003) Sandia Corporation. This software and manual is distributed under the GNU General Public License.">
</HEAD>
@ -21,7 +21,7 @@
<H1></H1>
LAMMPS Documentation :c,h3
29 Sep 2016 version :c,h4
30 Sep 2016 version :c,h4
Version info: :h4

View File

@ -139,7 +139,7 @@ InP, myString, a123, ab_23_cd, etc :pre
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
$\{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
next; the two remaining relational operators "==" and "!=" are next;
then the logical AND operator "&&"; and finally the logical OR
operator "||" has the lowest precedence. Parenthesis can be used to
group one or more portions of an expression and/or enforce a different
order of evaluation than what would occur with the default precedence.
operator "||" and logical XOR (exclusive or) operator "|^" have the
lowest precedence. Parenthesis can be used to group one or more
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
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
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
logical NOT operator 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.
logical XOR operator will return 1.0 if one of its 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. 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
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
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,
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),
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)
@ -450,7 +450,7 @@ Number: 0.2, 100, 1.0e20, -15.4, etc
Constant: PI, version, on, off, true, false, yes, no
Thermo keywords: vol, pe, ebond, etc
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), \
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), \
@ -551,9 +551,10 @@ division and the modulo operator "%" are next; addition and
subtraction are next; the 4 relational operators "<", "<=", ">", and
">=" are next; the two remaining relational operators "==" and "!="
are next; then the logical AND operator "&&"; and finally the logical
OR operator "||" has the lowest precedence. Parenthesis can be used
to group one or more portions of a formula and/or enforce a different
order of evaluation than what would occur with the default precedence.
OR operator "||" and logical XOR (exclusive or) operator "|^" have the
lowest precedence. Parenthesis can be used to group one or more
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,
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
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
returns 0.0. The logical NOT operator returns 1.0 if its argument is
0.0, else it returns 0.0.
returns 0.0. The logical XOR operator will return 1.0 if one of its
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
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(d12cmapgrid,6,CMAPDIM,CMAPDIM,"cmap:d12grid");
// read, initialize, broadcast cmapgrid
// read and setup CMAP data
if (me == 0) read_grid_map(arg[3]);
MPI_Bcast(&cmapgrid[0][0][0],6*CMAPDIM*CMAPDIM,MPI_DOUBLE,0,world);
read_grid_map(arg[3]);
// perform initial allocation of atom-based arrays
// register with Atom class

View File

@ -56,11 +56,11 @@ enum{INDEX,LOOP,WORLD,UNIVERSE,ULOOP,STRING,GETENV,
enum{ARG,OP};
// customize by adding a function
// if add before OR,
// if add before XOR:
// also set precedence level in constructor and precedence length in *.h
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,
RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,LOGFREQ2,
STRIDE,STRIDE2,VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,GRMASK,
@ -103,7 +103,7 @@ Variable::Variable(LAMMPS *lmp) : Pointers(lmp)
// customize by assigning a precedence level
precedence[DONE] = 0;
precedence[OR] = 1;
precedence[OR] = precedence[XOR] = 1;
precedence[AND] = 2;
precedence[EQ] = precedence[NE] = 3;
precedence[LT] = precedence[LE] = precedence[GT] = precedence[GE] = 4;
@ -2088,9 +2088,9 @@ double Variable::evaluate(char *str, Tree **tree)
op = AND;
i++;
} else if (onechar == '|') {
if (str[i+1] != '|')
error->all(FLERR,"Invalid syntax in variable formula");
op = OR;
if (str[i+1] == '|') op = OR;
else if (str[i+1] == '^') op = XOR;
else error->all(FLERR,"Invalid syntax in variable formula");
i++;
} else op = DONE;
@ -2180,6 +2180,10 @@ double Variable::evaluate(char *str, Tree **tree)
} else if (opprevious == OR) {
if (value1 != 0.0 || value2 != 0.0) argstack[nargstack++] = 1.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;
}
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) {
arg1 = collapse_tree(tree->first);
if (tree->first->type != VALUE) return 0.0;
@ -2809,6 +2824,13 @@ double Variable::eval_tree(Tree *tree, int i)
return 1.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) {
arg1 = eval_tree(tree->first,i);
@ -4678,9 +4700,9 @@ double Variable::evaluate_boolean(char *str)
op = AND;
i++;
} else if (onechar == '|') {
if (str[i+1] != '|')
error->all(FLERR,"Invalid Boolean syntax in if command");
op = OR;
if (str[i+1] == '|') op = OR;
else if (str[i+1] == '^') op = XOR;
else error->all(FLERR,"Invalid Boolean syntax in if command");
i++;
} 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 (value1 != 0.0 || value2 != 0.0) argstack[nargstack].value = 1.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;

View File

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

View File

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