From f6b81b0881d518f579f8f7db8603bef3e753a0a6 Mon Sep 17 00:00:00 2001 From: athomps Date: Mon, 22 Dec 2014 22:42:09 +0000 Subject: [PATCH] Added logfreq2 git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@12852 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- doc/variable.html | 28 ++++++++++---- doc/variable.txt | 20 ++++++++-- src/variable.cpp | 98 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 121 insertions(+), 25 deletions(-) diff --git a/doc/variable.html b/doc/variable.html index edd0202610..d8614d7fc3 100644 --- a/doc/variable.html +++ b/doc/variable.html @@ -54,7 +54,9 @@ 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), @@ -372,13 +374,13 @@ operators, math functions, group functions, region functions, atom values, atom vectors, compute references, fix references, and references to other variables.

-
+
- + @@ -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 command, it will generate the sequence of @@ -540,6 +543,15 @@ output timesteps:

100,200,300,400,1000,2000,3000,4000,10000,20000,etc 
 
+

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 command, it will generate +the sequence of output timesteps: +

+
100,150,200,...950,1000,1500,2000,...9500,10000,15000,etc 
+

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 @@ -773,7 +785,7 @@ kind of values they produce. There is no ambiguity as to what a reference means, since computes only produce global or per-atom quantities, never both.

-
Number 0.2, 100, 1.0e20, -15.4, etc
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), inertia(ID,dimdim), omega(ID,dim)
Region functions count(ID,IDR), mass(ID,IDR), charge(ID,IDR), xcm(ID,dim,IDR), vcm(ID,dim,IDR), fcm(ID,dim,IDR), bound(ID,dir,IDR), gyration(ID,IDR), ke(ID,IDR), angmom(ID,dim,IDR), torque(ID,dim,IDR), inertia(ID,dimdim,IDR), omega(ID,dim,IDR)
Special functions sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x)
+
c_ID global scalar, or per-atom vector
c_ID[I] Ith element of global vector, or atom I's value in per-atom vector, or Ith column from per-atom array
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");