new utility function "utils::expand_type" to convert type labels to numeric strings
This commit is contained in:
@ -211,6 +211,9 @@ Argument processing
|
|||||||
.. doxygenfunction:: expand_args
|
.. doxygenfunction:: expand_args
|
||||||
:project: progguide
|
:project: progguide
|
||||||
|
|
||||||
|
.. doxygenfunction:: expand_type
|
||||||
|
:project: progguide
|
||||||
|
|
||||||
Convenience functions
|
Convenience functions
|
||||||
^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
#include "fix.h"
|
#include "fix.h"
|
||||||
#include "fmt/chrono.h"
|
#include "fmt/chrono.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
#include "label_map.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "modify.h"
|
#include "modify.h"
|
||||||
#include "text_file_reader.h"
|
#include "text_file_reader.h"
|
||||||
@ -766,6 +767,26 @@ int utils::expand_args(const char *file, int line, int narg, char **arg, int mod
|
|||||||
return newarg;
|
return newarg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------
|
||||||
|
Expand type string to numeric string from labelmap.
|
||||||
|
Return copy of expanded type or null pointer.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
char *utils::expand_type(const char *file, int line, const std::string &str, int mode, LAMMPS *lmp)
|
||||||
|
{
|
||||||
|
if (!lmp) return nullptr;
|
||||||
|
if (is_type(str) == 1) {
|
||||||
|
if (!lmp->atom->labelmapflag)
|
||||||
|
lmp->error->all(file, line, "Type string {} cannot be used without a labelmap", str);
|
||||||
|
|
||||||
|
int type = lmp->atom->lmap->find(str, mode);
|
||||||
|
if (type == -1) lmp->error->all(file, line, "Type string {} not found in labelmap", str);
|
||||||
|
|
||||||
|
return utils::strdup(std::to_string(type));
|
||||||
|
} else
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
Make copy of string in new storage. Works like the (non-portable)
|
Make copy of string in new storage. Works like the (non-portable)
|
||||||
C-style strdup() but also accepts a C++ string as argument.
|
C-style strdup() but also accepts a C++ string as argument.
|
||||||
|
|||||||
18
src/utils.h
18
src/utils.h
@ -359,6 +359,24 @@ namespace utils {
|
|||||||
int expand_args(const char *file, int line, int narg, char **arg, int mode, char **&earg,
|
int expand_args(const char *file, int line, int narg, char **arg, int mode, char **&earg,
|
||||||
LAMMPS *lmp);
|
LAMMPS *lmp);
|
||||||
|
|
||||||
|
/*! Expand type label string into its equivalent numeric type
|
||||||
|
*
|
||||||
|
* This function checks if a given string may be a type label and
|
||||||
|
* then searches the labelmap type indicated by the *mode* argument
|
||||||
|
* for the corresponding numeric type. If this is found a copy of
|
||||||
|
* the numeric type string is made and returned. Otherwise a null
|
||||||
|
* pointer is returned.
|
||||||
|
* If a string is returned, the calling code must free it with delete[].
|
||||||
|
*
|
||||||
|
* \param file name of source file for error message
|
||||||
|
* \param line line number in source file for error message
|
||||||
|
* \param str type string to be expanded
|
||||||
|
* \param mode select labelmap using constants from Atom class
|
||||||
|
* \param lmp pointer to top-level LAMMPS class instance
|
||||||
|
* \return pointer to expanded string or null pointer */
|
||||||
|
|
||||||
|
char *expand_type(const char *file, int line, const std::string &str, int mode, LAMMPS *lmp);
|
||||||
|
|
||||||
/*! Make C-style copy of string in new storage
|
/*! Make C-style copy of string in new storage
|
||||||
*
|
*
|
||||||
* This allocates a storage buffer and copies the C-style or
|
* This allocates a storage buffer and copies the C-style or
|
||||||
|
|||||||
@ -63,6 +63,13 @@ TEST_F(LabelMapTest, Atoms)
|
|||||||
BEGIN_HIDE_OUTPUT();
|
BEGIN_HIDE_OUTPUT();
|
||||||
command("region box block 0 2 0 2 0 2");
|
command("region box block 0 2 0 2 0 2");
|
||||||
command("create_box 4 box");
|
command("create_box 4 box");
|
||||||
|
END_HIDE_OUTPUT();
|
||||||
|
EXPECT_EQ(domain->box_exist, 1);
|
||||||
|
EXPECT_EQ(atom->lmap, nullptr);
|
||||||
|
TEST_FAILURE(".*ERROR: Type string C1 cannot be used without a labelmap.*",
|
||||||
|
utils::expand_type(FLERR, "C1", Atom::ATOM, lmp););
|
||||||
|
|
||||||
|
BEGIN_HIDE_OUTPUT();
|
||||||
command("labelmap atom 2 N1");
|
command("labelmap atom 2 N1");
|
||||||
command("labelmap atom 3 O1 4 H1");
|
command("labelmap atom 3 O1 4 H1");
|
||||||
command("mass * 1.0");
|
command("mass * 1.0");
|
||||||
@ -89,6 +96,22 @@ TEST_F(LabelMapTest, Atoms)
|
|||||||
EXPECT_EQ(atom->lmap->find("X", Atom::ATOM), -1);
|
EXPECT_EQ(atom->lmap->find("X", Atom::ATOM), -1);
|
||||||
EXPECT_DOUBLE_EQ(atom->mass[3], 10.0);
|
EXPECT_DOUBLE_EQ(atom->mass[3], 10.0);
|
||||||
|
|
||||||
|
EXPECT_EQ(utils::expand_type(FLERR, "1", Atom::ATOM, lmp), nullptr);
|
||||||
|
EXPECT_EQ(utils::expand_type(FLERR, "*3", Atom::ATOM, lmp), nullptr);
|
||||||
|
EXPECT_EQ(utils::expand_type(FLERR, "1*2", Atom::ATOM, lmp), nullptr);
|
||||||
|
EXPECT_EQ(utils::expand_type(FLERR, "*", Atom::ATOM, lmp), nullptr);
|
||||||
|
EXPECT_EQ(utils::expand_type(FLERR, "**", Atom::ATOM, lmp), nullptr);
|
||||||
|
EXPECT_EQ(utils::expand_type(FLERR, "1*2*", Atom::ATOM, lmp), nullptr);
|
||||||
|
|
||||||
|
auto expanded = utils::expand_type(FLERR, "C1", Atom::ATOM, lmp);
|
||||||
|
EXPECT_THAT(expanded, StrEq("1"));
|
||||||
|
delete[] expanded;
|
||||||
|
expanded = utils::expand_type(FLERR, "O#", Atom::ATOM, lmp);
|
||||||
|
EXPECT_THAT(expanded, StrEq("3"));
|
||||||
|
delete[] expanded;
|
||||||
|
TEST_FAILURE(".*ERROR: Type string XX not found in labelmap.*",
|
||||||
|
utils::expand_type(FLERR, "XX", Atom::ATOM, lmp););
|
||||||
|
|
||||||
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"););
|
||||||
TEST_FAILURE(".*ERROR: Labelmap atom type 5 must be within 1-4.*",
|
TEST_FAILURE(".*ERROR: Labelmap atom type 5 must be within 1-4.*",
|
||||||
@ -238,6 +261,24 @@ TEST_F(LabelMapTest, Topology)
|
|||||||
EXPECT_EQ(atom->lmap->find("X", Atom::ATOM), -1);
|
EXPECT_EQ(atom->lmap->find("X", Atom::ATOM), -1);
|
||||||
EXPECT_EQ(atom->lmap->find("N2'-C1\"-N2'", Atom::BOND), -1);
|
EXPECT_EQ(atom->lmap->find("N2'-C1\"-N2'", Atom::BOND), -1);
|
||||||
platform::unlink("labelmap_topology.inc");
|
platform::unlink("labelmap_topology.inc");
|
||||||
|
|
||||||
|
auto expanded = utils::expand_type(FLERR, "N2'", Atom::ATOM, lmp);
|
||||||
|
EXPECT_THAT(expanded, StrEq("2"));
|
||||||
|
delete[] expanded;
|
||||||
|
expanded = utils::expand_type(FLERR, "[C1][C1]", Atom::BOND, lmp);
|
||||||
|
EXPECT_THAT(expanded, StrEq("2"));
|
||||||
|
delete[] expanded;
|
||||||
|
expanded = utils::expand_type(FLERR, "C1-N2-C1", Atom::ANGLE, lmp);
|
||||||
|
EXPECT_THAT(expanded, StrEq("1"));
|
||||||
|
delete[] expanded;
|
||||||
|
expanded = utils::expand_type(FLERR, "C1-N2-C1-N2", Atom::DIHEDRAL, lmp);
|
||||||
|
EXPECT_THAT(expanded, StrEq("1"));
|
||||||
|
delete[] expanded;
|
||||||
|
expanded = utils::expand_type(FLERR, "C1-N2-C1-N2", Atom::IMPROPER, lmp);
|
||||||
|
EXPECT_THAT(expanded, StrEq("1"));
|
||||||
|
delete[] expanded;
|
||||||
|
TEST_FAILURE(".*ERROR: Type string XX not found in labelmap.*",
|
||||||
|
utils::expand_type(FLERR, "XX", Atom::BOND, lmp););
|
||||||
}
|
}
|
||||||
} // namespace LAMMPS_NS
|
} // namespace LAMMPS_NS
|
||||||
|
|
||||||
|
|||||||
@ -33,10 +33,10 @@
|
|||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
|
|
||||||
namespace LAMMPS_NS {
|
namespace LAMMPS_NS {
|
||||||
|
using MathConst::MY_PI;
|
||||||
using ::testing::ContainsRegex;
|
using ::testing::ContainsRegex;
|
||||||
using ::testing::ExitedWithCode;
|
using ::testing::ExitedWithCode;
|
||||||
using ::testing::StrEq;
|
using ::testing::StrEq;
|
||||||
using MathConst::MY_PI;
|
|
||||||
|
|
||||||
class VariableTest : public LAMMPSTest {
|
class VariableTest : public LAMMPSTest {
|
||||||
protected:
|
protected:
|
||||||
@ -196,8 +196,10 @@ TEST_F(VariableTest, CreateDelete)
|
|||||||
|
|
||||||
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable"););
|
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable"););
|
||||||
TEST_FAILURE(".*ERROR: Illegal variable index command.*", command("variable dummy index"););
|
TEST_FAILURE(".*ERROR: Illegal variable index command.*", command("variable dummy index"););
|
||||||
TEST_FAILURE(".*ERROR: Illegal variable delete command: expected 2 arguments but found 3.*", command("variable dummy delete xxx"););
|
TEST_FAILURE(".*ERROR: Illegal variable delete command: expected 2 arguments but found 3.*",
|
||||||
TEST_FAILURE(".*ERROR: Invalid variable loop argument: -1.*", command("variable dummy loop -1"););
|
command("variable dummy delete xxx"););
|
||||||
|
TEST_FAILURE(".*ERROR: Invalid variable loop argument: -1.*",
|
||||||
|
command("variable dummy loop -1"););
|
||||||
TEST_FAILURE(".*ERROR: Illegal variable loop command.*", command("variable dummy loop 10 1"););
|
TEST_FAILURE(".*ERROR: Illegal variable loop command.*", command("variable dummy loop 10 1"););
|
||||||
TEST_FAILURE(".*ERROR: Unknown variable keyword: xxx.*", command("variable dummy xxxx"););
|
TEST_FAILURE(".*ERROR: Unknown variable keyword: xxx.*", command("variable dummy xxxx"););
|
||||||
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
|
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
|
||||||
@ -402,8 +404,9 @@ TEST_F(VariableTest, Functions)
|
|||||||
command("print \"$(extract_setting()\""););
|
command("print \"$(extract_setting()\""););
|
||||||
TEST_FAILURE(".*ERROR: Invalid extract_setting.. function syntax in variable formula.*",
|
TEST_FAILURE(".*ERROR: Invalid extract_setting.. function syntax in variable formula.*",
|
||||||
command("print \"$(extract_setting(one,two))\""););
|
command("print \"$(extract_setting(one,two))\""););
|
||||||
TEST_FAILURE(".*ERROR: Unknown setting nprocs for extract_setting.. function in variable formula.*",
|
TEST_FAILURE(
|
||||||
command("print \"$(extract_setting(nprocs))\""););
|
".*ERROR: Unknown setting nprocs for extract_setting.. function in variable formula.*",
|
||||||
|
command("print \"$(extract_setting(nprocs))\""););
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VariableTest, IfCommand)
|
TEST_F(VariableTest, IfCommand)
|
||||||
|
|||||||
Reference in New Issue
Block a user