Number | 0.2, 100, 1.0e20, -15.4, etc |
Thermo keywords | vol, pe, ebond, etc |
-Math operations | (), -x, x+y, x-y, x*y, x/y, x^y, sqrt(x), exp(x), ln(x), ceil(x), floor(x), round(x) |
+Math operations | (), -x, 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), acos(x), atan(x), ceil(x), floor(x), round(x) |
Group functions | count(ID), mass(ID), charge(ID), xcm(ID,dim), vcm(ID,dim), fcm(ID,dim), bound(ID,dir), gyration(ID) |
Atom values | mass[N], x[N], y[N], z[N], vx[N], vy[N], vz[N], fx[N], fy[N], fz[N] |
Atom vectors | mass[], x[], y[], z[], vx[], vy[], vz[], fx[], fy[], fz[] |
@@ -240,16 +243,16 @@
Math operations are written in the usual way, where the "x" and "y" in
the examples above can be another section of the formula. Operators
are evaluated left to right and have the usual precedence: unary minus
-before exponentiation, exponentiation before multiplication and
+before exponentiation ("^"), exponentiation before multiplication and
division, and multiplication and division before addition and
subtraction. Parenthesis can be used to group one or more portions of
a formula and enforce a desired order of operations. Additional math
operations can be specified as keywords followed by a parenthesized
-argument, e.g. sqrt(v_ke). The ceil(), floor(), and round()
-operations are those in the C math library. Ceil() is the smallest
-integer not less than its argument. Floor() if the largest integer
-not greater than its argument. Round() is the nearest integer to its
-argument.
+argument, e.g. sqrt(v_ke). Note that ln() is the natural log; log()
+is the base 10 log. The ceil(), floor(), and round() operations are
+those in the C math library. Ceil() is the smallest integer not less
+than its argument. Floor() if the largest integer not greater than
+its argument. Round() is the nearest integer to its argument.
Group functions take one or two arguments in a specific format. The
first argument is the group-ID. The dim argument, if it exists, is
diff -Naur lammps-14May08/doc/variable.txt lammps-15May08/doc/variable.txt
--- lammps-14May08/doc/variable.txt 2008-03-28 10:22:09.000000000 -0600
+++ lammps-15May08/doc/variable.txt 2008-05-15 14:32:10.000000000 -0600
@@ -22,7 +22,10 @@
{equal} or {atom} args = one formula containing numbers, thermo keywords, math operations, group functions, atom values and vectors, compute/fix/variable references
numbers = 0.0, 100, -5.4, 2.8e-4, etc
thermo keywords = vol, ke, press, etc from "thermo_style"_thermo_style.html
- math operations = (), -x, x+y, x-y, x*y, x/y, x^y, sqrt(x), exp(x), ln(x), ceil(x), floor(x), round(x)
+ math operations = (), -x, 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), acos(x), atan(x),
+ ceil(x), floor(x), round(x)
group functions = count(group), mass(group), charge(group),
xcm(group,dim), vcm(group,dim), fcm(group,dim),
bound(group,xmin), gyration(group)
@@ -206,7 +209,7 @@
Number: 0.2, 100, 1.0e20, -15.4, etc
Thermo keywords: vol, pe, ebond, etc
-Math operations: (), -x, x+y, x-y, x*y, x/y, x^y, sqrt(x), exp(x), ln(x), ceil(x), floor(x), round(x)
+Math operations: (), -x, 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), acos(x), atan(x), ceil(x), floor(x), round(x)
Group functions: count(ID), mass(ID), charge(ID), xcm(ID,dim), \
vcm(ID,dim), fcm(ID,dim), bound(ID,dir), gyration(ID)
Atom values: mass\[N\], x\[N\], y\[N\], z\[N\], \
@@ -235,16 +238,16 @@
Math operations are written in the usual way, where the "x" and "y" in
the examples above can be another section of the formula. Operators
are evaluated left to right and have the usual precedence: unary minus
-before exponentiation, exponentiation before multiplication and
+before exponentiation ("^"), exponentiation before multiplication and
division, and multiplication and division before addition and
subtraction. Parenthesis can be used to group one or more portions of
a formula and enforce a desired order of operations. Additional math
operations can be specified as keywords followed by a parenthesized
-argument, e.g. sqrt(v_ke). The ceil(), floor(), and round()
-operations are those in the C math library. Ceil() is the smallest
-integer not less than its argument. Floor() if the largest integer
-not greater than its argument. Round() is the nearest integer to its
-argument.
+argument, e.g. sqrt(v_ke). Note that ln() is the natural log; log()
+is the base 10 log. The ceil(), floor(), and round() operations are
+those in the C math library. Ceil() is the smallest integer not less
+than its argument. Floor() if the largest integer not greater than
+its argument. Round() is the nearest integer to its argument.
Group functions take one or two arguments in a specific format. The
first argument is the group-ID. The {dim} argument, if it exists, is
diff -Naur lammps-14May08/src/variable.cpp lammps-15May08/src/variable.cpp
--- lammps-14May08/src/variable.cpp 2008-04-01 08:47:15.000000000 -0600
+++ lammps-15May08/src/variable.cpp 2008-05-15 14:29:14.000000000 -0600
@@ -40,7 +40,8 @@
enum{INDEX,LOOP,EQUAL,WORLD,UNIVERSE,ULOOP,ATOM};
enum{ARG,OP};
enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,UNARY,
- SQRT,EXP,LN,CEIL,FLOOR,ROUND,VALUE,ATOMARRAY,TYPEARRAY};
+ SQRT,EXP,LN,LOG,SIN,COS,TAN,ASIN,ACOS,ATAN,
+ CEIL,FLOOR,ROUND,VALUE,ATOMARRAY,TYPEARRAY};
#define INVOKED_SCALAR 1 // same as in computes
#define INVOKED_VECTOR 2
@@ -500,7 +501,9 @@
string is a equal-style or atom-style formula containing one or more items:
number = 0.0, -5.45, 2.8e-4, ...
thermo keyword = ke, vol, atoms, ...
- math operation = (),-x,x+y,x-y,x*y,x/y,x^y,sqrt(x),exp(x),ln(x)
+ math operation = (),-x,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),acos(x),atan(x)
group function = count(group), mass(group), xcm(group,x), ...
atom value = x[123], y[3], vx[34], ...
atom vector = x[], y[], vx[], ...
@@ -1076,6 +1079,10 @@
}
}
+/* ----------------------------------------------------------------------
+ process an evaulation tree
+ customize by adding a math function:
+ sqrt(),exp(),ln(),log(),sin(),cos(),tan(),asin(),acos(),atan()
/* ---------------------------------------------------------------------- */
double Variable::eval_tree(Tree *tree, int i)
@@ -1115,6 +1122,34 @@
if (arg <= 0.0) error->all("Log of zero/negative in variable formula");
return log(arg);
}
+ if (tree->type == LOG) {
+ double arg = eval_tree(tree->left,i);
+ if (arg <= 0.0) error->all("Log of zero/negative in variable formula");
+ return log10(arg);
+ }
+
+ if (tree->type == SIN)
+ return sin(eval_tree(tree->left,i));
+ if (tree->type == COS)
+ return cos(eval_tree(tree->left,i));
+ if (tree->type == TAN)
+ return tan(eval_tree(tree->left,i));
+
+ if (tree->type == ASIN) {
+ double arg = eval_tree(tree->left,i);
+ if (arg < -1.0 || arg > 1.0)
+ error->all("Arcsin of invalid value in variable formula");
+ return asin(arg);
+ }
+ if (tree->type == ACOS) {
+ double arg = eval_tree(tree->left,i);
+ if (arg < -1.0 || arg > 1.0)
+ error->all("Arccos of invalid value in variable formula");
+ return acos(arg);
+ }
+ if (tree->type == ATAN)
+ return atan(eval_tree(tree->left,i));
+
if (tree->type == CEIL)
return ceil(eval_tree(tree->left,i));
if (tree->type == FLOOR)
@@ -1204,7 +1239,8 @@
word = math function
contents = str bewteen parentheses
return 0 if not a match, 1 if successfully processed
- customize by adding a math function: sqrt(),exp(),log()
+ customize by adding a math function in 2 places:
+ sqrt(),exp(),ln(),log(),sin(),cos(),tan(),asin(),acos(),atan()
------------------------------------------------------------------------- */
int Variable::math_function(char *word, char *contents, Tree **tree,
@@ -1213,7 +1249,11 @@
{
// word not a match to any math function
- if (strcmp(word,"sqrt") && strcmp(word,"exp") && strcmp(word,"ln") &&
+ if (strcmp(word,"sqrt") && strcmp(word,"exp") &&
+ strcmp(word,"ln") && strcmp(word,"log") &&
+ strcmp(word,"sin") && strcmp(word,"cos") &&
+ strcmp(word,"tan") && strcmp(word,"asin") &&
+ strcmp(word,"acos") && strcmp(word,"atan") &&
strcmp(word,"ceil") && strcmp(word,"floor") && strcmp(word,"round"))
return 0;
@@ -1239,13 +1279,46 @@
} else if (strcmp(word,"exp") == 0) {
if (tree) newtree->type = EXP;
else argstack[nargstack++] = exp(value);
-
} else if (strcmp(word,"ln") == 0) {
if (tree) newtree->type = LN;
else {
if (value <= 0.0) error->all("Log of zero/negative in variable formula");
argstack[nargstack++] = log(value);
}
+ } else if (strcmp(word,"log") == 0) {
+ if (tree) newtree->type = LOG;
+ else {
+ if (value <= 0.0) error->all("Log of zero/negative in variable formula");
+ argstack[nargstack++] = log10(value);
+ }
+
+ } else if (strcmp(word,"sin") == 0) {
+ if (tree) newtree->type = SIN;
+ else argstack[nargstack++] = sin(value);
+ } else if (strcmp(word,"cos") == 0) {
+ if (tree) newtree->type = COS;
+ else argstack[nargstack++] = cos(value);
+ } else if (strcmp(word,"tan") == 0) {
+ if (tree) newtree->type = TAN;
+ else argstack[nargstack++] = tan(value);
+
+ } else if (strcmp(word,"asin") == 0) {
+ if (tree) newtree->type = ASIN;
+ else {
+ if (value < -1.0 || value > 1.0)
+ error->all("Arcsin of invalid value in variable formula");
+ argstack[nargstack++] = asin(value);
+ }
+ } else if (strcmp(word,"acos") == 0) {
+ if (tree) newtree->type = ACOS;
+ else {
+ if (value < -1.0 || value > 1.0)
+ error->all("Arccos of invalid value in variable formula");
+ argstack[nargstack++] = acos(value);
+ }
+ } else if (strcmp(word,"atan") == 0) {
+ if (tree) newtree->type = ATAN;
+ else argstack[nargstack++] = atan(value);
} else if (strcmp(word,"ceil") == 0) {
if (tree) newtree->type = CEIL;