From fa1584cc1717a0d22c52ac98b19c90db88bc064e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 3 Sep 2022 12:38:07 -0400 Subject: [PATCH] add "labelmap clear" command, update docs --- doc/src/labelmap.rst | 13 ++++++++----- src/label_map.cpp | 26 +++++++++++++++++++------- src/label_map.h | 2 +- unittest/commands/test_labelmap.cpp | 18 ++++++++++++++---- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/doc/src/labelmap.rst b/doc/src/labelmap.rst index 2ff53b276b..abd65ba7db 100644 --- a/doc/src/labelmap.rst +++ b/doc/src/labelmap.rst @@ -8,11 +8,10 @@ Syntax .. 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* -* one or more numeric-type/type-label pairs may be specified -* zero or more keyword/arg pairs may be appended +* *option* = *atom* or *bond* or *angle* or *dihedral* or *improper* or *clear* +* except for the *clear* option, one or more numeric-type/type-label pairs may be appended Examples """""""" @@ -22,6 +21,7 @@ Examples labelmap atom 3 carbon labelmap bond 1 carbonyl 2 nitrile labelmap atom $(label(carbon)) C # change type label from 'carbon' to 'C' + labelmap clear 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 contain standard characters such as square brackets "[" and "]", dash "-", 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 (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 type-kind). +The *clear* option resets the labelmap and thus discards all previous +settings. + ---------- Restrictions diff --git a/src/label_map.cpp b/src/label_map.cpp index b489b793d2..72c20e56ac 100644 --- a/src/label_map.cpp +++ b/src/label_map.cpp @@ -33,7 +33,7 @@ LabelMap::LabelMap(LAMMPS *_lmp, int _natomtypes, int _nbondtypes, int _nanglety { lmap2lmap.atom = lmap2lmap.bond = lmap2lmap.angle = lmap2lmap.dihedral = lmap2lmap.improper = 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); delete[] lmap2lmap.atom; lmap2lmap.atom = new int[natomtypes]; for (auto &i : typelabel) i.clear(); memset(lmap2lmap.atom, 0, natomtypes * sizeof(int)); + btypelabel_map.clear(); btypelabel.resize(nbondtypes); delete[] lmap2lmap.bond; for (auto &i : btypelabel) i.clear(); lmap2lmap.bond = new int[nbondtypes]; memset(lmap2lmap.bond, 0, nbondtypes * sizeof(int)); + atypelabel_map.clear(); atypelabel.resize(nangletypes); delete[] lmap2lmap.angle; for (auto &i : atypelabel) i.clear(); lmap2lmap.angle = new int[nangletypes]; memset(lmap2lmap.angle, 0, nangletypes * sizeof(int)); + dtypelabel_map.clear(); dtypelabel.resize(ndihedraltypes); delete[] lmap2lmap.dihedral; for (auto &i : dtypelabel) i.clear(); lmap2lmap.dihedral = new int[ndihedraltypes]; memset(lmap2lmap.dihedral, 0, ndihedraltypes * sizeof(int)); + itypelabel_map.clear(); itypelabel.resize(nimpropertypes); delete[] lmap2lmap.improper; for (auto &i : itypelabel) i.clear(); 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) { - if (narg < 3 || narg % 2 == 0) + if ((narg < 1) || ((narg > 2) && ((narg % 2) == 0))) error->all(FLERR, "Incorrect number of arguments for labelmap command"); int ntypes; @@ -117,11 +122,17 @@ void LabelMap::modify_lmap(int narg, char **arg) ntypes = nimpropertypes; labels = &itypelabel; 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 - error->all(FLERR, "Unknown labelmap type {}", tlabel); + error->all(FLERR, "Unknown labelmap keyword {}", tlabel); int iarg = 1; + if (narg == 1) utils::missing_cmd_args(FLERR, "labelmap " + tlabel, error); 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); int itype = utils::inumeric(FLERR, arg[iarg++], false, lmp); if ((itype < 1) || (itype > ntypes)) @@ -130,7 +141,8 @@ void LabelMap::modify_lmap(int narg, char **arg) if (isdigit(slabel[0])) error->all(FLERR, "Label {} for {} type {} must not start with a number", slabel, tlabel, 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, (*labels_map)[slabel]); std::string &str = (*labels)[itype - 1]; diff --git a/src/label_map.h b/src/label_map.h index c56629cf2e..7bf5ab57d6 100644 --- a/src/label_map.h +++ b/src/label_map.h @@ -61,7 +61,7 @@ class LabelMap : protected Pointers { Lmap2Lmap lmap2lmap; - void allocate_type_labels(); + void reset_type_labels(); int find_or_create(const std::string &, std::vector &, std::unordered_map &); // look up type or create new type int search(const std::string &, diff --git a/unittest/commands/test_labelmap.cpp b/unittest/commands/test_labelmap.cpp index b4a3856883..f2d682f776 100644 --- a/unittest/commands/test_labelmap.cpp +++ b/unittest/commands/test_labelmap.cpp @@ -105,13 +105,13 @@ TEST_F(SetTest, NoBoxAtoms) ASSERT_FALSE(atom->lmap->is_complete(Atom::ATOM)); 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(); ASSERT_TRUE(atom->lmap->is_complete(Atom::ATOM)); ASSERT_EQ(atom->lmap->find("C1", Atom::ATOM), 1); ASSERT_EQ(atom->lmap->find("N2", Atom::ATOM), 2); - ASSERT_EQ(atom->lmap->find("O1", Atom::ATOM), 3); - ASSERT_EQ(atom->lmap->find("H1", Atom::ATOM), 4); + ASSERT_EQ(atom->lmap->find("O#", Atom::ATOM), 3); + ASSERT_EQ(atom->lmap->find("H", Atom::ATOM), 4); TEST_FAILURE(".*ERROR: Labelmap atom type 0 must be within 1-4.*", command("labelmap atom 0 C1");); @@ -136,9 +136,19 @@ TEST_F(SetTest, NoBoxAtoms) TEST_FAILURE(".*ERROR: Incorrect number of arguments for labelmap command.*", command("labelmap atom 1 C1 atom 2 C2");); 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");); - TEST_FAILURE(".*ERROR: Incorrect number of arguments for labelmap command.*", + TEST_FAILURE(".*ERROR: Illegal labelmap atom command: missing argument.*", 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