add "labelmap clear" command, update docs

This commit is contained in:
Axel Kohlmeyer
2022-09-03 12:38:07 -04:00
parent 849b41f67a
commit fa1584cc17
4 changed files with 42 additions and 17 deletions

View File

@ -8,11 +8,10 @@ Syntax
.. code-block:: LAMMPS .. code-block:: LAMMPS
labelmap type-kind numeric-type type-label ... keyword arg labelmap option args
* type-kind = *atom* or *bond* or *angle* or *dihedral* or *improper* * *option* = *atom* or *bond* or *angle* or *dihedral* or *improper* or *clear*
* one or more numeric-type/type-label pairs may be specified * except for the *clear* option, one or more numeric-type/type-label pairs may be appended
* zero or more keyword/arg pairs may be appended
Examples Examples
"""""""" """"""""
@ -22,6 +21,7 @@ Examples
labelmap atom 3 carbon labelmap atom 3 carbon
labelmap bond 1 carbonyl 2 nitrile labelmap bond 1 carbonyl 2 nitrile
labelmap atom $(label(carbon)) C # change type label from 'carbon' to 'C' labelmap atom $(label(carbon)) C # change type label from 'carbon' to 'C'
labelmap clear
Description Description
""""""""""" """""""""""
@ -40,7 +40,7 @@ As explained on the Howto page, valid type labels can contain any
alphanumeric character, but cannot start with a number. They can also alphanumeric character, but cannot start with a number. They can also
contain standard characters such as square brackets "[" and "]", dash contain standard characters such as square brackets "[" and "]", dash
"-", underscore "_", plus "+" and equals "=" signs. Note that type "-", underscore "_", plus "+" and equals "=" signs. Note that type
labels cannot contain the comment symbol '#'. labels must be put in quotation marks if they contain the comment symbol '#'.
A *labelmap* command can only modify the label map for one type-kind A *labelmap* command can only modify the label map for one type-kind
(atom types, bond types, etc). Any number of numeric-type/type-label (atom types, bond types, etc). Any number of numeric-type/type-label
@ -51,6 +51,9 @@ cases, such as when reading and writing data files, it is required
that a type label be defined for every numeric type (within a given that a type label be defined for every numeric type (within a given
type-kind). type-kind).
The *clear* option resets the labelmap and thus discards all previous
settings.
---------- ----------
Restrictions Restrictions

View File

