Merge pull request #3790 from jrgissing/is_typelabel-function
add is_typelabel() variable function
This commit is contained in:
@ -67,7 +67,7 @@ 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), is_os(name), extract_setting(name), label2type(kind,label)
|
||||
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), is_os(name), extract_setting(name), label2type(kind,label), is_typelabel(kind,label)
|
||||
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 vector = id, mass, type, mol, radius, q, x, y, z, vx, vy, vz, fx, fy, fz
|
||||
@ -532,7 +532,7 @@ variables.
|
||||
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 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), is_file(name), is_os(name), extract_setting(name), label2type(kind,label) |
|
||||
| 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), is_os(name), extract_setting(name), label2type(kind,label), is_typelabel(kind,label) |
|
||||
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Feature functions | is_available(category,feature), is_active(category,feature), is_defined(category,id) |
|
||||
+--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
@ -996,10 +996,17 @@ via the link in this paragraph.
|
||||
|
||||
The label2type(kind,label) function converts type labels into numeric
|
||||
types, using label maps created by the :doc:`labelmap <labelmap>` or
|
||||
:doc:`read_data <read_data>` commands. The first argument is the
|
||||
label map kind (atom, bond, angle, dihedral, or improper) and the
|
||||
second argument is the label. The function returns the corresponding
|
||||
numeric type.
|
||||
:doc:`read_data <read_data>` commands. The first argument is the label
|
||||
map kind (atom, bond, angle, dihedral, or improper) and the second
|
||||
argument is the label. The function returns the corresponding numeric
|
||||
type or triggers an error if the queried label does not exist.
|
||||
|
||||
.. versionadded:: TBD
|
||||
|
||||
The is_typelabel(kind,label) function has the same arguments as
|
||||
label2type(), but returns 1 if the type label has been assigned,
|
||||
otherwise it returns 0. This function can be used to check if a
|
||||
particular type label already exists in the simulation.
|
||||
|
||||
----------
|
||||
|
||||
|
||||
@ -4040,8 +4040,8 @@ Region *Variable::region_function(char *id, int ivar)
|
||||
return 0 if not a match, 1 if successfully processed
|
||||
customize by adding a special function:
|
||||
sum(x),min(x),max(x),ave(x),trap(x),slope(x),
|
||||
gmask(x),rmask(x),grmask(x,y),next(x),
|
||||
is_file(x),is_ox(x),extract_setting(x),label2type(x,y)
|
||||
gmask(x),rmask(x),grmask(x,y),next(x),is_file(x),is_ox(x),
|
||||
extract_setting(x),label2type(x,y),is_typelabel(x,y)
|
||||
------------------------------------------------------------------------- */
|
||||
|
||||
int Variable::special_function(char *word, char *contents, Tree **tree, Tree **treestack,
|
||||
@ -4056,20 +4056,28 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t
|
||||
strcmp(word,"ave") != 0 && strcmp(word,"trap") != 0 && strcmp(word,"slope") != 0 &&
|
||||
strcmp(word,"gmask") != 0 && strcmp(word,"rmask") != 0 && strcmp(word,"grmask") != 0 &&
|
||||
strcmp(word,"next") != 0 && strcmp(word,"is_file") != 0 && strcmp(word,"is_os") != 0 &&
|
||||
strcmp(word,"extract_setting") != 0 && strcmp(word,"label2type") != 0)
|
||||
strcmp(word,"extract_setting") != 0 && strcmp(word,"label2type") != 0 &&
|
||||
strcmp(word,"is_typelabel") != 0)
|
||||
return 0;
|
||||
|
||||
// process label2type() separately b/c its label arg can have commas in it
|
||||
|
||||
if (strcmp(word,"label2type") == 0) {
|
||||
if (strcmp(word,"label2type") == 0 || strcmp(word,"is_typelabel") == 0) {
|
||||
if (!atom->labelmapflag)
|
||||
print_var_error(FLERR,"Cannot use label2type() function without a labelmap",ivar);
|
||||
print_var_error(FLERR,fmt::format("Cannot use {}() function without a labelmap",word),ivar);
|
||||
|
||||
std::string contents_copy(contents);
|
||||
auto pos = contents_copy.find_first_of(',');
|
||||
if (pos == std::string::npos)
|
||||
print_var_error(FLERR, fmt::format("Invalid label2type({}) function in variable formula",
|
||||
contents_copy), ivar);
|
||||
if (pos == std::string::npos) {
|
||||
if (strcmp(word,"label2type") == 0) {
|
||||
print_var_error(FLERR, fmt::format("Invalid label2type({}) function in variable formula",
|
||||
contents_copy), ivar);
|
||||
} else {
|
||||
print_var_error(FLERR, fmt::format("Invalid is_typelabel({}) function in variable formula",
|
||||
contents_copy), ivar);
|
||||
}
|
||||
}
|
||||
|
||||
std::string typestr = contents_copy.substr(pos+1);
|
||||
std::string kind = contents_copy.substr(0, pos);
|
||||
|
||||
@ -4085,12 +4093,14 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t
|
||||
} else if (kind == "improper") {
|
||||
value = atom->lmap->find(typestr,Atom::IMPROPER);
|
||||
} else {
|
||||
print_var_error(FLERR, fmt::format("Invalid kind {} in label2type() in variable",kind),ivar);
|
||||
print_var_error(FLERR, fmt::format("Invalid kind {} in {}() in variable", kind, word),ivar);
|
||||
}
|
||||
|
||||
if (value == -1)
|
||||
print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type() in variable",
|
||||
kind, typestr), ivar);
|
||||
if (strcmp(word,"label2type") == 0) {
|
||||
if (value == -1)
|
||||
print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type() in variable",
|
||||
kind, typestr), ivar);
|
||||
} else value = (value == -1) ? 0.0 : 1.0;
|
||||
|
||||
// save value in tree or on argstack
|
||||
|
||||
|
||||
@ -590,7 +590,7 @@ TEST_F(VariableTest, NextCommand)
|
||||
command("next five four"););
|
||||
}
|
||||
|
||||
TEST_F(VariableTest, Label2TypeAtomic)
|
||||
TEST_F(VariableTest, LabelMapAtomic)
|
||||
{
|
||||
BEGIN_HIDE_OUTPUT();
|
||||
command("region box block 0 2 0 2 0 2");
|
||||
@ -608,14 +608,20 @@ TEST_F(VariableTest, Label2TypeAtomic)
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("label2type(atom,N1)"), 2.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("label2type(atom,O1)"), 3.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("label2type(atom,H1)"), 4.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,N1)"), 1.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,N2)"), 0.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,O)"), 0.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,H1)"), 1.0);
|
||||
|
||||
TEST_FAILURE(".*ERROR: Variable t1: Invalid atom type label C1 in label2type.. in variable.*",
|
||||
command("print \"${t1}\""););
|
||||
TEST_FAILURE(".*ERROR: Invalid bond type label H1 in label2type.. in variable.*",
|
||||
variable->compute_equal("label2type(bond,H1)"););
|
||||
TEST_FAILURE(".*ERROR: Invalid kind xxx in label2type.. in variable.*",
|
||||
variable->compute_equal("label2type(xxx,H1)"););
|
||||
TEST_FAILURE(".*ERROR: Invalid kind xxx in is_typelabel.. in variable.*",
|
||||
variable->compute_equal("is_typelabel(xxx,H1)"););
|
||||
}
|
||||
|
||||
TEST_F(VariableTest, Label2TypeMolecular)
|
||||
TEST_F(VariableTest, LabelMapMolecular)
|
||||
{
|
||||
if (!info->has_style("atom", "full")) GTEST_SKIP();
|
||||
|
||||
@ -637,6 +643,14 @@ TEST_F(VariableTest, Label2TypeMolecular)
|
||||
command("variable a2 equal \"\"\"label2type(angle,N2'-C1\"-N2')\"\"\"");
|
||||
command("variable d1 equal label2type(dihedral,C1-N2-C1-N2)");
|
||||
command("variable i1 equal label2type(improper,C1-N2-C1-N2)");
|
||||
|
||||
command("variable l1 equal is_typelabel(atom,C2)+is_typelabel(bond,C2-N1)"
|
||||
"+is_typelabel(bond,[X1][Y1])+is_typelabel(angle,C1-C2-N1)"
|
||||
"+is_typelabel(dihedral,N2-C1-C1-N2)+is_typelabel(improper,N2-C1-C1-N2)");
|
||||
command("variable l2 equal is_typelabel(atom,C1)+is_typelabel(bond,C1-N2)"
|
||||
"+is_typelabel(bond,[C1][C1])+is_typelabel(angle,C1-N2-C1)"
|
||||
"+is_typelabel(dihedral,C1-N2-C1-N2)+is_typelabel(improper,C1-N2-C1-N2)");
|
||||
|
||||
END_HIDE_OUTPUT();
|
||||
|
||||
ASSERT_THAT(variable->retrieve("t1"), StrEq("1"));
|
||||
@ -647,6 +661,30 @@ TEST_F(VariableTest, Label2TypeMolecular)
|
||||
ASSERT_THAT(variable->retrieve("a2"), StrEq("2"));
|
||||
ASSERT_THAT(variable->retrieve("d1"), StrEq("1"));
|
||||
ASSERT_THAT(variable->retrieve("i1"), StrEq("1"));
|
||||
ASSERT_THAT(variable->retrieve("l1"), StrEq("0"));
|
||||
ASSERT_THAT(variable->retrieve("l2"), StrEq("6"));
|
||||
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,N2')"), 1.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,\"N2'\")"), 0.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(bond,C1-N2)"), 1.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(bond,C2-N1)"), 0.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(bond,[C1][C1])"), 1.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(bond,[X1][Y1])"), 0.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(angle,C1-C2-N1)"), 0.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(angle,C1-N2-C1)"), 1.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(dihedral,C1-N2-C1-N2)"), 1.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(dihedral,N2-C1-C1-N2)"), 0.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(improper,C1-N2-C1-N2)"), 1.0);
|
||||
ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(improper,N2-C1-C1-N2)"), 0.0);
|
||||
|
||||
TEST_FAILURE(".*ERROR: Invalid bond type label H1 in label2type.. in variable.*",
|
||||
variable->compute_equal("label2type(bond,H1)"););
|
||||
TEST_FAILURE(".*ERROR: Invalid angle type label H1 in label2type.. in variable.*",
|
||||
variable->compute_equal("label2type(angle,H1)"););
|
||||
TEST_FAILURE(".*ERROR: Invalid dihedral type label H1 in label2type.. in variable.*",
|
||||
variable->compute_equal("label2type(dihedral,H1)"););
|
||||
TEST_FAILURE(".*ERROR: Invalid improper type label H1 in label2type.. in variable.*",
|
||||
variable->compute_equal("label2type(improper,H1)"););
|
||||
}
|
||||
|
||||
TEST_F(VariableTest, Format)
|
||||
|
||||
Reference in New Issue
Block a user