diff --git a/doc/src/group.rst b/doc/src/group.rst index fb1e0fb157..41510589a3 100644 --- a/doc/src/group.rst +++ b/doc/src/group.rst @@ -20,13 +20,13 @@ Syntax *empty* = no args *region* args = region-ID *type* or *id* or *molecule* - args = list of one or more atom types, atom IDs, or molecule IDs - any entry in list can be a sequence formatted as A:B or A:B:C where + args = list of one or more atom types (1-Ntypes or type label), atom IDs, or molecule IDs + any numeric entry in list can be a sequence formatted as A:B or A:B:C where A = starting index, B = ending index, C = increment between indices, 1 if not specified args = logical value logical = "<" or "<=" or ">" or ">=" or "==" or "!=" - value = an atom type or atom ID or molecule ID (depending on *style*\ ) + value = an atom type (1-Ntypes or type label) or atom ID or molecule ID (depending on *style*\ ) args = logical value1 value2 logical = "<>" value1,value2 = atom types or atom IDs or molecule IDs (depending on *style*\ ) @@ -52,6 +52,8 @@ Examples group edge region regstrip group water type 3 4 + group water type OW HT + group sub type != C H O N group sub id 10 25 50 group sub id 10 25 50 500:1000 group sub id 100:10000:10 @@ -119,7 +121,7 @@ three styles can use arguments specified in one of two formats. The first format is a list of values (types or IDs). For example, the second command in the examples above puts all atoms of type 3 or 4 into -the group named *water*\ . Each entry in the list can be a +the group named *water*\ . Each numeric entry in the list can be a colon-separated sequence ``A:B`` or ``A:B:C``, as in two of the examples above. A "sequence" generates a sequence of values (types or IDs), with an optional increment. The first example with ``500:1000`` has the @@ -135,7 +137,8 @@ except ``<>`` take a single argument. The third example above adds all atoms with IDs from 1 to 150 to the group named *sub*\ . The logical ``<>`` means "between" and takes 2 arguments. The fourth example above adds all atoms belonging to molecules with IDs from 50 to 250 (inclusive) to -the group named polyA. +the group named polyA. For the *type* style, type labels are converted into +numeric types before being evaluated. The *variable* style evaluates a variable to determine which atoms to add to the group. It must be an :doc:`atom-style variable ` diff --git a/src/group.cpp b/src/group.cpp index a586c33ed9..baf9f377ff 100644 --- a/src/group.cpp +++ b/src/group.cpp @@ -229,12 +229,16 @@ void Group::assign(int narg, char **arg) else error->all(FLERR,"Illegal group command"); tagint bound1,bound2; - bound1 = utils::tnumeric(FLERR,arg[3],false,lmp); + if (category == TYPE) + bound1 = (tagint) utils::expand_type_int(FLERR, arg[3], Atom::ATOM, lmp); + else bound1 = utils::tnumeric(FLERR, arg[3], false, lmp); bound2 = -1; if (condition == BETWEEN) { if (narg != 5) error->all(FLERR,"Illegal group command"); - bound2 = utils::tnumeric(FLERR,arg[4],false,lmp); + if (category == TYPE) + bound2 = (tagint) utils::expand_type_int(FLERR, arg[4], Atom::ATOM, lmp); + else bound2 = utils::tnumeric(FLERR, arg[4], false, lmp); } else if (narg != 4) error->all(FLERR,"Illegal group command"); int *attribute = nullptr; @@ -304,26 +308,34 @@ void Group::assign(int narg, char **arg) else if (category == MOLECULE) tattribute = atom->molecule; else if (category == ID) tattribute = atom->tag; + char *typestr = nullptr; tagint start,stop,delta; for (int iarg = 2; iarg < narg; iarg++) { delta = 1; - try { - ValueTokenizer values(arg[iarg],":"); - start = values.next_tagint(); - if (utils::strmatch(arg[iarg],"^-?\\d+$")) { - stop = start; - } else if (utils::strmatch(arg[iarg],"^-?\\d+:-?\\d+$")) { - stop = values.next_tagint(); - } else if (utils::strmatch(arg[iarg],"^-?\\d+:-?\\d+:\\d+$")) { - stop = values.next_tagint(); - delta = values.next_tagint(); - } else throw TokenizerException("Syntax error",""); - } catch (TokenizerException &e) { - error->all(FLERR,"Incorrect range string '{}': {}",arg[iarg],e.what()); + if (category == TYPE) { + delete[] typestr; + typestr = utils::expand_type(FLERR, arg[iarg], Atom::ATOM, lmp); + if (typestr) stop = start = utils::tnumeric(FLERR, typestr, false, lmp); + } + if (typestr == nullptr) { + try { + ValueTokenizer values(arg[iarg],":"); + start = values.next_tagint(); + if (utils::strmatch(arg[iarg],"^-?\\d+$")) { + stop = start; + } else if (utils::strmatch(arg[iarg],"^-?\\d+:-?\\d+$")) { + stop = values.next_tagint(); + } else if (utils::strmatch(arg[iarg],"^-?\\d+:-?\\d+:\\d+$")) { + stop = values.next_tagint(); + delta = values.next_tagint(); + } else throw TokenizerException("Syntax error",""); + } catch (TokenizerException &e) { + error->all(FLERR,"Incorrect range string '{}': {}",arg[iarg],e.what()); + } + if (delta < 1) + error->all(FLERR,"Illegal range increment value"); } - if (delta < 1) - error->all(FLERR,"Illegal range increment value"); // add to group if attribute matches value or sequence @@ -337,6 +349,8 @@ void Group::assign(int narg, char **arg) (tattribute[i]-start) % delta == 0) mask[i] |= bit; } } + + delete[] typestr; } // style = variable