diff --git a/doc/src/variable.rst b/doc/src/variable.rst index 25861ae17b..d0ad568cf1 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -65,8 +65,8 @@ Syntax bound(group,dir,region), gyration(group,region), ke(group,reigon), angmom(group,dim,region), torque(group,dim,region), inertia(group,dimdim,region), omega(group,dim,region) - special functions = sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name) - feature functions = is_available(category,feature), is_active(category,feature), is_defined(category,id) + special functions = sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), extract_setting(name) + feature functions = is_active(category,feature), is_available(category,feature), is_defined(category,id) atom value = id[i], mass[i], type[i], mol[i], x[i], y[i], z[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i], q[i] atom vector = id, mass, type, mol, x, y, z, vx, vy, vz, fx, fy, fz, q compute references = c_ID, c_ID[i], c_ID[i][j], C_ID, C_ID[i] @@ -823,10 +823,15 @@ Special Functions Special functions take specific kinds of arguments, meaning their arguments cannot be formulas themselves. -The is_file(x) function is a test whether 'x' is a (readable) file -and returns 1 in this case, otherwise it returns 0. For that 'x' +The is_file(name) function is a test whether *name* is a (readable) file +and returns 1 in this case, otherwise it returns 0. For that *name* is taken as a literal string and must not have any blanks in it. +The extract_setting(name) function allows to access some basic settings +through calling the :cpp:func:`lammps_extract_setting` library function. +For available keywords *name* and their meaning, please see the +documentation of that function. + The sum(x), min(x), max(x), ave(x), trap(x), and slope(x) functions each take 1 argument which is of the form "c_ID" or "c_ID[N]" or "f_ID" or "f_ID[N]" or "v_name". The first two are computes and the @@ -911,30 +916,30 @@ Feature Functions ----------------- Feature functions allow to probe the running LAMMPS executable for -whether specific features are either active, defined, or available. -The functions take two arguments, a *category* and a corresponding -*argument*\ . The arguments are strings thus cannot be formulas -themselves (only $-style immediate variable expansion is possible). +whether specific features are either active, defined, or available. The +functions take two arguments, a *category* and a corresponding +*argument*\ . The arguments are strings and thus cannot be formulas +themselves; only $-style immediate variable expansion is possible. Return value is either 1.0 or 0.0 depending on whether the function evaluates to true or false, respectively. -The *is_active()* function allows to query for active settings which -are grouped by categories. Currently supported categories and -arguments are: +The *is_active(category,feature)* function allows to query for active +settings which are grouped by categories. Currently supported categories +and arguments are: -* *package* (argument = *gpu* or *intel* or *kokkos* or *omp*\ ) -* *newton* (argument = *pair* or *bond* or *any*\ ) -* *pair* (argument = *single* or *respa* or *manybody* or *tail* or *shift*\ ) -* *comm_style* (argument = *brick* or *tiled*\ ) -* *min_style* (argument = any of the compiled in minimizer styles) -* *run_style* (argument = any of the compiled in run styles) -* *atom_style* (argument = any of the compiled in atom styles) -* *pair_style* (argument = any of the compiled in pair styles) -* *bond_style* (argument = any of the compiled in bond styles) -* *angle_style* (argument = any of the compiled in angle styles) -* *dihedral_style* (argument = any of the compiled in dihedral styles) -* *improper_style* (argument = any of the compiled in improper styles) -* *kspace_style* (argument = any of the compiled in kspace styles) +* *package*\ : argument = *gpu* or *intel* or *kokkos* or *omp* +* *newton*\ : argument = *pair* or *bond* or *any* +* *pair*\ : argument = *single* or *respa* or *manybody* or *tail* or *shift* +* *comm_style*\ : argument = *brick* or *tiled* +* *min_style*\ : argument = any of the compiled in minimizer styles +* *run_style*\ : argument = any of the compiled in run styles +* *atom_style*\ : argument = any of the compiled in atom style) +* *pair_style*\ : argument = any of the compiled in pair styles +* *bond_style*\ : argument = any of the compiled in bond styles +* *angle_style*\ : argument = any of the compiled in angle styles +* *dihedral_style*\ : argument = any of the compiled in dihedral styles +* *improper_style*\ : argument = any of the compiled in improper styles +* *kspace_style*\ : argument = any of the compiled in kspace styles Most of the settings are self-explanatory, the *single* argument in the *pair* category allows to check whether a pair style supports a @@ -943,7 +948,9 @@ features or LAMMPS, *respa* allows to check whether the inner/middle/outer mode of r-RESPA is supported. In the various style categories, the checking is also done using suffix flags, if available and enabled. -Example 1: disable use of suffix for pppm when using GPU package (i.e. run it on the CPU concurrently to running the pair style on the GPU), but do use the suffix otherwise (e.g. with OPENMP). +Example 1: disable use of suffix for pppm when using GPU package +(i.e. run it on the CPU concurrently to running the pair style on the +GPU), but do use the suffix otherwise (e.g. with OPENMP). .. code-block:: LAMMPS @@ -951,17 +958,15 @@ Example 1: disable use of suffix for pppm when using GPU package (i.e. run it on if $(is_active(package,gpu)) then "suffix off" kspace_style pppm -Example 2: use r-RESPA with inner/outer cutoff, if supported by pair style, otherwise fall back to using pair and reducing the outer time step +Example 2: use r-RESPA with inner/outer cutoff, if supported by pair +style, otherwise fall back to using pair and reducing the outer time +step .. code-block:: LAMMPS timestep $(2.0*(1.0+2.0*is_active(pair,respa)) if $(is_active(pair,respa)) then "run_style respa 4 3 2 2 improper 1 inner 2 5.5 7.0 outer 3 kspace 4" else "run_style respa 3 3 2 improper 1 pair 2 kspace 3" -The *is_defined()* function allows to query categories like *compute*, -*dump*, *fix*, *group*, *region*, and *variable* whether an entry -with the provided name or id is defined. - The *is_available(category,name)* function allows to query whether a specific optional feature is available, i.e. compiled in. This currently works for the following categories: *command*, @@ -983,6 +988,10 @@ the compiled binary supports it. if "$(is_available(feature,ffmpeg)" then "dump 3 all movie 25 movie.mp4 type type zoom 1.6 adiam 1.0" +The *is_defined(categoy,id)* function allows to query categories like +*compute*, *dump*, *fix*, *group*, *region*, and *variable* whether an +entry with the provided name or id is defined. + ---------- Atom Values and Vectors diff --git a/src/variable.cpp b/src/variable.cpp index ab4a0c6b0e..dd18854ef5 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -24,6 +24,7 @@ #include "group.h" #include "info.h" #include "input.h" +#include "library.h" #include "lmppython.h" #include "math_const.h" #include "memory.h" @@ -63,7 +64,7 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY, SQRT,EXP,LN,LOG,ABS,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2, RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,LOGFREQ2, LOGFREQ3,STRIDE,STRIDE2,VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK, - GRMASK,IS_ACTIVE,IS_DEFINED,IS_AVAILABLE,IS_FILE, + GRMASK,IS_ACTIVE,IS_DEFINED,IS_AVAILABLE,IS_FILE,EXTRACT_SETTING, VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,BIGINTARRAY,VECTORARRAY}; // customize by adding a special function @@ -3899,12 +3900,11 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t // word not a match to any special function - if (strcmp(word,"sum") && strcmp(word,"min") && strcmp(word,"max") && - strcmp(word,"ave") && strcmp(word,"trap") && strcmp(word,"slope") && - strcmp(word,"gmask") && strcmp(word,"rmask") && - strcmp(word,"grmask") && strcmp(word,"next") && - strcmp(word,"is_active") && strcmp(word,"is_defined") && - strcmp(word,"is_available") && strcmp(word,"is_file")) + if (strcmp(word,"sum") && strcmp(word,"min") && strcmp(word,"max") && strcmp(word,"ave") && + strcmp(word,"trap") && strcmp(word,"slope") && strcmp(word,"gmask") && strcmp(word,"rmask") && + strcmp(word,"grmask") && strcmp(word,"next") && strcmp(word,"is_active") && + strcmp(word,"is_defined") && strcmp(word,"is_available") && strcmp(word,"is_file") && + strcmp(word,"extract_setting")) return 0; // parse contents for comma-separated args @@ -4295,6 +4295,20 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t // save value in tree or on argstack + if (tree) { + Tree *newtree = new Tree(); + newtree->type = VALUE; + newtree->value = value; + treestack[ntreestack++] = newtree; + } else argstack[nargstack++] = value; + + } else if (strcmp(word,"extract_setting") == 0) { + if (narg != 1) print_var_error(FLERR,"Invalid extract_setting() function in variable formula",ivar); + + value = lammps_extract_setting(lmp, args[0]); + + // save value in tree or on argstack + if (tree) { Tree *newtree = new Tree(); newtree->type = VALUE;