@ -33,7 +33,7 @@ LabelMap::LabelMap(LAMMPS *_lmp, int _natomtypes, int _nbondtypes, int _nanglety
{ {
lmap2lmap.atom = lmap2lmap.bond = lmap2lmap.angle = lmap2lmap.dihedral = lmap2lmap.improper = lmap2lmap.atom = lmap2lmap.bond = lmap2lmap.angle = lmap2lmap.dihedral = lmap2lmap.improper =
nullptr; nullptr;
allocate_type_labels(); reset_type_labels();
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
@ -48,40 +48,45 @@ LabelMap::~LabelMap()
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
allocate character-based type arrays (labels) of length ntypes reset/allocate character-based type arrays (labels) of length ntypes
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void LabelMap::allocate_type_labels() void LabelMap::reset_type_labels()
{ {
typelabel_map.clear();
typelabel.resize(natomtypes); typelabel.resize(natomtypes);
delete[] lmap2lmap.atom; delete[] lmap2lmap.atom;
lmap2lmap.atom = new int[natomtypes]; lmap2lmap.atom = new int[natomtypes];
for (auto &i : typelabel) i.clear(); for (auto &i : typelabel) i.clear();
memset(lmap2lmap.atom, 0, natomtypes * sizeof(int)); memset(lmap2lmap.atom, 0, natomtypes * sizeof(int));
btypelabel_map.clear();
btypelabel.resize(nbondtypes); btypelabel.resize(nbondtypes);
delete[] lmap2lmap.bond; delete[] lmap2lmap.bond;
for (auto &i : btypelabel) i.clear(); for (auto &i : btypelabel) i.clear();
lmap2lmap.bond = new int[nbondtypes]; lmap2lmap.bond = new int[nbondtypes];
memset(lmap2lmap.bond, 0, nbondtypes * sizeof(int)); memset(lmap2lmap.bond, 0, nbondtypes * sizeof(int));
atypelabel_map.clear();
atypelabel.resize(nangletypes); atypelabel.resize(nangletypes);
delete[] lmap2lmap.angle; delete[] lmap2lmap.angle;
for (auto &i : atypelabel) i.clear(); for (auto &i : atypelabel) i.clear();
lmap2lmap.angle = new int[nangletypes]; lmap2lmap.angle = new int[nangletypes];
memset(lmap2lmap.angle, 0, nangletypes * sizeof(int)); memset(lmap2lmap.angle, 0, nangletypes * sizeof(int));
dtypelabel_map.clear();
dtypelabel.resize(ndihedraltypes); dtypelabel.resize(ndihedraltypes);
delete[] lmap2lmap.dihedral; delete[] lmap2lmap.dihedral;
for (auto &i : dtypelabel) i.clear(); for (auto &i : dtypelabel) i.clear();
lmap2lmap.dihedral = new int[ndihedraltypes]; lmap2lmap.dihedral = new int[ndihedraltypes];
memset(lmap2lmap.dihedral, 0, ndihedraltypes * sizeof(int)); memset(lmap2lmap.dihedral, 0, ndihedraltypes * sizeof(int));
itypelabel_map.clear();
itypelabel.resize(nimpropertypes); itypelabel.resize(nimpropertypes);
delete[] lmap2lmap.improper; delete[] lmap2lmap.improper;
for (auto &i : itypelabel) i.clear(); for (auto &i : itypelabel) i.clear();
lmap2lmap.improper = new int[nimpropertypes]; lmap2lmap.improper = new int[nimpropertypes];
memset(lmap2lmap.dihedral, 0, nimpropertypes * sizeof(int)); memset(lmap2lmap.improper, 0, nimpropertypes * sizeof(int));
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -90,7 +95,7 @@ void LabelMap::allocate_type_labels()
void LabelMap::modify_lmap(int narg, char **arg) void LabelMap::modify_lmap(int narg, char **arg)
{ {
if (narg < 3 || narg % 2 == 0) if ((narg < 1) || ((narg > 2) && ((narg % 2) == 0)))
error->all(FLERR, "Incorrect number of arguments for labelmap command"); error->all(FLERR, "Incorrect number of arguments for labelmap command");
int ntypes; int ntypes;
@ -117,11 +122,17 @@ void LabelMap::modify_lmap(int narg, char **arg)
ntypes = nimpropertypes; ntypes = nimpropertypes;
labels = &itypelabel; labels = &itypelabel;
labels_map = &itypelabel_map; labels_map = &itypelabel_map;
} else if (tlabel == "clear") {
if (narg != 1) error->all(FLERR, "Incorrect number of arguments for labelmap command");
reset_type_labels();
return;
} else } else
error->all(FLERR, "Unknown labelmap type {}", tlabel); error->all(FLERR, "Unknown labelmap keyword {}", tlabel);
int iarg = 1; int iarg = 1;
if (narg == 1) utils::missing_cmd_args(FLERR, "labelmap " + tlabel, error);
while (iarg < narg) { while (iarg < narg) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "labelmap " + tlabel, error);
if (ntypes < 1) error->all(FLERR, "No {} types allowed with current box settings", tlabel); if (ntypes < 1) error->all(FLERR, "No {} types allowed with current box settings", tlabel);
int itype = utils::inumeric(FLERR, arg[iarg++], false, lmp); int itype = utils::inumeric(FLERR, arg[iarg++], false, lmp);
if ((itype < 1) || (itype > ntypes)) if ((itype < 1) || (itype > ntypes))
@ -130,7 +141,8 @@ void LabelMap::modify_lmap(int narg, char **arg)
if (isdigit(slabel[0])) if (isdigit(slabel[0]))
error->all(FLERR, "Label {} for {} type {} must not start with a number", slabel, tlabel, error->all(FLERR, "Label {} for {} type {} must not start with a number", slabel, tlabel,
itype); itype);
if (search(slabel, (*labels_map)) != -1) int found = search(slabel, (*labels_map));
if ((found != -1) && (found != itype))
error->all(FLERR, "The {} type label {} is already in use for type {}", tlabel, slabel, error->all(FLERR, "The {} type label {} is already in use for type {}", tlabel, slabel,
(*labels_map)[slabel]); (*labels_map)[slabel]);
std::string &str = (*labels)[itype - 1]; std::string &str = (*labels)[itype - 1];

View File

@ -61,7 +61,7 @@ class LabelMap : protected Pointers {
Lmap2Lmap lmap2lmap; Lmap2Lmap lmap2lmap;
void allocate_type_labels(); void reset_type_labels();
int find_or_create(const std::string &, std::vector<std::string> &, int find_or_create(const std::string &, std::vector<std::string> &,
std::unordered_map<std::string, int> &); // look up type or create new type std::unordered_map<std::string, int> &); // look up type or create new type
int search(const std::string &, int search(const std::string &,

View File

@ -105,13 +105,13 @@ TEST_F(SetTest, NoBoxAtoms)
ASSERT_FALSE(atom->lmap->is_complete(Atom::ATOM)); ASSERT_FALSE(atom->lmap->is_complete(Atom::ATOM));
BEGIN_HIDE_OUTPUT(); BEGIN_HIDE_OUTPUT();
command("labelmap atom 1 C1 2 N2"); command("labelmap atom 1 C1 2 N2 3 'O#' 1 C1 4 H#");
END_HIDE_OUTPUT(); END_HIDE_OUTPUT();
ASSERT_TRUE(atom->lmap->is_complete(Atom::ATOM)); ASSERT_TRUE(atom->lmap->is_complete(Atom::ATOM));
ASSERT_EQ(atom->lmap->find("C1", Atom::ATOM), 1); ASSERT_EQ(atom->lmap->find("C1", Atom::ATOM), 1);
ASSERT_EQ(atom->lmap->find("N2", Atom::ATOM), 2); ASSERT_EQ(atom->lmap->find("N2", Atom::ATOM), 2);
ASSERT_EQ(atom->lmap->find("O1", Atom::ATOM), 3); ASSERT_EQ(atom->lmap->find("O#", Atom::ATOM), 3);
ASSERT_EQ(atom->lmap->find("H1", Atom::ATOM), 4); ASSERT_EQ(atom->lmap->find("H", Atom::ATOM), 4);
TEST_FAILURE(".*ERROR: Labelmap atom type 0 must be within 1-4.*", TEST_FAILURE(".*ERROR: Labelmap atom type 0 must be within 1-4.*",
command("labelmap atom 0 C1");); command("labelmap atom 0 C1"););
@ -136,9 +136,19 @@ TEST_F(SetTest, NoBoxAtoms)
TEST_FAILURE(".*ERROR: Incorrect number of arguments for labelmap command.*", TEST_FAILURE(".*ERROR: Incorrect number of arguments for labelmap command.*",
command("labelmap atom 1 C1 atom 2 C2");); command("labelmap atom 1 C1 atom 2 C2"););
TEST_FAILURE(".*ERROR: Incorrect number of arguments for labelmap command.*", TEST_FAILURE(".*ERROR: Incorrect number of arguments for labelmap command.*",
command("labelmap clear atom"););
TEST_FAILURE(".*ERROR: Illegal labelmap atom command: missing argument.*",
command("labelmap atom 1");); command("labelmap atom 1"););
TEST_FAILURE(".*ERROR: Incorrect number of arguments for labelmap command.*", TEST_FAILURE(".*ERROR: Illegal labelmap atom command: missing argument.*",
command("labelmap atom");); command("labelmap atom"););
BEGIN_HIDE_OUTPUT();
command("labelmap clear");
command("labelmap atom 3 C1 2 N2");
END_HIDE_OUTPUT();
ASSERT_FALSE(atom->lmap->is_complete(Atom::ATOM));
ASSERT_EQ(atom->lmap->find("C1", Atom::ATOM), 3);
ASSERT_EQ(atom->lmap->find("N2", Atom::ATOM), 2);
} }
} // namespace LAMMPS_NS } // namespace LAMMPS_NS