forked from lijiext/lammps
A function logfreq3(), for logarithmical spacing
Unlike logfreq(), this also allows for fractional ratios Resolves #1471
This commit is contained in:
parent
cfad0634ac
commit
c2a200fe85
|
@ -52,7 +52,7 @@ style = {delete} or {index} or {loop} or {world} or {universe} or {uloop} or {st
|
|||
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),
|
||||
logfreq3(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),
|
||||
|
@ -459,8 +459,8 @@ 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)
|
||||
logfreq3(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), \
|
||||
|
@ -670,6 +670,16 @@ sequence of output timesteps:
|
|||
|
||||
100,150,200,...950,1000,1500,2000,...9500,10000,15000,etc :pre
|
||||
|
||||
The logfreq3(x,y,z) function generates y points between x and z (inclusive),
|
||||
that are separated by a multiplicative ratio: (z/x)^(1/(y-1)). Constraints
|
||||
are: x,z > 0, y > 1, z-x >= y-1. For eg., if logfreq3(10,25,1000) is used in
|
||||
a variable by the "fix print"_fix_print.html command, then the interval
|
||||
between 10 and 1000 is divided into 24 parts with a multiplicative
|
||||
separation of ~1.21, and it will generate the following sequence of output
|
||||
timesteps:
|
||||
|
||||
10, 13, 15, 18, 22, 27, 32,...384, 465, 563, 682, 826, 1000 :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
|
||||
|
|
|
@ -63,8 +63,8 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY,
|
|||
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,
|
||||
IS_ACTIVE,IS_DEFINED,IS_AVAILABLE,
|
||||
LOGFREQ3,STRIDE,STRIDE2,VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,
|
||||
GRMASK,IS_ACTIVE,IS_DEFINED,IS_AVAILABLE,
|
||||
VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,BIGINTARRAY,VECTORARRAY};
|
||||
|
||||
// customize by adding a special function
|
||||
|
@ -2294,8 +2294,8 @@ double Variable::evaluate(char *str, Tree **tree, int ivar)
|
|||
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),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)
|
||||
logfreq3(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)
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
double Variable::collapse_tree(Tree *tree)
|
||||
|
@ -2702,6 +2702,35 @@ double Variable::collapse_tree(Tree *tree)
|
|||
return tree->value;
|
||||
}
|
||||
|
||||
if (tree->type == LOGFREQ3) {
|
||||
int ivalue1 = static_cast<int> (collapse_tree(tree->first));
|
||||
int ivalue2 = static_cast<int> (collapse_tree(tree->second));
|
||||
int ivalue3 = static_cast<int> (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 <= 1 || ivalue3 <= 0 ||
|
||||
ivalue3-ivalue1+1 < ivalue2 )
|
||||
error->all(FLERR,"Invalid math function in variable formula");
|
||||
if (update->ntimestep < ivalue1) tree->value = ivalue1;
|
||||
//else if (update->ntimestep <= ivalue3){
|
||||
else {
|
||||
tree->value = ivalue1;
|
||||
double logsp = ivalue1;
|
||||
double factor = pow(((double)ivalue3)/ivalue1, 1.0/(ivalue2-1));
|
||||
int linsp = ivalue1;
|
||||
while (update->ntimestep >= (tree->value)) {
|
||||
logsp *= factor;
|
||||
linsp++;
|
||||
if (linsp > logsp) tree->value = linsp;
|
||||
else tree->value = ceil(logsp)-(((int)ceil(logsp)-1)/ivalue3);
|
||||
}
|
||||
}
|
||||
if (update->ntimestep > ivalue3)
|
||||
error->all(FLERR,"Calls to variable exceeded limit");
|
||||
return tree->value;
|
||||
}
|
||||
|
||||
if (tree->type == STRIDE) {
|
||||
int ivalue1 = static_cast<int> (collapse_tree(tree->first));
|
||||
int ivalue2 = static_cast<int> (collapse_tree(tree->second));
|
||||
|
@ -2817,8 +2846,8 @@ double Variable::collapse_tree(Tree *tree)
|
|||
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),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)
|
||||
logfreq3(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)
|
||||
|
@ -3297,8 +3326,8 @@ tagint Variable::int_between_brackets(char *&ptr, int varallow)
|
|||
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),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)
|
||||
logfreq3(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,
|
||||
|
@ -3318,9 +3347,9 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
|
|||
strcmp(word,"floor") && strcmp(word,"round") &&
|
||||
strcmp(word,"ramp") && strcmp(word,"stagger") &&
|
||||
strcmp(word,"logfreq") && strcmp(word,"logfreq2") &&
|
||||
strcmp(word,"stride") && strcmp(word,"stride2") &&
|
||||
strcmp(word,"vdisplace") && strcmp(word,"swiggle") &&
|
||||
strcmp(word,"cwiggle"))
|
||||
strcmp(word,"logfreq3") && strcmp(word,"stride") &&
|
||||
strcmp(word,"stride2") && strcmp(word,"vdisplace") &&
|
||||
strcmp(word,"swiggle") && strcmp(word,"cwiggle"))
|
||||
return 0;
|
||||
|
||||
// parse contents for comma-separated args
|
||||
|
@ -3580,6 +3609,37 @@ int Variable::math_function(char *word, char *contents, Tree **tree,
|
|||
argstack[nargstack++] = ceil(value);
|
||||
}
|
||||
|
||||
} else if (strcmp(word,"logfreq3") == 0) {
|
||||
if (narg != 3)
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
if (tree) newtree->type = LOGFREQ3;
|
||||
else {
|
||||
int ivalue1 = static_cast<int> (value1);
|
||||
int ivalue2 = static_cast<int> (value2);
|
||||
int ivalue3 = static_cast<int> (values[0]);
|
||||
if (ivalue1 <= 0 || ivalue2 <= 1 || ivalue3 <= 0 ||
|
||||
ivalue3-ivalue1+1 < ivalue2 )
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
double value;
|
||||
if (update->ntimestep < ivalue1) value = ivalue1;
|
||||
//else if (update->ntimestep <= ivalue3){
|
||||
else {
|
||||
value = ivalue1;
|
||||
double logsp = ivalue1;
|
||||
double factor = pow(((double)ivalue3)/ivalue1, 1.0/(ivalue2-1));
|
||||
int linsp = ivalue1;
|
||||
while (update->ntimestep >= value) {
|
||||
logsp *= factor;
|
||||
linsp++;
|
||||
if (linsp > logsp) value = linsp;
|
||||
else value = ceil(logsp)-(((int)ceil(logsp)-1)/ivalue3);
|
||||
}
|
||||
}
|
||||
if (update->ntimestep > ivalue3)
|
||||
error->all(FLERR,"Calls to variable exceeded limit");
|
||||
argstack[nargstack++] = value;
|
||||
}
|
||||
|
||||
} else if (strcmp(word,"stride") == 0) {
|
||||
if (narg != 3)
|
||||
print_var_error(FLERR,"Invalid math function in variable formula",ivar);
|
||||
|
|
Loading…
Reference in New Issue