add is_file() special variable function and unit tests for it

This commit is contained in:
Axel Kohlmeyer
2021-04-02 12:07:43 -04:00
parent c3eb52f46a
commit 2dfafe4adb
3 changed files with 39 additions and 7 deletions

View File

@ -65,8 +65,8 @@ Syntax
bound(group,dir,region), gyration(group,region), ke(group,reigon), bound(group,dir,region), gyration(group,region), ke(group,reigon),
angmom(group,dim,region), torque(group,dim,region), angmom(group,dim,region), torque(group,dim,region),
inertia(group,dimdim,region), omega(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) 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_active(category,feature,exact), is_defined(category,id,exact) feature functions = is_available(category,feature), is_active(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 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 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] compute references = c_ID, c_ID[i], c_ID[i][j], C_ID, C_ID[i]
@ -821,6 +821,10 @@ Special Functions
Special functions take specific kinds of arguments, meaning their Special functions take specific kinds of arguments, meaning their
arguments cannot be formulas themselves. 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'
is taken as a literal string and must not have any blanks in it.
The sum(x), min(x), max(x), ave(x), trap(x), and slope(x) functions 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 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 "f_ID" or "f_ID[N]" or "v_name". The first two are computes and the

View File

@ -65,7 +65,7 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY,
SQRT,EXP,LN,LOG,ABS,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2, SQRT,EXP,LN,LOG,ABS,SIN,COS,TAN,ASIN,ACOS,ATAN,ATAN2,
RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,LOGFREQ2, RANDOM,NORMAL,CEIL,FLOOR,ROUND,RAMP,STAGGER,LOGFREQ,LOGFREQ2,
LOGFREQ3,STRIDE,STRIDE2,VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK, LOGFREQ3,STRIDE,STRIDE2,VDISPLACE,SWIGGLE,CWIGGLE,GMASK,RMASK,
GRMASK,IS_ACTIVE,IS_DEFINED,IS_AVAILABLE, GRMASK,IS_ACTIVE,IS_DEFINED,IS_AVAILABLE,IS_FILE,
VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,BIGINTARRAY,VECTORARRAY}; VALUE,ATOMARRAY,TYPEARRAY,INTARRAY,BIGINTARRAY,VECTORARRAY};
// customize by adding a special function // customize by adding a special function
@ -4079,7 +4079,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
strcmp(word,"gmask") && strcmp(word,"rmask") && strcmp(word,"gmask") && strcmp(word,"rmask") &&
strcmp(word,"grmask") && strcmp(word,"next") && strcmp(word,"grmask") && strcmp(word,"next") &&
strcmp(word,"is_active") && strcmp(word,"is_defined") && strcmp(word,"is_active") && strcmp(word,"is_defined") &&
strcmp(word,"is_available")) strcmp(word,"is_available") && strcmp(word,"is_file"))
return 0; return 0;
// parse contents for comma-separated args // parse contents for comma-separated args
@ -4488,6 +4488,26 @@ int Variable::special_function(char *word, char *contents, Tree **tree,
// save value in tree or on argstack // save value in tree or on argstack
if (tree) {
Tree *newtree = new Tree();
newtree->type = VALUE;
newtree->value = value;
newtree->first = newtree->second = nullptr;
newtree->nextra = 0;
treestack[ntreestack++] = newtree;
} else argstack[nargstack++] = value;
} else if (strcmp(word,"is_file") == 0) {
if (narg != 1)
print_var_error(FLERR,"Invalid is_file() function in "
"variable formula",ivar);
FILE *fp = fopen(args[0],"r");
value = (fp == nullptr) ? 0.0 : 1.0;
if (fp) fclose(fp);
// save value in tree or on argstack
if (tree) { if (tree) {
Tree *newtree = new Tree(); Tree *newtree = new Tree();
newtree->type = VALUE; newtree->type = VALUE;

View File

@ -142,12 +142,13 @@ TEST_F(VariableTest, CreateDelete)
command("variable ten2 uloop 4"); command("variable ten2 uloop 4");
command("variable ten3 uloop 4 pad"); command("variable ten3 uloop 4 pad");
command("variable dummy index 0"); command("variable dummy index 0");
command("variable file equal is_file(MYFILE)");
END_HIDE_OUTPUT(); END_HIDE_OUTPUT();
ASSERT_EQ(variable->nvar, 17); ASSERT_EQ(variable->nvar, 18);
BEGIN_HIDE_OUTPUT(); BEGIN_HIDE_OUTPUT();
command("variable dummy delete"); command("variable dummy delete");
END_HIDE_OUTPUT(); END_HIDE_OUTPUT();
ASSERT_EQ(variable->nvar, 16); ASSERT_EQ(variable->nvar, 17);
ASSERT_THAT(variable->retrieve("three"), StrEq("three")); ASSERT_THAT(variable->retrieve("three"), StrEq("three"));
variable->set_string("three", "four"); variable->set_string("three", "four");
ASSERT_THAT(variable->retrieve("three"), StrEq("four")); ASSERT_THAT(variable->retrieve("three"), StrEq("four"));
@ -158,6 +159,13 @@ TEST_F(VariableTest, CreateDelete)
ASSERT_THAT(variable->retrieve("eight"), StrEq("")); ASSERT_THAT(variable->retrieve("eight"), StrEq(""));
variable->internal_set(variable->find("ten"), 2.5); variable->internal_set(variable->find("ten"), 2.5);
ASSERT_THAT(variable->retrieve("ten"), StrEq("2.5")); ASSERT_THAT(variable->retrieve("ten"), StrEq("2.5"));
ASSERT_THAT(variable->retrieve("file"), StrEq("0"));
FILE *fp = fopen("MYFILE","w");
fputs(" ",fp);
fclose(fp);
ASSERT_THAT(variable->retrieve("file"), StrEq("1"));
unlink("MYFILE");
ASSERT_THAT(variable->retrieve("file"), StrEq("0"));
ASSERT_EQ(variable->equalstyle(variable->find("one")), 0); ASSERT_EQ(variable->equalstyle(variable->find("one")), 0);
ASSERT_EQ(variable->equalstyle(variable->find("two")), 1); ASSERT_EQ(variable->equalstyle(variable->find("two")), 1);
@ -200,7 +208,7 @@ TEST_F(VariableTest, CreateDelete)
TEST_F(VariableTest, AtomicSystem) TEST_F(VariableTest, AtomicSystem)
{ {
command("atom_modify map array"); HIDE_OUTPUT([&] { command("atom_modify map array"); });
atomic_system(); atomic_system();
file_vars(); file_vars();