c_ID[I][J] | I,J element of global array, or atom I's Jth value in per-atom array
@@ -810,7 +822,7 @@ compute references listed in the above table, where "c_" is replaced
by "f_". Again, there is no ambiguity as to what a reference means,
since fixes only produce global or per-atom quantities, never both.
-
+
f_ID | global scalar, or per-atom vector |
f_ID[I] | Ith element of global vector, or atom I's value in per-atom vector, or Ith column from per-atom array |
f_ID[I][J] | I,J element of global array, or atom I's Jth value in per-atom array
@@ -856,7 +868,7 @@ other atom-style or atomfile-style variables.
There is no ambiguity as to what a reference means, since variables
produce only a global scalar or a per-atom vector, never both.
-
+
v_name | scalar, or per-atom vector |
v_name[I] | atom I's value in per-atom vector
|
diff --git a/doc/variable.txt b/doc/variable.txt
index 6909908003..c546e009ca 100644
--- a/doc/variable.txt
+++ b/doc/variable.txt
@@ -49,7 +49,9 @@ style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {st
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)
- ramp(x,y), stagger(x,y), logfreq(x,y,z), stride(x,y,z), stride2(x,y,z,a,b,c), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z)
+ ramp(x,y), stagger(x,y), logfreq(x,y,z), logfreq2(x,y,z),
+ stride(x,y,z), stride2(x,y,z,a,b,c),
+ vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z)
group functions = count(group), mass(group), charge(group),
xcm(group,dim), vcm(group,dim), fcm(group,dim),
bound(group,dir), gyration(group), ke(group),
@@ -371,7 +373,7 @@ Constant: PI
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
-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), ramp(x,y), stagger(x,y), logfreq(x,y,z), stride(x,y,z), stride2(x,y,z,a,b,c), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z)
+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), ramp(x,y), stagger(x,y), logfreq(x,y,z), logfreq2(x,y,z), stride(x,y,z), stride2(x,y,z,a,b,c), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z)
Group functions: count(ID), mass(ID), charge(ID), xcm(ID,dim), \
vcm(ID,dim), fcm(ID,dim), bound(ID,dir), \
gyration(ID), ke(ID), angmom(ID,dim), torque(ID,dim), \
@@ -531,8 +533,9 @@ command, it will generate the sequence of output timesteps:
The logfreq(x,y,z) function uses the current timestep to generate a
new timestep. X,y,z > 0 and y < z are required. The generated
-timesteps increase in a logarithmic fashion, as the sequence
-x,2x,3x,...y*x,z*x,2*z*x,3*z*x,...y*z*x,z*z*x,2*z*x*x,etc. For any
+timesteps are gridpoints on a base-z logarithmic scale
+i.e. they follow the sequence
+x,2x,3x,...y*x,x*z,2x*z,3x*z,...y*x*z,x*z^2,2x*z^2,etc. For any
current timestep, the next timestep in the sequence is returned. Thus
if logfreq(100,4,10) is used in a variable by the "dump_modify
every"_dump_modify.html command, it will generate the sequence of
@@ -540,6 +543,15 @@ output timesteps:
100,200,300,400,1000,2000,3000,4000,10000,20000,etc :pre
+The logfreq2(x,y,z) function is similar to logfreq, except
+the y timesteps generated on the range \[x,x*z) are always
+evenly spaced, and y < z is not required.
+Thus, if logfreq2(100,18,10) is used in a variable by the
+"dump_modify every"_dump_modify.html command, it will generate
+the sequence of output timesteps:
+
+100,150,200,...950,1000,1500,2000,...9500,10000,15000,etc :pre
+
The stride(x,y,z) function uses the current timestep to generate a new
timestep. X,y >= 0 and z > 0 and x <= y are required. The generated
timesteps increase in increments of z, from x to y, i.e. it generates
diff --git a/src/variable.cpp b/src/variable.cpp
index c86135a11b..64ace21ed1 100644
--- a/src/variable.cpp
+++ b/src/variable.cpp
@@ -60,8 +60,8 @@ enum{ARG,OP};
enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY,
NOT,EQ,NE,LT,LE,GT,GE,AND,OR,
SQRT,EXP,LN,LOG,ABS,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2,
- RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,STRIDE,STRIDE2,
- VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,GRMASK,
+ RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,LOGFREQ2,
+ STRIDE,STRIDE2,VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,GRMASK,
VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,BIGINTARRAY};
// customize by adding a special function
@@ -1758,7 +1758,7 @@ double Variable::evaluate(char *str, Tree **tree)
/* ----------------------------------------------------------------------
one-time collapse of an atom-style variable parse tree
- tree was created by one-time parsing of formula string via evaulate()
+ tree was created by one-time parsing of formula string via evaluate()
only keep tree nodes that depend on
ATOMARRAY, TYPEARRAY, INTARRAY, BIGINTARRAY
remainder is converted to single VALUE
@@ -1766,8 +1766,8 @@ double Variable::evaluate(char *str, Tree **tree)
customize by adding a function:
sqrt(),exp(),ln(),log(),abs(),sin(),cos(),tan(),asin(),acos(),atan(),
atan2(y,x),random(x,y,z),normal(x,y,z),ceil(),floor(),round(),
- ramp(x,y),stagger(x,y),logfreq(x,y,z),stride(x,y,z),
- vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z),
+ ramp(x,y),stagger(x,y),logfreq(x,y,z),logfreq2(x,y,z),
+ stride(x,y,z),vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z),
gmask(x),rmask(x),grmask(x,y)
---------------------------------------------------------------------- */
@@ -2139,6 +2139,30 @@ double Variable::collapse_tree(Tree *tree)
return tree->value;
}
+ if (tree->type == LOGFREQ2) {
+ int ivalue1 = static_cast (collapse_tree(tree->first));
+ int ivalue2 = static_cast (collapse_tree(tree->second));
+ int ivalue3 = static_cast (collapse_tree(tree->extra[0]));
+ if (tree->first->type != VALUE || tree->second->type != VALUE ||
+ tree->extra[0]->type != VALUE) return 0.0;
+ tree->type = VALUE;
+ if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 )
+ error->all(FLERR,"Invalid math function in variable formula");
+ if (update->ntimestep < ivalue1) tree->value = ivalue1;
+ else {
+ tree->value = ivalue1;
+ double delta = ivalue1*(ivalue3-1.0)/ivalue2;
+ int count = 0;
+ while (update->ntimestep >= tree->value) {
+ tree->value += delta;
+ count++;
+ if (count % ivalue2 == 0) delta *= ivalue3;
+ }
+ }
+ tree->value = ceil(tree->value);
+ return tree->value;
+ }
+
if (tree->type == STRIDE) {
int ivalue1 = static_cast (collapse_tree(tree->first));
int ivalue2 = static_cast (collapse_tree(tree->second));
@@ -2252,9 +2276,9 @@ double Variable::collapse_tree(Tree *tree)
customize by adding a function:
sqrt(),exp(),ln(),log(),sin(),cos(),tan(),asin(),acos(),atan(),
atan2(y,x),random(x,y,z),normal(x,y,z),ceil(),floor(),round(),
- ramp(x,y),stagger(x,y),logfreq(x,y,z),stride(x,y,z),
- vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z),
- gmask(x),rmask(x),grmask(x,y)
+ ramp(x,y),stagger(x,y),logfreq(x,y,z),logfreq2(x,y,z),
+ stride(x,y,z),stride2(x,y,z),vdisplace(x,y),swiggle(x,y,z),
+ cwiggle(x,y,z),gmask(x),rmask(x),grmask(x,y)
---------------------------------------------------------------------- */
double Variable::eval_tree(Tree *tree, int i)
@@ -2446,6 +2470,27 @@ double Variable::eval_tree(Tree *tree, int i)
return arg;
}
+ if (tree->type == LOGFREQ2) {
+ int ivalue1 = static_cast (eval_tree(tree->first,i));
+ int ivalue2 = static_cast (eval_tree(tree->second,i));
+ int ivalue3 = static_cast (eval_tree(tree->extra[0],i));
+ if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 )
+ error->all(FLERR,"Invalid math function in variable formula");
+ if (update->ntimestep < ivalue1) arg = ivalue1;
+ else {
+ arg = ivalue1;
+ double delta = ivalue1*(ivalue3-1.0)/ivalue2;
+ int count = 0;
+ while (update->ntimestep >= arg) {
+ arg += delta;
+ count++;
+ if (count % ivalue2 == 0) delta *= ivalue3;
+ }
+ }
+ arg = ceil(arg);
+ return arg;
+ }
+
if (tree->type == STRIDE) {
int ivalue1 = static_cast (eval_tree(tree->first,i));
int ivalue2 = static_cast (eval_tree(tree->second,i));
@@ -2671,8 +2716,9 @@ tagint Variable::int_between_brackets(char *&ptr, int varallow)
customize by adding a math function:
sqrt(),exp(),ln(),log(),abs(),sin(),cos(),tan(),asin(),acos(),atan(),
atan2(y,x),random(x,y,z),normal(x,y,z),ceil(),floor(),round(),
- ramp(x,y),stagger(x,y),logfreq(x,y,z),stride(x,y,z),stride2(x,y,z,a,b,c),
- vdisplace(x,y),swiggle(x,y,z),cwiggle(x,y,z)
+ ramp(x,y),stagger(x,y),logfreq(x,y,z),logfreq2(x,y,z),
+ stride(x,y,z),stride2(x,y,z,a,b,c),vdisplace(x,y),swiggle(x,y,z),
+ cwiggle(x,y,z)
------------------------------------------------------------------------- */
int Variable::math_function(char *word, char *contents, Tree **tree,
@@ -2691,9 +2737,10 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
strcmp(word,"normal") && strcmp(word,"ceil") &&
strcmp(word,"floor") && strcmp(word,"round") &&
strcmp(word,"ramp") && strcmp(word,"stagger") &&
- strcmp(word,"logfreq") && strcmp(word,"stride") &&
- strcmp(word,"stride2") && strcmp(word,"vdisplace") &&
- strcmp(word,"swiggle") && strcmp(word,"cwiggle"))
+ strcmp(word,"logfreq") && strcmp(word,"logfreq2") &&
+ strcmp(word,"stride") && strcmp(word,"stride2") &&
+ strcmp(word,"vdisplace") && strcmp(word,"swiggle") &&
+ strcmp(word,"cwiggle"))
return 0;
// parse contents for comma-separated args
@@ -2924,6 +2971,31 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
argstack[nargstack++] = value;
}
+ } else if (strcmp(word,"logfreq2") == 0) {
+ if (narg != 3)
+ error->all(FLERR,"Invalid math function in variable formula");
+ if (tree) newtree->type = LOGFREQ2;
+ else {
+ int ivalue1 = static_cast (value1);
+ int ivalue2 = static_cast (value2);
+ int ivalue3 = static_cast (values[0]);
+ if (ivalue1 <= 0 || ivalue2 <= 0 || ivalue3 <= 0 )
+ error->all(FLERR,"Invalid math function in variable formula");
+ double value;
+ if (update->ntimestep < ivalue1) value = ivalue1;
+ else {
+ value = ivalue1;
+ double delta = ivalue1*(ivalue3-1.0)/ivalue2;
+ int count = 0;
+ while (update->ntimestep >= value) {
+ value += delta;
+ count++;
+ if (count % ivalue2 == 0) delta *= ivalue3;
+ }
+ }
+ argstack[nargstack++] = ceil(value);
+ }
+
} else if (strcmp(word,"stride") == 0) {
if (narg != 3)
error->all(FLERR,"Invalid math function in variable formula");
| |